我正在尝试构建一个库来解决不同的约束问题。 我首先尝试了4皇后问题,我无法弄清楚我如何能代表节点。 我的意思是我可以在没有任何树类(通过维数组)的情况下完成它,但我想将其表示为树结构问题。
树的深度总是<= 4
这是我的代码:
class Node { Node []next ; int value; int depth; String name; Node(){ next=null; value=0; depth=0; name=null; } Node(int value,int depth,String name){ this.value=value; //this.next=child; this.depth=depth; this.name=name; }class Tree{ Node root; Stack stack; String[] vars={"Q1","Q2","Q3","Q4"}; int[] domain={1,2,3,4}; int count=0; Tree(){ root=new Node(); stack=new Stack();
}
void start(){ stack.push(root); count++; search(stack.pop(),0); }
boolean consistent(Node current){ boolean flag=true; int n=current.getDepth(); //need more return flag; }
private void search(Node current,int num) { if(num==3&&consistent(current)){ System.out.println("solution !"); num=0; } else{ if(consistent(current)){ Node child[]=new Node[4]; for(int i=0;i<4;i++) child[i]=new Node(domain[i],current.getDepth()+1,vars[num]); current.setNext(child); for(int i=3;i>=0;i--) stack.push(child[i]); search(stack.pop(),num+1); } search(stack.pop(),num); } }<code>
答案 0 :(得分:6)
有很多方法可以解决N皇后问题。你提到了回溯,所以我将解释用这种技术解决它的最佳方法之一。
首先,请注意,同一列中不能有两个皇后:每列必须只有一个皇后,不多也不少。因此,不是将女王位置表示为二维(r, c)
,而是将一个女王准确地分配给一列; q[c] == r
表示分配到c
列的女王位于r
行。
现在你的问题变得更加简单了:现在可以保证不会有两个皇后在同一列上。你现在只需要强制执行其他2个约束:同一行上没有两个皇后,同一对角线上没有两个皇后。
检查两个皇后是否在同一行上是微不足道的:q[c1] == q[c2]
表示两个皇后在同一行。但请注意,您实际上并不需要比较每对皇后的q
值:您可以简单地为每一行分配一个标签,当您在该行上放置一个女王时,您可以标记该行作为“使用”。没有其他女王可以放在已使用的行上。
检查两个皇后是否在同一对角线上并不困难:根据q[c1]
和q[c2]
找到方程式。您可以像对行一样标记对角线。
所以问题现在只是找到[1..N]
的排列,这些排列可以分配给满足所有3个约束的q[1..N]
。我会把剩下的留给你。
答案 1 :(得分:1)
任何时间点问题的状态是棋盘上每列中每个皇后的位置。正如@poly所说,两个皇后不可能在同一列中。 @poly在解释问题的参数方面做得很好。
如果您采取回溯方法,那么您要做的就是为第一位女王选择一个位置,然后继续观察它是否有效。接下来,您选择第二位女王的位置,然后是第三位,最后是第四位。如果第4个不起作用,你将回溯到第三个,如果第三个不起作用,你将回到第二个,等等。
我将在4x4主板上谈论4皇后案例。我认为它的方式是树的根是你做出零选择的地方。根下面的第一层将是四个孩子......第一列中第一个女王的每个可能位置的一个孩子(1,2,3和4)。在树的第二高处,您可以在第二列中选择第二个女王的位置,依此类推。
这是一个部分完成的树:
""
|
-----------------------------------------------
1 2 3 4
| | | |
---------------------
1,1 1,2 1,3 1,4
|
------------------------------------
1,1,1 1,1,2 1,1,3 1,1,4
|
-------------------------------------------------
1,1,4,1 1,1,4,2 1,1,4,3 1,1,4,4
所以树的所有叶子都是形式(A,B,C,D)的元组,其中A是第一个女王的位置,B是第二个的位置,C是第三个的位置, D是第四个位置。
所以我会说每个节点的“价值”是你到目前为止所做的选择。我认为我不认为它是int
。您可以将其保留为string
,如果您愿意或类似ArrayList
之类的内容可能会使您的递归更容易一些。希望有所帮助。
答案 2 :(得分:0)
你把它倒了 - 你应该存储节点的父节点而不是子节点。