我對自定義樹有點麻煩。我正在編寫一個「學習」動物的程序。讓我們從節點開始。我從一個名爲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));
}
}
好吧,我認爲這是問題,但我仍然不明白如何解決它。如果我理解正確,那麼您的兩條建議都需要我在播放方法的while循環期間跟蹤兩個節點(父 - 子)並將它們傳遞給它們。 –
正確。您需要父級,因此您可以修改它並替換它指向的其中一個節點。您還需要用戶啓用的葉節點,以便您可以構建新的QuestionNode。 (或者你需要用戶的是/否,所以你可以直接從父節點獲得節點。) –
想想我已經解決了,謝謝你們。 –