如何在C#中实现交互式决策树 [英] How to implement an interactive decision tree in C#

查看:149
本文介绍了如何在C#中实现交互式决策树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要允许用户通过在屏幕上显示的两个简单选择之间进行选择来选择自己的路径,以便前进到下一组选择,直到他们到达其中一个结局为止,即应达到类似的目的:

I need to allow the users choose their own path by picking between two simple choices displayed on their screen in order to progress to the next set of choices, until they get to one of the endings, i.e something like this should be achieved:

我尝试了以下代码,但是每次仅评估左侧.我想知道如何获得如上图所示的结果(覆盖所有分支)?例如,如果用户选择否",则应用程序不应再向用户提出任何其他问题,而只是显示也许您想要比萨饼"消息.我已经用决策树算法做到了这一点,需要对其进行修复,以使其像上面的图像一样覆盖左右两侧.

I have tried the following code, but only the left side is evaluated each time. I am wondering how can I achieve a results like the above image (covering all the branches)? For instance, if the user selects "No" the application shouldn't ask any further question from the user and just simply shows the "Maybe you want a Pizza" message. I have done this with decision tree algorithm and need to fix it, so that it covers both the left and right sides just like the above image.

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            var decisionTree = MainDecisionTree();

            var client = new Client();

            Console.WriteLine("Do you want a book? true/false");
            client.Answer[0] = bool.Parse(Console.ReadLine());
            Console.WriteLine("Do you like it? true/false");
            client.Answer[1] = bool.Parse(Console.ReadLine());
            Console.WriteLine("Are you sure? true/false");
            client.Answer[2] = bool.Parse(Console.ReadLine());

            decisionTree.Evaluate(client);

            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }

        private static DecisionQuery MainDecisionTree()
        {
            //Decision 2
            var wantBranch = new DecisionQuery
            {
                Title = "Do you want a book?",
                Test = (client) => client.Answer[0],
                Positive = new DecisionResult { Result = true },
                Negative = new DecisionResult { Result = false }
            };

            //Decision 1
            var deserveBranch = new DecisionQuery
            {
                Title = "Do you like it?",
                Test = (client) => client.Answer[1],
                Positive = wantBranch,
                Negative = new DecisionResult { Result = false }
            };


            //Decision 0
            var sureBranch = new DecisionQuery
            {
                Title = "Are you sure?",
                Test = (client) => client.Answer[2],
                Positive = deserveBranch,
                Negative = new DecisionResult { Result = false }
            };

            return sureBranch;
        }
    }

    public class DecisionResult : Decision
    {
        public bool Result { get; set; }

        public override void Evaluate(Client client)
        {
            Console.WriteLine("\r\nThe result: {0}", Result ? "Buy it" : "You need to wait");
        }
    }

    public class DecisionQuery : Decision
    {
        public string Title { get; set; }
        public Decision Positive { get; set; }
        public Decision Negative { get; set; }
        public Func<Client, bool> Test { get; set; }

        public override void Evaluate(Client client)
        {
            bool result = this.Test(client);
            string resultAsString = result ? "yes" : "no";

            Console.WriteLine($"\t- {this.Title}? {resultAsString}");

            if (result) this.Positive.Evaluate(client);
            else this.Negative.Evaluate(client);
        }
    }

    public abstract class Decision
    {
        public abstract void Evaluate(Client client);
    }

    public class Client
    {
        public bool[] Answer { get; set; } = new bool[3];
    }
}

推荐答案

如果我了解您的问题,那么您的代码已更正.

If I understand your issue, here is your code corrected.

我重命名了一些东西.

我称为MakeDecisionTree,该方法使用条件树初始化专家系统并返回根条件.

I called MakeDecisionTree the method that initializes the expert system with the conditions tree and it returns the root condition.

每个condition包含一个sentenceevaluate,并且可以是queryresult.

Each condition contains a sentence to evaluate and it can be a query or a result.

对于resultevaluate显示sentence.

对于queryevaluate方法要求用户通过yesno回答问题.并使用此答案,它调用下一个子condition的相应evaluate.

For a query, the evaluate method asks the user to answer the question by yes or no. And using this answer, it calls the corresponding evaluate of the next child condition.

抱歉,我的英语不是我的母语,并且我不参与AI.

Sorry for my english here, it is not my native language, and I'm not involved in AI.

static private void DecisionTreeTest()
{
  Console.WriteLine("Please, answer a few questions with yes or no.");
  Console.WriteLine();
  MakeDecisionTree().Evaluate();
}

static private bool GetUserAnswer(string question)
{
  Console.WriteLine(question);
  string userInput;
  while ( true )
  {
    userInput = Console.ReadLine().ToLower();
    if ( userInput == "yes" )
      return true;
    else
    if ( userInput == "no" )
      return false;
    else
      Console.WriteLine("Your answer is not supported, retry please." +
                        Environment.NewLine + Environment.NewLine +
                        question);
  }
}

static private DecisionTreeQuery MakeDecisionTree()
{
  var queryAreYouSure
    = new DecisionTreeQuery("Are you sure?",
                            new DecisionTreeResult("Buy it."),
                            new DecisionTreeResult("You need to wait."),
                            GetUserAnswer);
  var queryIsItAGoodBook
    = new DecisionTreeQuery("Is it a good book?",
                            new DecisionTreeResult("What are you waiting for? Just buy it."),
                            new DecisionTreeResult("Find another one."),
                            GetUserAnswer);
  var queryDoYouLikeIt
    = new DecisionTreeQuery("Do you like it?",
                            queryAreYouSure,
                            queryIsItAGoodBook,
                            GetUserAnswer);
  var queryDoYouWantABook
    = new DecisionTreeQuery("Do you want a book?",
                            queryDoYouLikeIt,
                            new DecisionTreeResult("Maybe you want a pizza."),
                            GetUserAnswer);
  return queryDoYouWantABook;
}

abstract public class DecisionTreeCondition
{
  protected string Sentence { get; private set; }
  abstract public void Evaluate();
  public DecisionTreeCondition(string sentence)
  {
    Sentence = sentence;
  }
}

public class DecisionTreeQuery : DecisionTreeCondition
{
  private DecisionTreeCondition Positive;
  private DecisionTreeCondition Negative;
  private Func<string, bool> UserAnswerProvider;
  public override void Evaluate()
  {
    if ( UserAnswerProvider(Sentence) )
      Positive.Evaluate();
    else
      Negative.Evaluate();
  }
  public DecisionTreeQuery(string sentence,
                           DecisionTreeCondition positive,
                           DecisionTreeCondition negative,
                           Func<string, bool> userAnswerProvider)
    : base(sentence)
  {
    Positive = positive;
    Negative = negative;
    UserAnswerProvider = userAnswerProvider;
  }
}

public class DecisionTreeResult : DecisionTreeCondition
{
  public override void Evaluate()
  {
    Console.WriteLine(Sentence);
  }
  public DecisionTreeResult(string sentence)
    : base(sentence)
  {
  }
}

这篇关于如何在C#中实现交互式决策树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆