关于 N-Queen 求解的疑问?

发布于 2024-09-27 10:27:02 字数 932 浏览 3 评论 0原文

我解决了N皇后问题,条件是每列只能有一个皇后。因此,我将皇后放置在第一列的方格中,然后移动到下一列,并将皇后放置在船上未被皇后攻击的方格中。 我能够用这种方法找到所有解决方案,但在 n=13 之后开始需要很长时间。我还发现问题的大多数解决方案都可以通过极少数不同解决方案的旋转和反射来找到。例如,8 皇后问题共有 92 个解决方案,其中只有 12 个是不同的。 (http://en.wikipedia.org/wiki/Eight_queens_puzzle)

所以我的问题是如何检查板的这些状态并仅将这些状态推入堆栈以提供不同的解决方案?

这就是我现在正在做的事情。

typedef struct state{
    int board[N][N];
    int col;
}state;

state cur;
state next;

stack<state> myS;
myS.push(emptyBoard);

while(!myS.empty()){           
      cur=myS.top(); myS.pop();
      if(cur.col==n){
          count++;
          continue;
      }
      for(i=0;i<n;i++){
          next=cur;
          if(cur.board[i][cur.col]==available){
              next.board[i][cur.col]=occupied;
              markConflicts(i,cur.col);          //mark squares attacked by queen as conflicted
              next.col=cur.col+1;
              myS.push(next);
          }
      }  
  } 

I solved the N- Queen problem with the condition that there can only be one queen per column. So I place a queen in a square in first column, then move onto the next column and place a queen in a square not attacked by the queen on board.
I am able to find all solutions with this approach but it starts taking a long time after n=13. Also I found that most of the solutions of the problem can be found by rotations and reflections of a very few distinct solutions.E.g 8 queen problem has 92 total solutions out of which only 12 are distinct. (http://en.wikipedia.org/wiki/Eight_queens_puzzle)

So my question is how do I check for these states of the board and only push those states onto the stack which give a distinct solution?

This is what I am doing right now.

typedef struct state{
    int board[N][N];
    int col;
}state;

state cur;
state next;

stack<state> myS;
myS.push(emptyBoard);

while(!myS.empty()){           
      cur=myS.top(); myS.pop();
      if(cur.col==n){
          count++;
          continue;
      }
      for(i=0;i<n;i++){
          next=cur;
          if(cur.board[i][cur.col]==available){
              next.board[i][cur.col]=occupied;
              markConflicts(i,cur.col);          //mark squares attacked by queen as conflicted
              next.col=cur.col+1;
              myS.push(next);
          }
      }  
  } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

霓裳挽歌倾城醉 2024-10-04 10:27:02

好吧,只有在有了解决方案后,您才能检查唯一的解决方案。要检查的位置是您递增 count 变量的位置。此时,将当前板与一组独特的板进行比较,如果它不在该组中,则将新的解决方案添加到其中。

至于您的速度,您的解决方案在推送和弹出 state 值时存在瓶颈。板越大,速度就越慢。

一种更快的方法是只有一个棋盘,并让每个方格记录控制该方格的皇后的数量。所以你会得到这样的结果:

function scan (column)
   if column == number of columns (zero based index)
     check solution
   else
     if there's a free space
       add queen
       increment controlled squares in columns to right of current column
       scan (column+1)
       decrement controlled squares in columns to right of current column
       remove queen

这样推送/弹出的数据要少得多,并且会大大提高速度。

Well, you can only check for a unique solution once you have a solution. The place to check is at the point you increment the count variable. At this point, compare the current board to a set of unique boards and if it's not in the set then add the new solution to it.

As for your speed, your solution has a bottleneck when pushing and popping the state value. The bigger the board, the slower this becomes.

A much faster way is to only have one board and have each square keep a count og the number of queens controlling the square. So you'd have this:

function scan (column)
   if column == number of columns (zero based index)
     check solution
   else
     if there's a free space
       add queen
       increment controlled squares in columns to right of current column
       scan (column+1)
       decrement controlled squares in columns to right of current column
       remove queen

This has far less data being pushed / popped and will greatly increase the speed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文