2014-02-20 60 views
1

我試圖打印出Mini Max的訪問狀態和實用程序。 我有問題時,從終端狀態返回到它的根,從而導致我的訪問狀態實用程序值4錯誤的值。我只是無法弄清楚是什麼原因導致了這個錯誤。我很確定我的最小和最大方法是正確的。MiniMax返回反向效用值

+0

我可以看到你說的什麼是錯的。我甚至不知道我在看什麼。 – zapl

回答

1

以第一狀態在列表中,你需要解釋爲什麼ooxxxo-xo應該是1。如果我重新寫這個我怎麼想,我應該讀它,國家全文:

oox 
xxo 
-xo 

如果我們正確應用x作爲下一步,我們會得到正確的答案。所以,也許問題在於你的移動世代。

看着這個,你有一個存儲移動的靜態數組,但是當你進行遞歸調用時,你會一遍又一遍覆蓋這個移動。相反,您需要每次遞歸調用的移動的本地副本。因此,將您的minChildrenmaxChildren的定義移動到MinTurnMaxTurn應該修復代碼中的至少一個問題。 (我沒有驗證,有沒有其他的問題。)

要清楚,你的調用堆棧是這樣的:

MaxTurn call 
    Set maxChildren to legal moves // <--- A 
    Call MinTurn recursively 
    MinTurn call 
     Set minChildren to legal moves 
     Call MaxTurn recursively 
     MaxTurn call 
      Set maxChildren to legal moves // <--- B 
      Call MinTurn recursively 

當你到達行標B要覆蓋maxChildren它們在行A處計算。因此,當程序返回到A時,可用的移動將被覆蓋,並且可能與先前預期的不同。


修復後,我相信你的新問題就像你打印的東西一樣。如果你看一下你的打印代碼,您登錄當前的最大價值,而不是由孩子返回值:

int maxValue = Setting.NEGATIVE_INFINITY; 
maxChildren = generateMoves(state); 
for (State aChildren : maxChildren) { 
    maxValue = Math.max(maxValue, MinTurn(aChildren)); // <-- A 
    nodes.add(aChildren.getState() + " " + maxValue); // <--B 
} 

因此,在該行標有B要打印maxValue爲迄今所看到的所有兒童。如果你想看到孩子的價值,你不應該立即採取行A的最大值,而是存儲結果並記錄下來。然後,取最大值。

你有這個狀態的缺陷:

oox 
xxo 
--- 

的第一個舉動是把X中:

oox 
xxo 
-x- 

這是從哪兒搜索可能開始從父狀態印刷左下角,贏得比賽並給出1的值。當第二次移動被應用時,導致x在中間的狀態,maxValue仍然是前一次移動的1。

您的代碼應該是這個樣子:

int nextValue = MinTurn(aChildren) 
maxValue = Math.max(maxValue, nextValue); 
nodes.add(aChildren.getState() + " " + nextValue); 
+0

我已將靜態數組列表更改爲本地副本數組列表,現在問題已減少到4個錯誤的實用程序值。我不知道爲什麼價值不能取代。這個4錯誤的實用性發生在'O'回合。在聲明變量時是否有錯誤? – user3333603

+0

@ user3333603您應該更新原始問題的底部和更新後的結果,而不是發佈問題的答案。 (我更新我的回答上面解決您的問題。) –

+0

我修改我的最大和最小的方法 公共靜態INT明特恩(州州) { 如果(state.isTerminal()){ 回報state.getUtility (); } else { int value = Setting.POSITIVE_INFINITY; for(State aChildren:generateMoves(state))value = Setting.POSITIVE_INFINITY; value = Math.min(value,MaxTurn(aChildren)); nodes.add(aChildren.getState()+「」+ value); } 返回值; } } 我將值重置爲for循環內的+ inifnity。但仍然是錯誤的。 – user3333603