English 中文(简体)
3. 尽可能解决N-Queen的算法
原标题:All possible solution of the n-Queen s algorithm

When implementing an algorithm for all possible solution of an n-Queen problem, i found that the same solution is reached by many branches. Is there any good way to generate every unique solutions to the n-Queens problem? How to avoid the duplicate solutions generated by the different branches (except store and compare)?

Here is what i have tried, for the first solution: http://www.ideone.com/hDpr3

法典:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* crude */

#define QUEEN  Q 
#define BLANK  . 

int is_valid (char **board, int n, int a, int b)
{
  int i, j;

  for (i=0; i<n; i++)
  {
    if (board[a][i] == QUEEN)
      return 0;
    if (board[i][b] == QUEEN)
      return 0;
  }

  for (i=a, j=b; (i>=0) && (j>=0); i--, j--)
  {
    if (board[i][j] == QUEEN)
      return 0;
  }

  for (i=a, j=b; (i<n) && (j<n); i++, j++)
  {
    if (board[i][j] == QUEEN)
      return 0;
  }

  for (i=a, j=b; (i>=0) && (j<n); i--, j++)
  {
    if (board[i][j] == QUEEN)
      return 0;
  }

  for (i=a, j=b; (i<n) && (j>=0); i++, j--)
  {
    if (board[i][j] == QUEEN)
      return 0;
  }
  return 1;
}

void show_board (char **board, int n)
{
  int i, j;

  for (i=0; i<n; i++)
  {
    printf ("
");
    for (j=0; j<n; j++)
    {
      printf (" %c", board[i][j]);
    }
  }
}

int nqdfs_all (char **board, int n, int d)
{
  int i, j, ret = 0;

  /* the last queen was placed on the last depth
   * therefore this dfs branch in the recursion 
   * tree is a solution, return 1
   */
  if (d == n)
  {
    /* Print whenever we find one solution */
    printf ("
");
    show_board (board, n);
    return 1;
  }

  /* check all position */
  for (i=0; i<n; i++)
  {
    for (j=0; j<n; j++)
    {
      if (is_valid (board, n, i, j))
      {
    board[i][j] = QUEEN;
    nqdfs_all (board, n, d + 1);
    board[i][j] = BLANK;
      }
    }
  }

  return ret;  
}

int nqdfs_first (char **board, int n, int d)
{
  int i, j, ret = 0;

  /* the last queen was placed on the last depth
   * therefore this dfs branch in the recursion 
   * tree is a solution, return 1
   */
  if (d == n)
    return 1;

  /* check all position */
  for (i=0; i<n; i++)
  {
    for (j=0; j<n; j++)
    {
      if (is_valid (board, n, i, j))
      {
    board[i][j] = QUEEN;
    ret = nqdfs_first (board, n, d + 1);
    if (ret)
    {
      /* if the first branch is found, tell about its 
       * success to its parent, we will not look in other
       * solutions in this function.
       */
      return ret;
    }
    else
    {
      /* this was not a successful path, so replace the
       * queen with a blank, and prepare board for next
       * pass
       */
      board[i][j] = BLANK;
    }
      }
    }
  }

  return ret;
}

int main (void)
{
  char **board;
  int n, i, j, ret;

  printf ("
Enter "n": ");
  scanf ("%d", &n);

  board = malloc (sizeof (char *) * n);
  for (i=0; i<n; i++)
  {
    board[i] = malloc (sizeof (char) * n);
    memset (board[i], BLANK, n * sizeof (char));
  }

  nqdfs_first (board, n, 0);
  show_board (board, n);

  printf ("
");
  return 0;
}

产生所有可能的解决办法,即使用相同的代码nqdfs_all(>功能,但并未将控制权退回到母公司,而是继续进行查点和检查。 对这项职能的呼吁显示了不同部门取得的重复结果。

最佳回答

你们应当利用这样一个事实,即每个问题必须放在一个不同的一栏。 如果您在头几栏中已经放过了电梯,则重新将电梯号加1放在K+1栏,然后进入第1至N栏(而不是像你目前所做的那样通过所有N*n囚室)。 每个有效安置点继续使用k:k+1。 这将避免产生任何重复的结果,因为这一利戈根本不会产生任何重复的董事会。

EDIT: to your question about avoiding of symmetries: a part of those can be avoided beforehand, for example, by restricting queen 1 in column 1 to rows 1,...n/2. If you want to avoid the output of symmetric solutions completely, you will have to store every found solution in a list and whenever you find a new solution, before printing it out, test if one of it s symmetric equivalents is already there in the list.

为了提高这一效率,你可以按以下定义,在每个委员会中进行“扫描”。 形成一个特定委员会的所有对称委员会,将每个委员会都编成一个旁观阵列,在这些阵列中,阵列中,被解读为大数的阵列具有最低价值。 这种包装的代谢是一种独特的识别特征,可以很容易地列入字典/斜面表,这样,如果该等金属类别已经非常有效,就会进行测试。

问题回答

暂无回答




相关问题
How to add/merge several Big O s into one

If I have an algorithm which is comprised of (let s say) three sub-algorithms, all with different O() characteristics, e.g.: algorithm A: O(n) algorithm B: O(log(n)) algorithm C: O(n log(n)) How do ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Enumerating All Minimal Directed Cycles Of A Directed Graph

I have a directed graph and my problem is to enumerate all the minimal (cycles that cannot be constructed as the union of other cycles) directed cycles of this graph. This is different from what the ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签