I want to pass a shared variable in python scipy "differential_evolution" to keep track of experiment number. I can do this with worker=1 , but i am unable to keep track of experiment number with worker > 2. Here is my code:
from scipy.optimize import differential_evolution
def objectiveFunction(x,experiment_no ):
y=x[0]+x[1]
# Keep track of experiment number
experiment_no["exp"]=experiment_no["exp"]+1
print("This is expriment no :"+ str(experiment_no["exp"]))
return y
if __name__ == "__main__":
minRanges=[1.2,10]
maxRanges=[1.5,20]
experiment_no={}
experiment_no["exp"]=0
try:
bounds = list(zip(minRanges,maxRanges))
result = differential_evolution(objectiveFunction,bounds, args=(experiment_no,),strategy="best1bin", workers=1, maxiter=int("2"), updating="deferred", polish=False)
print('Global minimum [x]:')
print(result.x)
print('Function value at global minimum [f(x)]:')
print(result.fun)
except :
exit( sys.exc_info()[:2])
with workers=1 my output is :
This is expriment no :1
This is expriment no :2
This is expriment no :3
This is expriment no :4
This is expriment no :5
This is expriment no :6
....
but with workers=2 or 3 , my output is :
This is expriment no :1
This is expriment no :1
This is expriment no :11
This is expriment no :1
This is expriment no :1
This is expriment no :1
How can i achieve my below output with workers=2 ?
This is expriment no :1
This is expriment no :2
This is expriment no :3
This is expriment no :4
This is expriment no :5
This is expriment no :6
I'm not sure if it is the best way, but it is working through a thread-safe counter:
from scipy.optimize import differential_evolution
from multiprocessing import Process, RawValue, Lock
class Counter(object):
def __init__(self, value=0):
# RawValue because we don't need it to create a Lock:
self.val = RawValue('i', value)
self.lock = Lock()
def increment(self):
with self.lock:
self.val.value += 1
return self.val.value
class ExpermientInfo:
no = Counter()
def increment():
return ExpermientInfo.no.increment()
def objectiveFunction(x):
y = x[0]+x[1]
# Keep track of experiment number
no = ExpermientInfo.increment()
print("This is expriment no :" + str(no))
return y
if __name__ == "__main__":
minRanges = [1.2, 10]
maxRanges = [1.5, 20]
try:
bounds = list(zip(minRanges, maxRanges))
counter = 0
result = differential_evolution(objectiveFunction, bounds, args=(
), strategy="best1bin", workers=2, maxiter=int("2"), updating="deferred", polish=False)
print('Global minimum [x]:')
print(result.x)
print('Function value at global minimum [f(x)]:')
print(result.fun)
except:
exit(sys.exc_info()[:2])