我一直在研究蛮力算法,以生成给定集合的所有排列。最终,我想将这些排列的每一个馈入一个nxn矩阵中,以测试它是否是有效的幻方。
-我知道有一种简便的方法可以产生魔方-
不过,那不是我想要的。我专注于它的暴力方面。

对于一组3个元素,它效果很好。但是,一旦使用4个或更多元素,我就会失去一些排列。仅从4的输出来看,我缺少7个排列。

#include <stdio.h>
#include <iostream>

using namespace std;


//ms = magic square
//n = size
void perm(int ms[], int n) {
    int pivot = 0;
    int index = 0;
    int pivBit = 1;
    int fin = 0;
    int hold = 0;

    //While we are not finished
    while (fin == 0)  {
        //Incriment the index
        ++index;
        if (index >= n) {
            index = 0;
        }
        //if index is equal to the pivot
        if (index == pivot) {
            //Is this the first time visiting the pivot?
            if (pivBit == 0) {
                //Are we at the beginning again?
                if (index == 0 && pivot == 0)
                {
                    fin = 1;
                }
                pivBit = 1;
                ++index;
            }
            //Second time visiting?
            else {
                pivBit = 0;
                ++pivot;
                if (pivot >= n) {
                    pivot = 0;
                }
            }
        }

        //If we are out of bounds
        if (index >= n) {
            index = 0;
        }

        //swap
        hold = ms[index];
        ms[index] = ms[pivot];
        ms[pivot] = hold;

        for (int i = 0; i < n; ++i) {
            cout << ms[i];
            if (i < n - 1) {
                cout << ", ";
            }
            else {
                cout << endl;
            }


        }

    }

}



int main() {

    cout << "Are you ready to brute force, my brother?" << endl;

    //Set
    int magicsquare[] = { 1, 2, 3, 4};
    int size = 4;

    perm(magicsquare, size);

    getchar();
    return 0;
}

我的输出是:
2 1 3 4
3 1 2 4
4 1 2 3
1 4 2 3
1 2 4 3
1 3 4 2
3 1 4 2
3 4 1 2
3 4 2 1
2 4 3 1
2 3 4 1
2 3 1 4
4 3 1 2
4 2 1 3
4 2 3 1
1 2 3 4
2 1 3 4

查看它,我已经可以看到我同时缺少1 4 3 2和1 3 2 4。
我的算法哪里出错了?

最佳答案

Wiki上有关置换的文章包括用于按字典顺序生成所有置换的通用算法,该算法以顺序递增的整数数组开始,以该数组反转为结尾。 wiki next permutation

如果处理对象数组,则可以生成索引0到n-1的数组,并在索引上使用下一个置换来生成对象数组的所有置换。

您也可以在网络上搜索下一个排列以查找类似的算法。递归的产生所有排列,但不按字典顺序排列。

关于c++ - 蛮力置换交换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26394242/

10-11 00:53