2014-11-08 49 views
0

我在框架中使用回溯來處理帶約束脩剪的圖着色問題。圖形的每個可能的狀態(即,可以放在圖上的顏色的每個組合)由狀態對象表示。該框架要求每個國家生產所有的孩子,選擇最合適的孩子,並重復尋找最佳解決方案,並沿途修剪。我碰到的麻煩是這樣的:狀態對象在生成新對象時覆蓋以前的孩子

當我在一個狀態下調用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, , , , , , 

我說這個輸出是不幸的,因爲爲了使回溯框架的工作,我需要所有這些孩子的存儲在同一時間,不同的值。我曾嘗試在每個州內使用數組實例變量來存儲它的子項,但無濟於事。

爲什麼我的代碼改變了我已經生成的孩子的值?

請謝謝! :)

回答

0

gcolors是你設置爲新的子值

theClone.gcolors = this.gcolors; 

然後修改gcolors在nextChild()數組

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

爲了避免這樣的錯誤,你可以使用一個改爲不可修改的列表。

+0

我不知道我明白 - 我應該讓gcolors變量最終?由於我的代碼試圖修改它,是不是隻是拋出異常? – 2014-11-08 19:45:56

+0

如果你想保留年齡較大的孩子,那麼你不能覆蓋他們的狀態。你可以使GraphColoringState不變,方法是使所有變量都是最終的,並用列表替換gcolors數組。通過調用Collections.unmodifiableList(..)將列表包裝到一個不可修改的列表中,確保該列表也是不可變的。這樣,你不可能意外地改變前一個孩子的狀態。但是,原來的錯誤似乎是你複製gcolors數組然後修改它。 – avidD 2014-11-08 19:56:34

+0

我明白了。 那麼,我找到了一個解決方案 - 我只是改變了行 theClone.gcolors = this.gcolors; 閱讀 theClone.gcolors = this.gcolors.clone(); 真的非常簡單,我可能不需要打擾你們都與它。 謝謝你的建議,祝你有美好的一天! – 2014-11-08 20:35:48

0

原來,問題是在這個行:

theClone.gcolors = this.gcolors; 

這導致所有國家的共享一個陣列表示每個節點的顏色。我真正想要的是每個國家擁有自己的陣列。

更改該行:

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

是需要所有。感謝大家的幫助!