簡體   English   中英

編寫此遞歸邏輯的最佳方法是什么?

[英]What is the best way to write this recursion logic?

我正在嘗試為概率樹編寫深度優先遍歷邏輯。 這是我要完成的一些示例代碼。

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-DependencyTrees執行此邏輯,但是我很難概念化可以完成此任務的遞歸循環。 任何幫助將非常感激。

編輯:感謝所有的輸入。 我不知道我要做什么。 我的應用程序的工作方式是有許多通往特定概率點的路徑。

例如,樹A具有結果1、2和3。樹B具有結果4、5和6。結果1和結果4不能一起出現,結果6只能與結果2一起出現,等等。

我第一次嘗試將此模型建模為一棵大樹,並列舉了所有可能性,並使用類似於下面建議的遞歸方法。 這導致創建了不切實際的對象,其中大多數是僅具有不同父對象的現有對象的副本。

這種嘗試是將其分成不同的概率樹,然后將它們“連接”在一起,但是我無法提出可擴展的邏輯。

很有可能我沒有想到更好的結構,並且會感謝您的任何投入。 我想要的是計算從所有可用“路徑”中達到特定結果的概率。

我會簡化結構。 一棵樹由節點組成。 它具有子節點,其概率是根據其子節點的概率乘積計算的,或者它不具有子節點,在這種情況下,它是葉節點,必須產生根據其內部狀態計算出的自身概率。

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類。 該樹僅由根節點表示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM