【问题标题】:Calculating paths in a graph计算图中的路径
【发布时间】:2009-08-17 11:32:29
【问题描述】:

我必须制定一种方法来制作包含图中所有路径的列表。我的图只有一个开始节点和一个结束节点。每个节点都有一个包含其子节点的列表和另一个包含其父节点的列表。我必须制作另一个包含所有路径的列表(每个路径都在另一个列表中)

有什么建议吗??

【问题讨论】:

  • 从每个节点到每个节点或从开始到结束的所有路径?有没有周期?
  • 您将不得不提供更多信息。什么是允许的,什么是不允许的?如前所述,是否存在周期?
  • 这种问题最好标记为[作业],如果是这样的话。事实上,我更希望版主现在已经标记了它。

标签: algorithm graph-theory


【解决方案1】:

这取决于它是否是非循环的。显然,一个循环将导致无限的路径(一次循环,两次循环,3次循环......等等)。如果图表是非循环的,那么您应该能够进行深度优先搜索 (DFS) (http://en.wikipedia.org/wiki/Depth-first_search) 并简单地计算遇到目标节点的次数。

【讨论】:

    【解决方案2】:

    首先熟悉基本的图算法(试试教科书或谷歌)。找出哪一个最适合您正在解决的问题,然后实施它。您可能需要稍微调整一下算法,但一般来说,所有基本图问题都有广为人知的算法。

    【讨论】:

      【解决方案3】:

      如果你有一个看起来像这样的 GraphNode 类:

      public class GraphNode
      {
          public IEnumerable<GraphNode> Children { get; set; }
          // ...
      }
      

      然后这个就可以完成工作了:

      public static class GraphPathFinder
      {
          public static IEnumerable<IEnumerable<GraphNode>> FindAllPathsTo(this GraphNode startNode, GraphNode endNode)
          {
              List<IEnumerable<GraphNode>> results = new List<IEnumerable<GraphNode>>();
              Stack<GraphNode> currentPath = new Stack<GraphNode>();
              currentPath.Push(startNode);
      
              FindAllPathsRecursive(endNode, currentPath, results);
      
              return results;
          }
      
          private static void FindAllPathsRecursive(GraphNode endNode, Stack<GraphNode> currentPath, List<IEnumerable<GraphNode>> results)
          {
              if (currentPath.Peek() == endNode) results.Add(currentPath.ToList());
              else
              {
                  foreach (GraphNode node in currentPath.Peek().Children.Where(p => !currentPath.Contains(p)))
                  {
                      currentPath.Push(node);
                      FindAllPathsRecursive(endNode, currentPath, new List<IEnumerable<GraphNode>>());
                      currentPath.Pop();
                  }
              }
          }
      }
      

      这是 DFS 算法的简单实现。没有错误检查、优化、线程安全等...

      此外,如果您确定您的图表不循环,您可以在最后一个方法中删除 foreach 语句中的 where 子句。

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        您可以生成所有可能的顶点组合(使用组合算法)并过滤掉不存在的路径(顶点没有被边连接或边上的方向错误)。

        您可以通过让生成组合的代码检查当前顶点中可用的剩余顶点来改进这个基本概念。

        这一切都假设您有无环图并希望只访问每个顶点一次。

        【讨论】:

          猜你喜欢
          • 2023-01-30
          • 1970-01-01
          • 2018-10-16
          • 2010-11-11
          • 2020-11-05
          • 1970-01-01
          • 1970-01-01
          • 2015-07-14
          • 1970-01-01
          相关资源
          最近更新 更多