Python 在类中使用多处理模块
我有以下程序,我想使用多处理模块。它使用外部文件,在其中我从另一个文件调用PSO类Python 在类中使用多处理模块,python,python-multiprocessing,Python,Python Multiprocessing,我有以下程序,我想使用多处理模块。它使用外部文件,在其中我从另一个文件调用PSO类costfunc是另一个文件中的函数,其他参数只是变量 Swarm是一个包含与ps值一样多的对象的列表,每个对象都有多个属性,需要在每次迭代时更新 之后,Hannu实现了multiprocessing.pool,它正在工作,但比按顺序运行要花更多的时间 如果您能告诉我发生这种情况的原因,以及如何让它运行得更快,我将不胜感激 # IMPORT PACKAGES ----------------------------
costfunc
是另一个文件中的函数,其他参数只是变量
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
#导入软件包-----------------------------------------------------------+
随机输入
将numpy作为np导入
#导入文件--------------------------------------------------------------+
从减速器导入初始值
#粒子类------------------------------------------------------------+
类粒子:
定义初始值(self,D,bounds,x,bounds):
self.Position_i=[]粒子位置
self.Velocity_i=[]#粒子速度
self.Cost_i=-1#个人成本
self.Position_Best_i=[]最佳职位个人
self.Cost_Best_i=-1#最佳成本个人
自我约束_最佳_i=[]#最佳成本个别约束
self.Constraint_i=[]个体约束
self.poulding_i=-1#个体约束
x0,v0=初始值(D,界限x,界限v)
对于范围(0,D)内的i:
自速度i.append(v0[i])
self.Position_i.append(x0[i])
#评估当前健康状况
def评估(自我、costFunc、i):
self.Cost\u i,self.Constraint\u i,self.population\u i=costFunc(self.Position\u i,i)
#检查当前位置是否为个人最佳位置
如果self.Cost\u i 虽然i您需要一个代理函数来执行函数调用,并且由于您需要向函数传递参数,您还需要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\u async
将您的Swarm列表映射到您的池。这给每个工作人员一个Swarm列表中的Foo
实例,我们有一个proxy
函数,它实际调用evaluate()
但是,由于apply\u async
仅将对象从iterable发送到函数,因此我们使用partial
创建目标函数以传递“固定”参数,而不是将proxy
用作池的目标函数
当你显然想找回修改过的对象时,这需要另一个技巧。如果在池进程中修改目标对象,它只会修改本地副本,并在处理完成后将其丢弃。子进程无论如何都无法修改主进程内存(反之亦然),这将导致分段错误
相反,在修改对象后,我们返回self
。当您的池完成其工作后,我们将丢弃旧的Swarm
,并从结果对象重新组装它 谢谢你的帮助!我想我明白了,但是在你的例子中,CostFunc不是内部求值,所以什么都不做。我怎样才能把它包括进去?它当然可以在任何地方。我编辑了我的答案,并将对CostFunction的调用移动到evaluate方法中。同样的原则也适用。代理调用求值,其余的只是正确设置函数参数。它正在工作,但在池之后,对象的属性现在应该是空的。确定。那是一个完全不同的问题。基本上不能通过多处理来解决,因为您的子流程只修改传递给子流程的对象的本地副本。无法从子进程修改主进程内存中的对象,因为这将导致分段错误。让我想想是否有一个简单的解决方法。编辑上面的代码,这样它可能会帮助你。非常感谢你的帮助。