生成新的子对象时,State对象会覆盖以前的子对象

时间:2014-11-08 19:30:35

标签: java state backtracking

我在框架中使用回溯来处理带有绑定修剪的图形着色问题。 图的每个可能状态(即,可以放在图上的每种颜色组合)由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中使用一个数组实例变量来存储它的子节点,但是无济于事。

为什么我的代码会改变我已经生成的孩子的值?

请,谢谢! :)

2 个答案:

答案 0 :(得分:0)

gcolors是一个数组,您可以将其设置为新子项的值

theClone.gcolors = this.gcolors;

然后在nextChild()

中修改gcolors
child.gcolors[firstUncolored] = colors.get(currentColor++);

为避免此类错误,您可以使用不可修改的列表。

答案 1 :(得分:0)

原来问题出在这一行:

 theClone.gcolors = this.gcolors;

这导致所有状态共享一个表示每个节点颜色的数组。我真正想要的是每个国家拥有它自己的阵列。

将该行更改为:

theClone.gcolors = this.gcolors.clone();

只需要一切。谢谢大家的帮助!