如何在python的循环中使用多处理快速生成解决方案?

Posted

技术标签:

【中文标题】如何在python的循环中使用多处理快速生成解决方案?【英文标题】:How to use multiprocessing in a loop in python to generate solutions quickly? 【发布时间】:2020-05-10 05:53:41 【问题描述】:

我以前没有在我的任何程序中使用过多处理,我想了解它是如何实现的。我可以使用具有 24 个内核的机器,并且目前正在进行优化项目。

def compute_euclidean_distance_matrix(locations):
"""Creates callback to return distance between points."""
distances = 
for from_counter, from_node in enumerate(locations):
    distances[from_counter] = 
    for to_counter, to_node in enumerate(locations):
        if from_counter == to_counter:
            distances[from_counter][to_counter] = 0
        else:
            # Euclidean distance
            distances[from_counter][to_counter] = (int(
                math.hypot((from_node[0] - to_node[0]),
                           (from_node[1] - to_node[1]))))
return distances

这是我目前用来构建距离时间矩阵的代码。对于 1000 点左右的数据集,它会很快生成输出,但是假设我有一个 50000 点的数据集,如何使用我 PC 上的所有内核快速计算?

【问题讨论】:

【参考方案1】:

使用multiprocessing.Pool

修改您的距离函数以仅计算 一个 值,并将其用作池工作者。

from functools import partial
from itertools import combinations_with_replacement
from collections import defaultdict
import multiprocessing
import math


def distance(fromto, locations):
    fromindex, toindex = fromto
    if fromindex == toindex:
        return (fromindex, toindex, 0.0)
    fn, tn = locations[fromindex], locations[toindex]
    return (fromindex, toindex, math.hypot((fn[0] - tn[0]), (fn[1] - tn[1])))


locations = [(1, 2), (3, 4), (6, 9)]  # just an example...
pool = multiprocessing.Pool()
worker = partial(distance, locations=locations)
distance = defaultdict(dict)

for fromindex, toindex, distance in pool.imap_unordered(
    worker, combinations_with_replacement(range(len(locations)), 2)
):
    distance[fromindex][toindex] = distance

Pool workers 只能得到 一个 参数,所以我们将 fromindextoindex 组合成一个元组。 出于同样的原因,我们使用partial 为其提供locations 列表。

使用combinations_with_replacement 只是为池生成元组的一种优雅方式:

In [1]: from itertools import combinations_with_replacement                                              

In [2]: locations = [(1, 2), (3, 4), (6, 9)]                                                             
Out[2]: [(1, 2), (3, 4), (6, 9)]

In [3]: list( combinations_with_replacement(range(len(locations)), 2) )                                  
Out[3]: [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]

【讨论】:

以上是关于如何在python的循环中使用多处理快速生成解决方案?的主要内容,如果未能解决你的问题,请参考以下文章

C#多线程实现循环。界面会假死怎么办?

在函数内多处理 Python 中的 for 循环

贝宝多卖家中的无限循环

Python中如何快速生成注释文档?

Python面试必考重点之列表,元组和字典第六关——快速调换字典中的key和value/用循环快速生成一个从0到100的列表

Python列表的元素比较