【问题标题】:how to use Graph Theory for scheduling execution order? [duplicate]如何使用图论来调度执行顺序? [复制]
【发布时间】:2011-06-25 10:50:37
【问题描述】:

我正在设计一个应用程序,它执行一系列插件。插件的执行可能/可能不依赖于另一个/其他插件的执行。即一些(不是全部)插件期望在它开始执行之前执行其他插件。

我需要派生正确的执行顺序,这样在它所依赖的插件之前不会执行任何插件。

我相信图论可以用来解决这个问题(插件作为顶点,依赖作为边,并使用某种遍历导出执行顺序)。

我打算使用 JGraphT,因为该应用程序是用 Java 开发的。

解决此案的任何帮助或指示???我并不期待整个 java 代码,任何关于图论(使用的算法)的指针都会同样有帮助....

谢谢!!!

[solution:] @Artium 导致了解决方案,这个link 显示了一个非常相似的实现。

【问题讨论】:

标签: java graph-theory job-scheduling jgrapht graph-traversal


【解决方案1】:

我建议topological sort

经过快速检查,与 JGraphT 相关的是 easy。 另请注意:

为了让这个迭代器正常工作,图必须是非循环的,并且不能在迭代期间修改。目前没有办法确保这一点,也没有快速失败的方法;循环输入(包括自循环)或并发修改的结果未定义。要预先检查循环图,请考虑使用 CycleDetector 或 StrongConnectivityInspector。

【讨论】:

  • 如果你有一个循环,那么你就有一个依赖于插件 B 的插件 A,而插件 B 又依赖于 A。拓扑排序不起作用将是你的问题中最少的一个。
  • @toto 是的,但正如@artium 提到的那样,CycleDetector 会处理这个问题,我正在尝试他的建议,很快就会发布我的进展
  • 感谢@Artium TopologicalOrderIterator 以及CycleDetector 完成了所需的操作。
  • 我正在尝试使用 JGraphT 的 TopologicalOrderIterator 来获取调度顺序。迭代器一次返回一个节点。但是在拓扑排序中,每次迭代可能会有更多的候选者。是否有可能获得所有候选人,以便我可以对他们进行并行执行?
  • @amrk7 不熟悉 JGraph,但您可以对 Kahn 算法进行一些小改动 (en.wikipedia.org/wiki/Topological_sorting)
【解决方案2】:

我会建议一个简单的按需加载方法,加载插件依赖的所有插件(如果尚未加载)。

一些观察:

  1. 如果依赖关系树非常深(> 1,000 个插件),这可能会导致 StackOverflowException
  2. 这个解决方案是线程安全的,假设所有的插件都是一个一个同步加载的
  3. 在“图表”中查找非法循环通过使用starting 标志来处理,该标志在加载所有依赖项之前设置为true,仅在插件初始化后设置回false
  4. 此案例处理插件显式启动另一个插件的情况(不作为其依赖项的一部分,但不考虑异步初始化)

这是一个未经测试的示例,可以提供一个想法:

class Plugin {
    Set<Plugin> dependencies;
    boolean started, starting;

    Plugin(Set<Plugin> deps) { dependencies = deps; }

    void start() {
        if (started) { /* already initialized */ }
        else if (starting) { throw new IllegalArgumentException("Cyclic plugin dependency"); }
        else {
            starting = true;
            for (Plugin p : dependencies) { p.start(); }
            /* initialize this plugin here */
            starting = false;
            started = true;
        }
    }
}

【讨论】:

  • 插件不是运行时相互依赖的,应用程序更像是一个构建工具,我以特定的顺序执行插件,无论如何我不希望插件被持有引用(设置 deps),我正在寻找一个解决方案,您只需将特定插件 id 提及为依赖项,因此基于信息的主程序将决定执行顺序。谢谢。
  • 您仍然可以通过使用int 而不是Plugin 并基本上提取正确的ID 顺序来使用这种方法——但是进行拓扑排序是您更好的选择。
  • 试图提取正确的 id 序列将迫使插件编写者决定序列......它可以使用 Comparable 接口实现,我希望程序“解决”订单......我将尝试使用拓扑排序...谢谢
猜你喜欢
  • 2020-04-30
  • 2011-08-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2012-05-26
  • 2012-06-08
  • 2010-12-23
相关资源
最近更新 更多