我有一个决策树,我需要将其转换为 C# 中的代码
简单的方法是使用 if-else 语句,但在这个解决方案中,我需要创建 4-5 个嵌套条件。
我正在寻找一种更好的方法来做到这一点,到目前为止,我阅读了一些关于规则引擎的内容。
对于开发具有 4-5 个嵌套条件的决策树的有效方法,您还有其他建议吗?
我有一个决策树,我需要将其转换为 C# 中的代码
简单的方法是使用 if-else 语句,但在这个解决方案中,我需要创建 4-5 个嵌套条件。
我正在寻找一种更好的方法来做到这一点,到目前为止,我阅读了一些关于规则引擎的内容。
对于开发具有 4-5 个嵌套条件的决策树的有效方法,您还有其他建议吗?
我在书中实现了一个简单的决策树作为示例。该代码可在此处在线获得,因此也许您可以将其用作灵感。决策本质上表示为一个类,该类具有对true
分支和false
分支的引用,并包含一个执行测试的函数:
class DecisionQuery : Decision {
public Decision Positive { get; set; }
public Decision Negative { get; set; }
// Primitive operation to be provided by the user
public Func<Client, bool> Test { get; set; }
public override bool Evaluate(Client client) {
// Test a client using the primitive operation
bool res = Test(client);
// Select a branch to follow
return res ? Positive.Evaluate(client) : Negative.Evaluate(client);
}
}
这里,Decision
是一个包含Evaluate
方法的基类,而源包含一个额外的派生类型,该派生类型包含树的最终决定(是/否)。该类型Client
是您使用树分析的示例输入数据。
要创建决策树,您可以编写如下内容:
var tree = new DecisionQuery {
Test = (client) => client.Income > 40000,
Positive = otherTree,
Negative = someOtherTree
};
如果您只想编写五个嵌套的静态if
子句,那么编写if
就可以了。使用这样的类型的好处是您可以轻松地组合树 - 例如重用树的一部分或模块化构造。
以下是答案https://stackoverflow.com/a/3889544/5288052中提到的 Tomas Petricek 的代码。
包含“Real-World Functional Programming”一书的所有源代码的 zip 可在此处获取https://www.manning.com/books/real-world-functional-programming。
// Section 8.4.2 Decision trees in C#
// Listing 8.15 Object oriented decision tree (C#)
abstract class Decision {
// Tests the given client
public abstract void Evaluate(Client client);
}
class DecisionResult : Decision {
public bool Result { get; set; }
public override void Evaluate(Client client) {
// Print the final result
Console.WriteLine("OFFER A LOAN: {0}", Result ? "YES" : "NO");
}
}
// Listing 8.16 Simplified implementation of Template method
class DecisionQuery : Decision {
public string Title { get; set; }
public Decision Positive { get; set; }
public Decision Negative { get; set; }
// Primitive operation to be provided by the user
public Func<Client, bool> Test { get; set; }
public override void Evaluate(Client client) {
// Test a client using the primitive operation
bool res = Test(client);
Console.WriteLine(" - {0}? {1}", Title, res ? "yes" : "no");
// Select a branch to follow
if (res) Positive.Evaluate(client);
else Negative.Evaluate(client);
}
}
static void MainDecisionTrees()
{
// The tree is constructed from a query
var tree =
new DecisionQuery
{
Title = "More than $40k",
// Test is specified using a lambda function
Test = (client) => client.Income > 40000,
// Sub-trees can be 'DecisionResult' or 'DecisionQuery'
Positive = new DecisionResult { Result = true },
Negative = new DecisionResult { Result = false }
};
// Test a client using this tree
// Create client using object initializer
var john = new Client {
Name = "John Doe", Income = 40000, YearsInJob = 1,
UsesCreditCard = true, CriminalRecord = false
};
tree.Evaluate(john);
}
private static void Main(string[] args)
{
MainDecisionTrees();
}