我有以下程序,我想使用多处理模块。它使用外部文件,我在其中从另一个文件调用PSO类。 costfunc
是来自另一个文件的函数,其他args只是变量。
Swarm
是一个包含与ps
的值一样多的对象的列表,每个对象都有多个属性,需要在每次迭代时更新。
在Hannu实现了multiprocessing.pool并且它正在工作,但是它比连续运行花费更多的时间。
如果您能告诉我它发生的原因是什么以及如何让它运行得更快,我将不胜感激?
# IMPORT PACKAGES -----------------------------------------------------------+
import random
import numpy as np
# IMPORT FILES --------------------------------------------------------------+
from Reducer import initial
# Particle Class ------------------------------------------------------------+
class Particle:
def __init__(self,D,bounds_x,bounds_v):
self.Position_i = [] # particle position
self.Velocity_i = [] # particle velocity
self.Cost_i = -1 # cost individual
self.Position_Best_i = [] # best position individual
self.Cost_Best_i = -1 # best cost individual
self.Constraint_Best_i = [] # best cost individual contraints
self.Constraint_i = [] # constraints individual
self.Penalty_i = -1 # constraints individual
x0,v0 = initial(D,bounds_x,bounds_v)
for i in range(0,D):
self.Velocity_i.append(v0[i])
self.Position_i.append(x0[i])
# evaluate current fitness
def evaluate(self,costFunc,i):
self.Cost_i, self.Constraint_i,self.Penalty_i = costFunc(self.Position_i,i)
# check to see if the current position is an individual best
if self.Cost_i < self.Cost_Best_i or self.Cost_Best_i == -1:
self.Position_Best_i = self.Position_i
self.Cost_Best_i = self.Cost_i
self.Constraint_Best_i = self.Constraint_i
self.Penalty_Best_i = self.Penalty_i
return self
def proxy(gg, costf, i):
print(gg.evaluate(costf, i))
# Swarm Class ---------------------------------------------------------------+
class PSO():
def __init__(self,costFunc,bounds_x,bounds_v,ps,D,maxiter):
self.Cost_Best_g = -1 # Best Cost for Group
self.Position_Best_g = [] # Best Position for Group
self.Constraint_Best_g = []
self.Penalty_Best_g = -1
# Establish Swarm
Swarm = []
for i in range(0,ps):
Swarm.append(Particle(D,bounds_x,bounds_v))
# Begin optimization Loop
i = 1
self.Evol = []
while i <= maxiter:
pool = multiprocessing.Pool(processes = 4)
results = pool.map_async(partial(proxy, costf = costFunc, i=i), Swarm)
pool.close()
pool.join()
Swarm = results.get()
if Swarm[j].Cost_i< self.Cost_Best_g or self.Cost_Best_g == -1:
self.Position_Best_g = list(Swarm[j].Position_i)
self.Cost_Best_g = float(Swarm[j].Cost_i)
self.Constraint_Best_g = list(Swarm[j].Constraint_i)
self.Penalty_Best_g = float(Swarm[j].Penalty_i)
self.Evol.append(self.Cost_Best_g)
i += 1
答案 0 :(得分:1)
您需要一个代理函数来执行函数调用,并且当您需要为函数提供参数时,您还需要partial
。考虑一下:
from time import sleep
from multiprocessing import Pool
from functools import partial
class Foo:
def __init__(self, a):
self.a = a
self.b = None
def evaluate(self, CostFunction, i):
xyzzy = CostFunction(i)
sleep(0.01)
self.b = self.a*xyzzy
return self
def CostFunc(i):
return i*i
def proxy(gg, costf, i):
return gg.evaluate(costf, i)
def main():
Swarm = []
for i in range(0,10):
nc = Foo(i)
Swarm.append(nc)
p = Pool()
for i in range(100,102):
results = p.map_async(partial(proxy, costf=CostFunc, i=i), Swarm)
p.close()
p.join()
Swarm = []
for a in results.get():
Swarm.append(a)
for s in Swarm:
print (s.b)
main()
这将创建一个Swarm
对象列表,并且在每个对象中都有evaluate
这是您需要调用的函数。然后我们有参数(CostFunc和代码中的整数)。
现在我们将使用Pool.map_async
将您的Swarm列表映射到您的池中。这为每个工作人员提供了一个来自您的Swarm列表的Foo
实例,我们有一个proxy
函数实际调用evaluate()
。
但是,由于apply_async
只将一个对象从iterable发送到函数,而不是使用proxy
作为目标函数来汇集,我们使用partial
来创建目标函数传递“固定”参数。
当你显然想要修改对象时,这需要另一个技巧。如果在池进程中修改目标对象,它只会修改本地副本,并在处理完成后立即将其抛出。无论如何,子进程都无法修改主进程内存(反之亦然),这会导致分段错误。
相反,在修改对象后,我们返回self
。当您的池完成其工作后,我们会丢弃旧的Swarm
并从结果对象中重新组合它。