我正在尝试为概率树编写深度优先遍历逻辑。这是我要完成的一些示例代码。
public class ProbBranch
{
public virtual void Execute()
{
// Consequence of this probability branch determined by derived class
}
public virtual double GetProbability()
{
// Returns the probability chance of the probability branch determined by derived
// class
return 1.0;
}
}
public class ProbTree
{
public ProbTree[] DependencyTrees { get; set; }
public ProbBranch[] ProbBranches { get; set; }
public Reset()
{
// Calls other methods in the application to reset the state back to initial
// values
}
public double GetBranchOverallProbability(int branchKey)
{
double overallProbability = 0.0;
double currentProbability = 1.0;
double[] branchProbability = double[DependencyTrees.Length];
if (DependencyTrees[0].ProbBranches[0].GetProbability() > 0)
{
branchProbability[0] = DependencyTrees[0].ProbBranches[0].GetProbability();
Reset();
DependencyTrees[0].branch[0].Execute();
if (DependencyTrees[1].branch[0].GetProbability() > 0)
{
branchProbability[1] = DependencyTrees[1].branch[0].GetProbability();
Reset();
DependencyTrees[0].branch[0].Execute();
DependencyTrees[1].branch[0].Execute();
...
if (DependencyTrees[n-1].branch[0].GetProbability() > 0)
{
branchProbability[n-1] = DependencyTrees[n-1].branch[0].GetProbability();
Reset();
DependencyTrees[0].branch[0].Execute();
DependencyTrees[1].branch[0].Execute();
...
DependencyTrees[n-1].branch[0].Execute();
if (DependencyTrees[n].branch[0].GetProbability() > 0)
{
branchProbability[n] = DependencyTrees[n].branch[0].GetProbability();
Reset();
DependencyTrees[0].branch[0].Execute();
DependencyTrees[1].branch[0].Execute();
...
DependencyTrees[n-1].branch[0].Execute();
DependencyTrees[n].branch[0].Execute();
if (ProbBranches[branchKey].GetProbability() > 0)
{
currentProbability = 1.0;
foreach (double prob in branchProbability)
{
currentProbability *= prob
}
currentProbability *= ProbBranches[branchKey].GetProbability();
overallProbability += currentProbability;
}
}
if (DependencyTrees[n].branch[1].GetProbability() > 0)
{
branchProbability[n] = DependencyTrees[n].branch[1].GetProbability();
Reset();
DependencyTrees[0].branch[0].Execute();
DependencyTrees[1].branch[0].Execute();
...
DependencyTrees[n-1].branch[0].Execute();
DependencyTrees[n].branch[1].Execute();
if (ProbBranches[branchKey].GetProbability() > 0)
{
currentProbability = 1.0;
foreach (double prob in branchProbability)
{
currentProbability *= prob
}
currentProbability *= ProbBranches[branchKey].GetProbability();
overallProbability += currentProbability;
}
}
...
DependencyTrees中的每个条目都需要对其分支进行概率评估,然后执行分支的结果并移至下一棵树。评估完所有分支后,将各个概率相乘并获得参数中指定的分支的概率。到达树的尽头之后,我想首先开始评估最远的分支的其他分支。
我想编写递归以能够对n-DependencyTree执行此逻辑,但是我很难在概念上实现递归循环。任何帮助将不胜感激。
编辑:感谢您的所有输入。我不知道我要做什么。我的应用程序的工作方式是有许多通往特定概率点的路径。
例如,树A具有结果1、2和3。树B具有结果4、5和6。结果1和结果4不能同时出现,结果6只能与结果2一起出现,等等。>
我第一次尝试将此模型建模为一棵大树,并列举所有可能性,并使用类似于以下建议的递归方法。这导致创建了不切实际的对象,其中大多数是仅具有不同父对象的现有对象的副本。
这种尝试是将其分成不同的概率树,然后将它们“连接”在一起,但是我无法提出可扩展的逻辑。
很有可能我没有想到一个更好的结构,并且希望得到任何输入。我想要的是从所有可用的“路径”中计算出达到特定结果的可能性。
答案 0 :(得分:0)
我将简化结构。一棵树由节点组成。它要么具有子节点,要么根据其子节点的概率乘积计算其概率,要么不具有子节点,在这种情况下,它是一个叶子节点,必须产生根据其内部状态计算出的自身概率。
public abstract class ProbNode
{
public ProbNode[] ChildNodes { get; set; }
public abstract double ThisProbability(); // In case it is a leaf node.
public double OverallProbablility()
{
if (ChildNodes == null || ChildNodes.All(n => n == null)) {
// We have a leaf node
return ThisProbability();
} else {
// We have an internal node.
// Get the probability as product of the probabilities of the child nodes.
double p = 1.0;
foreach (ProbNode child in ChildNodes) {
if (child != null) {
p *= child.OverallProbablility(); // <== Recursive call.
}
}
return p;
}
}
}
我不清楚Execute
方法的用途是什么,因此在此示例中未包含它。
请注意,此实现会先自动评估最远的节点,因为每个节点都会获得其子代的概率,然后才能计算自己的子代。
我们不需要Tree
类。该树仅由根节点表示。