如何使用Graph Theory来调度执行顺序?

时间:2011-06-25 10:50:37

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

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

我需要导出正确的执行顺序,以便在插件依赖之前不会执行任何插件。

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

我计划使用JGraphT,因为应用程序是用Java开发的。

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

谢谢!!!

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

2 个答案:

答案 0 :(得分:3)

我建议topological sort

经过快速检查后,与{JGraphT} easy有关。 另请注意:

  

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

答案 1 :(得分:0)

我建议使用一种简单的按需加载方法,如果尚未加载插件,则加载所有插件。

一些观察结果:

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

    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;
            }
        }
    }