2012-11-02 40 views
1

我對自定義樹有點麻煩。我正在編寫一個「學習」動物的程序。讓我們從節點開始。我從一個名爲BTNode的類開始。它包含一個字符串值和一個「右」和「左」BTNode。然後,我將BTNode擴展到名爲DecisionTreeNode的抽象類。 DecisionTreeNode由ThingNode和QuestionNode擴展。 Thing節點僅用於葉節點,其字符串值是動物的名稱。 QuestionNode將持有區分動物的問題,並且應始終有兩個子節點。Java自定義樹節點交換

所以,這個想法是,它會通過詢問用戶提供的問題來學習。因此,它首先要求用戶考慮動物,然後問「這是一個?」,如果我回答「否」,它會詢問我的答案,並提出一個區分兩者的問題。例如,我可以用一個thingNode(「mouse」)「種下」樹,如果我想到一條魚,那麼我會回答它的第一個問題「不」,然後提供一個問題, 「它生活在水中嗎?」。現在下一次,它會開始問:「它生活在水中嗎?」並且「是」會導致「是魚」,而「否」會導致「是鼠標嗎?」。

所以,我會在下面發佈我的「學習」方法。我想我有一個引用問題。我將DecisionTreeNode傳遞給學習方法,但我對它做的更改不是級聯備份。不知道我是否正確解釋。該方法適用於第一次運行,您會看到將根節點從Thing更改爲Question的位置,並將其子節點設置爲兩個動物。然而,這對於「當前」(傳遞到方法中的葉節點)不起作用,學習方法的最後一行是不按預期行事的行。

對不起,文本牆,讓我知道你是否想要更多的代碼發佈或任何其他信息。 在此先感謝。

最初將「root」傳遞給play方法。

public static void play(DecisionTreeNode current) { 
    while(!current.isLeaf()) { 
     if(queryUser(current.getValue())) { 
      current = current.getYesLink(); 
     } 
     else { 

      current = current.getNoLink(); 
     } 
    } 
    System.out.println("Is it a " + current.getValue() + "?"); 
    if(!queryUser("Correct?")) { 
     learn(current); 
    } 
    else { 
     System.out.println("I win!"); 
    } 
} 




public static void learn(DecisionTreeNode current) { 
     String currentGuess; 
     String correctGuess; 
     String newQuestion; 
     ThingNode tempNode; 

     currentGuess = current.getValue(); 
     System.out.println("I give up, what animal were you thinking of?"); 

     correctGuess = stdin.nextLine(); 
     System.out.println("Please enter a yes or no question that distinguishes a " + correctGuess + " from a " + currentGuess +": "); 

     newQuestion = stdin.nextLine(); 

     tempNode = (ThingNode)current; 
     if(current == root) { 
      if(queryUser("")) { 
       root = new QuestionNode(newQuestion, tempNode, new ThingNode(correctGuess)); 
      } 
      else { 
       root = new QuestionNode(newQuestion, new ThingNode(correctGuess), tempNode); 
      } 
     } 
     else { 
      current = new QuestionNode(newQuestion, tempNode, new ThingNode(correctGuess)); 
     } 
    } 

回答

1

你的問題是在這裏:

else { 
    current = new QuestionNode(newQuestion, tempNode, new ThingNode(correctGuess)); 
} 

當前是參數的方法。它是對值爲的DecisionTreeNode 的引用。 設置current這裏不會更改傳遞給該方法的current

您可以在current父傳遞給函數和調整其參考current或創建一個replace(Node, Node)方法,你可以調用像parent.replace(leaf, createNewLearnedNode(leaf))

+0

好吧,我認爲這是問題,但我仍然不明白如何解決它。如果我理解正確,那麼您的兩條建議都需要我在播放方法的while循環期間跟蹤兩個節點(父 - 子)並將它們傳遞給它們。 –

+1

正確。您需要父級,因此您可以修改它並替換它指向的其中一個節點。您還需要用戶啓用的葉節點,以便您可以構建新的QuestionNode。 (或者你需要用戶的是/否,所以你可以直接從父節點獲得節點。) –

+0

想想我已經解決了,謝謝你們。 –