n-queens在同一条线上没有3个皇后

时间:2016-10-12 10:53:50

标签: algorithm optimization constraint-programming n-queens

我正在尝试生成具有更强条件的n-queen实例,以便没有3个皇后在同一行

这是,如果(r0, c0), (r1, c1), (r2, c2)是皇后的三个独特位置,

然后(c0 - c1) * (r0 - r2) != (c0 - c2) * (r0 - r1)

现在,我正在尝试使用简单的随机爬山在每次迭代中交换两行,以便减少冲突的数量。使用这个,我能够解决到n~200。

#include <cstdio>
#include <cstdlib>
#include <ctime>

class Board{
public:
    int size;
    int * ar;
    Board(int size): size(size){
        ar = new int[size];
        for(int i=0;i<size;i++){
            ar[i] = i+1;
        }
        for(int i=0;i<size*50;i++){
            cell_swap(rand() % size, i % size);
        }
    }

    void cell_swap(int a, int b){
        if(a == b) return;
        ar[a] ^= ar[b];
        ar[b] ^= ar[a];
        ar[a] ^= ar[b];
    }

    int clash_count(int i){
        int count = 0;
        for(int j=0;j<size;j++){
            if(i==j) continue;
            for(int k=j+1;k<size;k++){
                if(i==k) continue;
                if((i-k)*(ar[i]-ar[j]) == (i-j)*(ar[i]-ar[k])){
                    count++;
                }
            }
        }
        return count;
    }

    void print(){
        for(int i=0;i<size;i++){
            printf("%4d", ar[i]);
        }
        printf("\n");
    }

    ~Board(){
        delete[] ar;
    }
};

int main(int argc, char *argv[]){
    srand(time(NULL));
    int size = argc > 1 ? atoi(argv[1]) : 10;
    Board * b = new Board(size);
    bool flag = 0;
    while(1){
        // b->print();
        int clashes[size];
        int total_clash = 0;
        for(int i=0;i<size;i++){
            clashes[i] = b->clash_count(i);
            total_clash += clashes[i];
        }
        total_clash /= 3;
        printf("clash: %d\n", total_clash);
        if(total_clash == 0) break;
        int moves[(size*(size-1))<<1][3];
        int ix = 0;
        int s = 0;
        for(int i=0;i<size;i++){
            for(int j=0;j<size;j++){
                b->cell_swap(i, j);
                moves[ix][0] = clashes[i] + clashes[j];
                moves[ix][0] -= b->clash_count(i);
                moves[ix][0] -= b->clash_count(j);
                if(moves[ix][0] > 0){
                    s += moves[ix][0];
                    moves[ix][1] = i;
                    moves[ix][2] = j;
                    ix++;
                }
                b->cell_swap(i, j);
            }
        }
        if(s == 0) continue;
        int rand_ = rand() % s;
        int s_ = 0;

        for(int i=0;i<ix;i++){
            if(moves[i][0] < 0) continue;
            s_ += moves[i][0];
            if(s_ > rand_){
                b->cell_swap(moves[i][1], moves[i][2]);
                break;
            }
        }
    }
    b->print();
    return 0;
}

我想扩展我的算法。我想减少发现冲突的运行时间。无论如何要提高每次迭代的复杂性?

0 个答案:

没有答案