我在框架中使用回溯來處理帶約束脩剪的圖着色問題。圖形的每個可能的狀態(即,可以放在圖上的顏色的每個組合)由狀態對象表示。該框架要求每個國家生產所有的孩子,選擇最合適的孩子,並重復尋找最佳解決方案,並沿途修剪。我碰到的麻煩是這樣的:狀態對象在生成新對象時覆蓋以前的孩子
當我在一個狀態下調用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, , , , , ,
我說這個輸出是不幸的,因爲爲了使回溯框架的工作,我需要所有這些孩子的存儲在同一時間,不同的值。我曾嘗試在每個州內使用數組實例變量來存儲它的子項,但無濟於事。
爲什麼我的代碼改變了我已經生成的孩子的值?
請謝謝! :)
我不知道我明白 - 我應該讓gcolors變量最終?由於我的代碼試圖修改它,是不是隻是拋出異常? – 2014-11-08 19:45:56
如果你想保留年齡較大的孩子,那麼你不能覆蓋他們的狀態。你可以使GraphColoringState不變,方法是使所有變量都是最終的,並用列表替換gcolors數組。通過調用Collections.unmodifiableList(..)將列表包裝到一個不可修改的列表中,確保該列表也是不可變的。這樣,你不可能意外地改變前一個孩子的狀態。但是,原來的錯誤似乎是你複製gcolors數組然後修改它。 – avidD 2014-11-08 19:56:34
我明白了。 那麼,我找到了一個解決方案 - 我只是改變了行 theClone.gcolors = this.gcolors; 閱讀 theClone.gcolors = this.gcolors.clone(); 真的非常簡單,我可能不需要打擾你們都與它。 謝謝你的建議,祝你有美好的一天! – 2014-11-08 20:35:48