我必须评估一个函数(让我们称之为my_func()),它将8个参数作为输入,并在不同的矩阵计算时返回一个标量。因为我对my_func()没有任何约束,所以我别无选择,只能强行所有可能性达到8 ^ 8 = 16777216.我开始使用itertools的产品函数并将生成的序列顺序传递给my_func() 。请看下面我的代码示例
到目前为止.....
from itertools import product
import numpy as np
def my_func(a,b,c,d,e,f,g,h): #Function that I have to evaluate
#do some matrix computations and return some scalar q#
return q
def Evaluate():
Range = [x for x in np.arange(0,3.60,0.5)] # A list that contains 8 elements
it = itertools.product(Range, repeat=8) #Generate all possiblities
Max = 0
for i in it:
Sum = my_func(*i)
if Sum > Max:
Max = present
return Max
Result = Evaluate() #Output
陷阱...
不幸的是,按顺序执行上述代码需要很长时间才能生成输出。这是因为my_func很重。我别无选择,只能以某种方式并行化此代码,以便我可以利用多个可用的处理器来运行我的代码。
问题:
由于itertools.product是一个生成器,我不能并行化它以同时为不同的参数集评估my_func()。 有什么方法可以并行化代码吗?如果不是asnswer,我是否应该放弃使用itertools并尝试其他的想法?
请帮我找到解决方案。
感谢您提出任何想法。
干杯!!
答案 0 :(得分:4)
您可以并行化发电机!您可以使用multiprocessing
库,该库提供Pool
类,它可以完全满足您的需要。 Here你可以获得更多的文档,但基本上,你想要做的是:
with Pool(processes=4) as pool:
pool.map(my_func, itertools.product(Range, repeat=8))
您应该查看pool.map
的替代方案,找到最适合您的方案。
答案 1 :(得分:3)
您使用的核心数量可能远小于 8 8 。
这导致以下的并行化方案。
上的multiprocessing.Pool.map
itertools.product(<all-combinations-of-first-2-or-3-parameters>)
在每个流程中,对其余参数执行并行化,并仅返回单个结果 - 找到的最佳参数元组。
这比传递每个 8 8 组合要高效得多。这些东西都有开销。
示例强>
假设您决定映射前三个参数。然后,您的product
是一系列三元组:..., (1, 3, 2), ...
。你在每个这样的三元组上使用类似multiprocessing.Pool.map
的东西,所以让我们从函数的角度考虑它:
def find_best_for_triplet(xyz):
x, y, z = xyz[0], xyz[1], xyz[2]
for ... in itertools.product(<all-combinations-of-last-5-parameters>)
# Here you have all 8 of your parameters: x, y, z, and the last 5
return xyz + (last-five-parameters) of the min
在另一个问题上 - 在实践中,Nelder Mead method在优化高维问题方面效果很好,并且比蛮力便宜得多。您可能希望尝试实现它。