【问题标题】:A clean algorithm for sorting a objects according to defined dependencies?根据定义的依赖关系对对象进行排序的干净算法?
【发布时间】:2010-01-15 18:54:23
【问题描述】:

给定一个继承自这个基础的类的列表:

class Plugin(object):
    run_after_plugins = ()
    run_before_plugins = ()

...以及以下规则:

  • 插件可以提供它们必须运行的插件列表。
  • 插件可以提供之前必须运行的插件列表。
  • 插件列表可能包含也可能不包含在排序约束中指定的所有插件。

谁能提供一个很好的干净算法来排序插件列表?它还需要检测循环依赖项......

 def order_plugins(plugins):
      pass

我想出了几个版本,但没有什么特别整洁:我相信你们中的一些 Art of Computer Programming 类型会喜欢挑战 :)

[注意:问题在 Python 中给出,但显然不仅仅是一个 Python 问题:任何语言的伪代码都可以]

【问题讨论】:

    标签: python algorithm


    【解决方案1】:

    这叫topological sorting

    的规范应用 拓扑排序(拓扑 order) 是在调度一个序列 工作或任务;拓扑排序 算法最早是在 1960 年代初期在 PERT 的背景下 项目调度技术 管理(Jarnagin 1960)。职位 由顶点表示,并且有 如果作业 x 必须是从 x 到 y 的边 在工作之前完成 开始(例如,洗涤时 衣服,洗衣机必须 在我们把衣服送到之前完成 干燥)。然后,拓扑排序给出 执行工作的顺序。

    【讨论】:

    • @Eli:我发现这个问题 (stackoverflow.com/questions/952302/…) 刚才提到了这种排序,但是给出的示例没有两种不同类型的依赖项要排序:该算法可以处理吗这个案子也是?
    • @jkp:它可以转换为那个表示。即 A 说 B 必须在它之前运行,但 C 必须在它之后运行。因此,只有“后”约束,我们说 A 在 B 之后,C 在 A 之后。
    • @Eli:哈哈!是的,我猜当你把它打开时,它会干净利落地应用。一个插件的前约束只是另一个插件的后约束:)
    • 注意:拓扑排序可以解决问题,但可能没有必要。如果他的“输入”是一个插件,他想为其解析一个排序的依赖项列表,那么他只有一个“根”节点,他可以进行更简单的深度优先搜索,并通过一些检查来检测循环。只有当他有多个“输入”插件时,才需要拓扑排序算法。
    【解决方案2】:

    Here 是执行拓扑排序的 Python 代码。

    【讨论】:

    • @ΤZΩΤZΙΟΥ:是的,我也发现了。我想要的有点长:我的版本与我在 Eli 的 cmets 中链接的帖子中给出的示例非常匹配。不管怎样,我学到了一个新技巧,这是主要的:)
    【解决方案3】:

    这叫topological sorting

    这样做涉及几个步骤:

    首先构建一个图,将所有选择的插件作为顶点,将它们的依赖关系作为边。在 deps 归结为相同类型的边缘之前/之后运行。

    接下来构建一个transitiv hull:查看所有插件并添加所有缺少的依赖项。重复此操作,直到集合不再发生变化。

    最后一步:选择一个没有传入边的顶点并执行DFS(或 BFS)搜索。这种算法可以通过循环检测来丰富。

    【讨论】:

      【解决方案4】:

      如果您在插件上定义__lt__ 和相关方法,基于它们是否应该在之前或之后运行,则可以使用sorted() 找到合理的排序。不过,循环仍然是个问题。

      【讨论】:

        【解决方案5】:

        如果您想对存在循环的情况进行良好的诊断,请查看http://en.wikipedia.org/wiki/Strongly_connected_component。我认为,如果您使用类似http://www.cs.sunysb.edu/~skiena/373/notes/lecture16/lecture16.html 中概述的强连接组件的版本,您可以让它以拓扑排序顺序打印出强连接组件。

        【讨论】:

          猜你喜欢
          • 2011-05-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-05
          • 2018-11-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多