我在使用自定义树时遇到了一些麻烦。我正在编写一个“学习”动物的程序。让我们从节点开始。我从一个名为 BTNode 的类开始。它包含一个字符串值和一个“右”和“左”BTNode。然后我将 BTNode 扩展为一个名为 DecisionTreeNode 的抽象类。DecisionTreeNode 由 ThingNode 和 QuestionNode 扩展。事物节点仅作为叶节点,其字符串值是动物的名称。QuestionNode 将保存区分动物的问题,并且应该始终有两个子节点。
所以,这个想法是它将通过询问用户提供的问题来学习。因此,它会从简单地让用户想到一种动物开始,然后问,“它是一个吗?”,如果我回答不是,它会询问我的答案,以及一个区分两者的问题。
例如,我可以用一个thingNode(“mouse”)“播种”树,如果我想的是一条鱼,那么我将回答它的第一个问题“否”,并提供一个问题,“它活吗?在水里?”。现在下一次,它会先问:“它生活在水中吗?” “是”将导致“它是一条鱼”,而“否”将导致“它是一只老鼠吗?”。
所以,我将在下面发布我的“学习”方法。我想我有一个参考问题。我将 DecisionTreeNode 传递给 learn 方法,但我对其所做的更改并没有级联备份。不确定我是否解释正确。该方法适用于第一次运行,您将看到我将根节点从事物更改为问题并将其子节点设置为两个动物的位置。然而,这不适用于“当前”(传递给方法的叶节点),学习方法的最后一行是未按预期运行的行。
对不起,文字墙,如果您想发布更多代码或任何其他信息,请告诉我。提前致谢。
“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));
}
}