算法找到独立集

时间:2010-03-07 07:35:46

标签: python algorithm data-structures

民间, 我有个问题。我是在python中编写一个脚本,它包含几个模块。某些模块依赖于其他模块,因此只有在成功运行相关模块后才能运行它们。因此,每个模块都派生自一个基类模块,并覆盖一个名为DEPENDENCIES的列表,该列表是在运行此模块时要满足的依赖列表。有一个模块需要在所有其他模块之前运行。目前我正在做这样的事情。

modules_to_run.append(a)
modules_to_run.append(b)
modules_to_run.append(c)
.....
.....     
modules_to_run.append(z)


# Very simplistically just run the Analysis modules sequentially in
# an order that respects their dependencies
foundOne = True
while foundOne and len(modules_to_run) > 0:
    foundOne = False
    for module in modules_to_run:
        if len(module.DEPENDENCIES) == 0:
            foundOne = True
            print_log("Executing module %s..." % module.__name__, log)
            try:
                module().execute()
                modules_to_run.remove(module)
                for module2 in modules_to_run:
                    try:
                        module2.DEPENDENCIES.remove(module)
                    except:
                        #module may not be in module2's DEPENDENCIES
                        pass
            except Exception as e:
                print_log("ERROR: %s did not run to completion" % module.__name__, log)
                modules_to_run.remove(module)
                print_log(e, log)

for module in modules_to_run:
    name = module.__name__
    print_log("ERROR: %s has unmet dependencies and could not be run:" % name, log)
    print_log(module.DEPENDENCIES, log)

现在我看到一些模块需要很长时间才能执行,而脚本调试时间太长。所以我想让它多线程,以便独立的模块可以同时运行,从而节省时间。所以我想要一个解决方案,在每次迭代之后,我将重新计算'n'个独立模块(其中'n'是线程的最大数量,通常是2开始)并且并行执行它们并等待它们在下一次迭代之前完成。我不太了解算法,所以我被卡住了。请各位大家帮帮我找一个算法,在每次迭代后找到最大的'n'组独立模块,这些算法并不相互依赖。

2 个答案:

答案 0 :(得分:2)

我最近发布了topological sorting in a question about make -j的说明。情缘!来自维基百科的文章:

  

拓扑排序(拓扑顺序)的规范应用是安排一系列工作或任务;拓扑排序算法最早是在20世纪60年代早期在PERT技术中用于项目管理中的调度(Jarnagin 1960)。作业由顶点表示,如果在作业y开始之前必须完成作业x,则从x到y存在边缘(例如,洗衣服时,洗衣机必须在我们将衣服晾干之前完成)。然后,拓扑排序给出了执行作业的顺序。

粗略轮廓:

  1. 构建依赖关系图。
  2. 查找没有依赖项的 n 模块。这些可以现在并行执行。
  3. 从图表中删除这些模块。
  4. 重复步骤2直至完成。
  5. 阅读这些链接以获取更详细的说明。

答案 1 :(得分:1)

从您的设置说明中,您也可以直接进行此操作。

看起来每个模块都知道它的依赖关系。然后在每个模块中添加一个谓词函数,说明它是否可以运行,这很简单。当且仅当满足所有模块的先决条件依赖关系时,才能运行模块。

顶级模块没有依赖关系,所以它们可以从一开始就运行。

基本上,这是部分拓扑排序的一个简单实现(您不必探索所有依赖图,只需保持最高级别)。

要注意两个陷阱:

如果你的依赖包含循环(A依赖于B取决于C取决于A)它可能永远循环(这意味着问题没有解决方案)。您应检测此案例并报告和错误。

您可以运行的模块可能少于线程数。这应该不是一个错误。然后,当您有可用的模块运行或者询问每个模块是否可以运行时,您已找到解决方案。