【问题标题】:make big process on graph with python parallelised使用 python 并行化在图上进行大处理
【发布时间】:2019-10-24 14:26:41
【问题描述】:

我正在研究复杂网络的图表和大型数据集。我使用 ndlib 库对它们运行 SIR 算法。 但每次迭代需要 1Sec 之类的时间,它使代码需要 10-12 小时才能完成。 我想知道有没有办法让它并行化? 代码如下所示

这行代码是核心:

sir = model.infected_SIR_MODEL(it, infectionList, False)

有什么简单的方法让它在多线程或并行上运行?

count = 500
for i in numpy.arange(1, count, 1):

    for it in model.get_nodes():

        sir = model.infected_SIR_MODEL(it, infectionList, False)

每次迭代:

 for u in self.graph.nodes():

            u_status = self.status[u]
            eventp = np.random.random_sample()
            neighbors = self.graph.neighbors(u)
            if isinstance(self.graph, nx.DiGraph):
                neighbors = self.graph.predecessors(u)

            if u_status == 0:
                infected_neighbors = len([v for v in neighbors if self.status[v] == 1])
                if eventp < self.BetaList[u] * infected_neighbors:
                    actual_status[u] = 1
            elif u_status == 1:
                if eventp < self.params['model']['gamma']:
                    actual_status[u] = 2

【问题讨论】:

  • 这取决于 - 迭代是否独立?只有其中一个是独立的 - 哪一个?或者model 在迭代过程中会发生变化吗?
  • 在每个节点进程上都有一个 for 和它。我认为它们是独立的。一个接一个@MarekSchwarz
  • 模型是静态的
  • 问题是,如果在处理过程中,model 是否以某种方式改变了......?或者,如果您可以独立于 i=100 运行 i=10。好的..
  • infectionList 也是静态的?

标签: python python-3.x graph parallel-processing


【解决方案1】:

所以,如果迭代是独立的,那么我看不到 count=500 上的迭代点。无论哪种方式,您都可能对 multiprocessing 库感兴趣。

我准备了 2 个存根解决方案(即根据您的确切需求进行更改)。 第一个期望每个输入都是静态的(据我所知,OP 的问题是从每次迭代中的随机状态生成引起的解决方案的变化)。使用第二个,您可以在i 的迭代之间更新输入数据。我没有尝试过代码,因为我没有model,所以它可能无法直接工作。

import multiprocessing as mp


# if everything is independent (eg. "infectionList" is static and does not change during the iterations)

def worker(model, infectionList):
    sirs = []
    for it in model.get_nodes():
        sir = model.infected_SIR_MODEL(it, infectionList, False)
        sirs.append(sir)
    return sirs

count = 500
infectionList = []
model = "YOUR MODEL INSTANCE"

data = [(model, infectionList) for _ in range(1, count+1)]
with mp.Pool() as pool:
    results = pool.starmap(worker, data)

如果“infectionList”或其他东西在“i”的每次迭代中得到更新,则第二个建议的解决方案:

def worker2(model, it, infectionList):
    sir = model.infected_SIR_MODEL(it, infectionList, False)
    return sir

with mp.Pool() as pool:
    for i in range(1, count+1):
        data = [(model, it, infectionList) for it in model.get_nodes()]
        results = pool.starmap(worker2, data)

        # process results, update something go to next iteration....

编辑:更清楚地更新了单独提案的答案。

【讨论】:

  • 感谢您的回复。解释:这里的模型是一个复杂的图,我在每个节点上运行“infected_SIR_MODEL”。那么这行代码是什么意思:“data = [(model,infectionList) for _ in range(1, count+1)]”??
  • 我将 count 设置为 10 。我得到了 3 行完全一样的结果。 3 其他再次喜欢每个。其他 2 行是新结果,但实际上有 3 束 res 。为什么答案是这样的?
  • data = [(model, infectionList) for _ in range(1, count+1)] 执行以下操作:列出从 1 到 count + 1 的元组列表(输入到 worker)。据我所知,您的 infected_SIR_MODEL - 你是在函数内部生成一些随机状态。这可能会导致差异。多处理对您的代码没有任何作用。
  • 干得好,谢谢。 Infected_SIR_MODEL() 方法本身使用概率。多处理是否会使某些结果可能完全一样?
  • 您必须在函数内播种 rng 生成器。看到这个stackoverflow.com/questions/12915177/…和这个stackoverflow.com/questions/9209078/…
猜你喜欢
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多