カスタムツリーに少し問題があります。私は動物について「学ぶ」プログラムを書いています。ノードから始めましょう。私はBTNodeと呼ばれるクラスから始めました。文字列値と「右」および「左」のBTNodeを保持します。次に、BTNodeをDecisionTreeNodeと呼ばれる抽象クラスに拡張しました。DecisionTreeNodeは、ThingNodeとQuestionNodeによって拡張されます。Thingノードは、葉のノードのみを対象としており、その文字列値は動物の名前です。QuestionNodeは動物を区別する質問を保持し、常に2つの子ノードを持つ必要があります。
つまり、ユーザーが入力した質問をすることで学習するという考え方です。それで、それは単にユーザーに動物のことを考えてもらい、次に「それは?」と尋ねることから始まり、私が「いいえ」と答えると、それは私の答えと、2つを区別する質問を求めます。
たとえば、単一のthingNode( "mouse")でツリーを「シード」することができます。魚のことを考えている場合は、最初の質問「no」に答えて、「Doesitlive。水中で?"。さて、次回は「水中に住んでいるの?」と聞くことから始まります。「はい」の場合は「魚ですか」、「いいえ」の場合は「マウスですか?」になります。
それで、私は私の「学ぶ」方法を以下に投稿します。参照に問題があると思います。DecisionTreeNodeをlearnメソッドに渡しますが、それに加えた変更はカスケードバックアップされません。私がその権利を説明しているかどうかはわかりません。この方法は最初の実行で機能します。ルートノードをThingからQuestionに変更し、その子ノードを2匹の動物に設定する場所がわかります。ただし、これは「current」(メソッドに渡されるリーフノード)では機能しません。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));
}
}