包含特定链接的有向非循环图中的路径总数

时间:2014-02-20 20:09:33

标签: python path directed-acyclic-graphs totals

我一直在尝试编写一个算法,该算法采用一组有向节点(我现在表示为稀疏的有向邻接矩阵),比如A,B,C和D,当被调用时,给出了包含给定路径(例如AB或AD)的所有可能路径。节点无法连接到自身,并且最终将所有节点定向为从A流向D.

到目前为止,我已尝试编写一个递归python脚本,但成功有限 - 我的图论不强(我实际上没有背景)。任何人都可以提供任何帮助,我应该感谢。

作为免责声明 - 这不是家庭作业(我只是尝试处理大型数据集并为某些研究建立个人库),我已经看了几个小时的“类似问题”,但主要是没有用(除了前面提到的递归python脚本)。

感谢。

2 个答案:

答案 0 :(得分:8)

首先解决更简单的问题:给定DAG中的两个点A和B,您可以计算所有以A开头并以B结尾的路径吗? (“路径”定义为边的列表,其中一个端节点等于下一个节点的起始节点。)

听起来很难。我们可以简化吗?

很明显,最简单的情况是A和B实际上是同一个节点。在这种情况下,路径为零,因为图形是非循环的。

假设A和B不同。 WOLOG假设A恰好有两个邻居C和D,它们都不是B.从A到B的路径数必须等于从C到B的路径数,再加上从D到B的路径数。

更一般地说:如果A有n个邻居,其中没有一个是B,那么找到从每个邻居到B的路径数并将它们相加。

如果A 有邻居B,那么不要忘记在路径A-> B的总数中加一。

现在我们将其分解为许多子问题,每个子问题都严格小于上一个问题。

你会认为一个简单的递归解决方案可以解决这个问题,但不幸的是它没有。考虑一下这个图:

                    A
                   / \
                  C   D
                   \ /
                    E
                   / \
                  F   G
                   \ /
                    H
                   / \
                  I   J
                   \ /
                    B
  • 从A到B的路径等于从C到B的路径加上从D到B的路径。所以计算这些路径。
  • 从C到B的路径等于从E到B的路径。
  • 从D到B的路径等于从E到B的路径。

而且......我们只计算了从E到B两次的路径。这将依次计算从H到B的路径两次,总共四次。我绘制的算法最终可以计算相同的事情2 n 次,其中n与图中节点的数量成正比!

你需要做的是制作一个记忆器,这样一旦答案被计算一次,它就再也不会被计算出来了。

因此,通过制作一个计算两个给定节点之间路径总数的递归,记忆算法来解决更简单的问题。

所以让我们试一试。从A到B有多少条路径?我们用ab表示。我们计算:

ab = cb + db, but we don't know them...
  cb = eb, but we don't know it...
    eb = fb + gb, but we don't know them...
      fb = hb, but we don't know it...
        hb = ib + jb, but we don't know them...
          ib = 1
          jb = 1
        therefore hb = 2
      therefore fb = 2
    gb = hb, but we already know that is 2
    therefore eb = 4
  therefore cb = 4
  db = eb, but we already know that is 4
therefore ab is 8

我们已经完成了。

一旦找到两个节点之间的路径数,就可以直接计算包含给定边的所有路径。例如,从A到B的路径通过E-G,等于从A到E的路径数乘以从G到B的路径数。

我们试一试。

ae = ce + de
  ce = 1
  de = 1
so ae = 2

gb = hb
  hb = ib + jb
    ib = 1
    jb = 1
  so hb = 2
so gb = 2

并且从A到B有ae * gb = 4路径通过EG。我们来看看我们的工作。路径是

AC-CE-EG-GH-HI-IB
AC-CE-EG-GH-HI-JB
AD-DE-EG-GH-HI-IB
AD-DE-EG-GH-HI-JB
是的,有四个。

有意义吗?

答案 1 :(得分:1)

如果您愿意使用外部资源库,请查看networkx及其功能all_simple_paths

假设您有一个包含来源s和接收t的DAG。要查找包含边a -> b的所有路径,请查找从sa的所有路径,以及从bt的所有路径,并获取笛卡尔积这两组路径。