依赖树实现

时间:2011-03-13 04:54:44

标签: python computer-science

对于那些使用apt-get的人,您知道每次安装/卸载某些内容时,您都会收到通知,说明您需要/不再需要某些依赖项。

我试图理解这背后的理论,并可能实现我自己的版本。我做了一些谷歌搜索,提出了大多数耦合的东西。据我所知,耦合是两个相互依赖的类/模块。这不是我正在寻找的。我正在寻找的更像是依赖树生成,在那里我可以找到最少依赖的模块(我已经做了这样的递归方式),并且(这是我避风港的一部分&#39完成)找到删除节点后不再需要的内容。

另外,了解图论有用吗?是否有任何教程,最好使用Python作为语言?

5 个答案:

答案 0 :(得分:7)

This可能会引起一些兴趣:

def dep(arg):
    '''
        Dependency resolver

    "arg" is a dependency dictionary in which
    the values are the dependencies of their respective keys.
    '''
    d=dict((k, set(arg[k])) for k in arg)
    r=[]
    while d:
        # values not in keys (items without dep)
        t=set(i for v in d.values() for i in v)-set(d.keys())
        # and keys without value (items without dep)
        t.update(k for k, v in d.items() if not v)
        # can be done right away
        r.append(t)
        # and cleaned up
        d=dict(((k, v-t) for k, v in d.items() if v))
    return r

if __name__=='__main__':
    d=dict(
        a=('b','c'),
        b=('c','d'),
        e=(),
        f=('c','e'),
        g=('h','f'),
        i=('f',)
    )
    print dep(d)

答案 1 :(得分:4)

我写了一个工具,用于在PyPi上查找和绘制Python包之间的依赖关系。这是gluttony

我确实用它来分析我正在使用的某些库的依赖关系。以下是一些图表:

enter image description here enter image description here

我不确定这是你想要的。如果是,您可以阅读源代码here,它是一个开源项目。有关更多依赖关系图,您可以查看gallery

谈到我如何实现它,为了找到包依赖关系,我使用pip作为后端。对于绘制图表,我使用Networkx

答案 2 :(得分:3)

图论是可行的方法。

图表只是一堆地方(顶点),它们之间有道路(边缘),特别是我们谈的是有向图,这意味着单向道路。找出依赖关系基本上意味着找出所有可以沿着单行道到达特定城镇的地方。

所以现在,你已经拥有了大量的模块,它们成了你的顶点。假设我们有A和B,我们知道B依赖于A,所以有一个有向边 - 一条“单向道路” - 从A到B。

如果C取决于B,那么你有A→B→C。

形式上,图形只是顶点和(有序)顶点对的集合,称为边。你想要一个名为“拓扑排序”的图形算法,现在你已经有了一些东西需要阅读。

答案 3 :(得分:0)

  1. 走旧的依赖树。构建其中所有元素的set
  2. 走新的依赖树。和以前一样。
  3. 从前者中减去后者set。结果就是你的答案。
  4. 可替换地:

    1. 走旧的依赖树。在每个节点上,存储依赖于(指向)该节点的事物的数量。
    2. 删除您要删除的项目。遵循所有依赖关系并将其使用次数减少1.如果以这种方式递减会将节点的计数降低为0,则不再需要它。
    3. 前者更容易实现,但效率较低。后者是有效的,但更难实施。

答案 4 :(得分:0)

我认为您正在寻找的步骤是区分显式安装的软件包和依赖项的软件包。完成此操作后,您可以构建所有请求的包的依赖关系树,并将这些包的集合与已安装的包进行比较。假设安装了所有请求的软件包,对这些软件进行异或,应该为您提供不再依赖的所有软件包的集合。