在vb.net或c#中寻找算法,但我不知道它的名字!

时间:2010-04-14 08:55:05

标签: c# .net vb.net algorithm

我会尽力解释算法应该做什么:

有一类“食谱”。每个食谱可以包括其他食谱,但不能包括自己或包含它的任何其他食谱。

所以,一个简单的例子就是我们只有两个食谱A&乙

如果A先添加B,那么稍后B就不能添加A,因为它会导致循环。

更复杂的例子是:

A,B,C

(1)食谱C添加B
(2)配方B添加A
(3)配方A试图添加C,但由于这种关系不能。 C - B - A.

我自己可以这样做,我只是想知道这是否是一个标准命名算法,我可以抓住最佳解决方案。

由于

4 个答案:

答案 0 :(得分:7)

在数学/计算机科学术语中,您的结构称为directed graph。你想要一个“Directed Acyclic Graph” - 就是没有循环的那个。

要确定图表中是否存在周期,您可以使用名为 Topological sorting 的算法。它试图重新排列图形,这样如果A指的是B,那么A总是按顺序出现在B之前。如果图表有周期,它会停止。

如果您想在图表中找到所有周期(这对错误消息有帮助),那么 this stackoverflow question and answer 可以提供很多帮助。

作为背景:
图形 =具有通过边链接的节点的任何东西(在您的情况下节点是配方,参考是边)。
定向 =边缘有方向。在你的情况下,这是真的,因为'A'指的是'B',而不是'A'和'B'彼此。

答案 1 :(得分:3)

Topological ordering /循环检测? (如果检测到循环,则拓扑排序算法停止。)

这应该与你正在做的事情很接近。

答案 2 :(得分:1)

鉴于你的条件,我认为你最终会得到的结构是DAG。

因此,如果是,我们可以找出添加新节点是否创建周期然后我们不添加它,否则我们添加它。

class Foo
{
    public List<Foo> Reachables { get; set; }

    public Foo()
    {
        this.Reachables = new List<Foo>();
    }

    public bool Add(Foo other)
    {
        this.Reachables.Add(other); // add it 

        if(other.IsReachable(this)) // then see if it create a cycle
        {
            this.Reachables.Remove(other); // if yes remove it
            return false;
        }
        else
        {
            return true; // else keep it 
        }
    }

    private bool IsReachable(Foo goal) 
    {
        // BFS 

        Queue<Foo> nextQueue = new Queue<Foo>();
        List<Foo> traversed = new List<Foo>();

        bool found = false;

        nextQueue.Enqueue(this);

        while (!found) {

            Foo node = null;

            try { node = nextQueue.Dequeue(); }
            catch { break; }

            traversed.Add(node);

            if (node.Equals(goal)) {
                found = true;
                break;
            } 
            else 
            {
                foreach (Foo neighbor in node.Reachables)
                    if (!traversed.Contains(neighbor) && !nextQueue.Contains(neighbor)) 
                        nextQueue.Enqueue(neighbor);
            }
        }
        return found;
    }

}

class Program
{
    static void Main(string[] args)
    {
        Foo A = new Foo();
        Foo B = new Foo();
        Foo C = new Foo();

        Console.WriteLine(C.Add(B));
        Console.WriteLine(B.Add(A));
        Console.WriteLine(A.Add(C));
        Console.WriteLine(C.Add(A));

    }
}

输出:

True
True
False
True

答案 3 :(得分:0)

请看cycle detection