我在框架中使用回溯来处理带有绑定修剪的图形着色问题。 图的每个可能状态(即,可以放在图上的每种颜色组合)由State对象表示。该框架要求每个国家生产所有儿童,选择具有最佳界限的儿童,并重复以找到最佳解决方案,一路修剪边界。我遇到的麻烦是:
当我在状态上调用nextChild()时,它会将该状态生成的前一个子项更改为刚生成的子项。
以下是我认为是我的代码的相关部分:
public State nextChild() {
// System.out.println("currentColor: "+ colors.get(currentColor) + " firstUncolored " + this.firstUncolored);
// previous line for debugging
GraphColoringState child = childSetup();
child.gcolors[firstUncolored] = colors.get(currentColor++);
if(this.currentColor == colors.size()){
this.currentColor = 0;
this.hasMoreChildren = false;
}
return child;
}
private GraphColoringState childSetup() {
GraphColoringState theClone = new GraphColoringState(graph, colors);
theClone.gcolors = this.gcolors;
theClone.firstUncolored = this.firstUncolored +1;
theClone.currentColor = 0;
return theClone;
}
当我制作和打印这样的孩子时:
State s = new GraphColoringState(graph, colors);
System.out.println(s);
State s1 = s.nextChild();
System.out.println(s1);
State s2 = s.nextChild();
System.out.println(s2);
State s3 = s.nextChild();
System.out.println(s3);
我得到了这个输出:
, , , , , ,
Red, , , , , ,
Green, , , , , ,
Blue, , , , , ,
但是当我以这种方式制作和打印时:
System.out.println(s);
State s1 = s.nextChild();
State s2 = s.nextChild();
State s3 = s.nextChild();
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
我得到了这个不幸的输出:
, , , , , ,
Blue, , , , , ,
Blue, , , , , ,
Blue, , , , , ,
我说这个输出是不幸的,因为为了使回溯框架起作用,我需要同时存储所有这些子项,具有不同的值。我已经尝试在每个State中使用一个数组实例变量来存储它的子节点,但是无济于事。
为什么我的代码会改变我已经生成的孩子的值?
请,谢谢! :)
答案 0 :(得分:0)
gcolors是一个数组,您可以将其设置为新子项的值
theClone.gcolors = this.gcolors;
然后在nextChild()
中修改gcolorschild.gcolors[firstUncolored] = colors.get(currentColor++);
为避免此类错误,您可以使用不可修改的列表。
答案 1 :(得分:0)
原来问题出在这一行:
theClone.gcolors = this.gcolors;
这导致所有状态共享一个表示每个节点颜色的数组。我真正想要的是每个国家拥有它自己的阵列。
将该行更改为:
theClone.gcolors = this.gcolors.clone();
只需要一切。谢谢大家的帮助!