【问题标题】:Collecting all paths of DAG收集 DAG 的所有路径
【发布时间】:2013-01-31 17:41:45
【问题描述】:

我有一个有向无环图,其中每个节点都由一个状态表示

public class State{
   List<State> ForwardStates;
   string stateName;
}

其中ForwardStates 是当前状态下一个状态的列表。

我有两种特殊状态

State initialState (name=initial)
State finalState (name=final)

我希望找到从初始状态最终状态的所有路径,并填充

List<List<string>> paths

例如给出如下图

paths 应该包含值 {{"initial","a","final"},{"initial","b","final"}}

我应该如何在没有递归的情况下在 C# 中轻松实现这一点(因为图可能很大)?

【问题讨论】:

  • 任何算法课程都会教你搜索算法
  • 如果图真的很大,可能的路径数量可能会呈指数增长,并且路径字符串可能甚至无法放入磁盘,更不用说内存
  • 查看此链接以获得处理图的算法的良好描述。为 DAG 跳过大约一半。 (algs4.cs.princeton.edu/42directed)
  • 也许你可以调整 Dijkstra 算法来完成

标签: c# algorithm


【解决方案1】:

你的算法可能是这样的:

  • 创建Tuple&lt;State, List&lt;String&gt;&gt;的队列。
  • 入队{ InitialState, new List&lt;string&gt; { InitialState.Name } }
  • 当队列有任何项目时,
    • 出列第一项
    • 对于所有处于出队状态的非最终转发状态,入队{ ForwardState, DequeuedList.ToList().Add(ForwardState.Name) }
    • 如果最终状态是前向状态,请将DequeuedList.ToList().Add(FinalState.Name) 添加到您的输出列表中。

你应该得到一个空队列和一个你想要的字符串列表列表。

【讨论】:

    【解决方案2】:

    感谢 cmets,我也使用这里的建议 https://stackoverflow.com/a/9535898/1497720 (关键是在 BFS/DFS 期间不使用已访问状态

    这是一个使用 DFS 的版本,没有访问状态

     List<List<string>> paths= new List<List<string>>();
                Stack<Tuple<State, List<string>>> working = new Stack<Tuple<State, List<string>>>();
                working.Push(new Tuple<State,
                    List<string>>(initialNode,
                    new List<string> { initialNode.stateName }));
                do
                {
                    Tuple<State, List<string>> curr = working.Pop();
    
    
                    if (currNexts.stateName == "final")
                    {
                        res.Add(curr.Item2);
                    }
                    else
                    {
                        foreach (State currNext in curr.Item1.ForwardStates)
                        {
                            working.Push(new Tuple<State,
                            List<string>>(rnext, curr.Item2.Union(new[] { rnext.stateName }).ToList()));
                        }
                    }
                } while (working.Count != 0);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 2017-08-21
      • 2022-11-28
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多