编写此递归逻辑的最佳方法是什么?

时间:2019-02-12 17:15:30

标签: c#

我正在尝试为概率树编写深度优先遍历逻辑。这是我要完成的一些示例代码。

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一起出现,等等。

我第一次尝试将此模型建模为一棵大树,并列举所有可能性,并使用类似于以下建议的递归方法。这导致创建了不切实际的对象,其中大多数是仅具有不同父对象的现有对象的副本。

这种尝试是将其分成不同的概率树,然后将它们“连接”在一起,但是我无法提出可扩展的逻辑。

很有可能我没有想到一个更好的结构,并且希望得到任何输入。我想要的是从所有可用的“路径”中计算出达到特定结果的可能性。

1 个答案:

答案 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类。该树仅由根节点表示。