我正在使用模块 scipy.optimize.differential_evolution
运行优化问题。我写的代码比较复杂,我尝试总结一下我遇到的困难:
2. 的问题是外部模型可能对同一组参数运行两次:第一次计算目标函数,第二次计算要评估约束的因变量。为了避免这种情况并加速我的代码,我创建了一个全局字典,每次调用外部模型时,我都会保存每组参数的因变量结果(作为查找表)。这将阻止评估约束的函数为同一组参数再次运行模型。
当我使用单个 CPU 优化时,这非常有效。但是,据我所知,函数 differential_evolution
还允许通过为选项“workers”设置适当的值来进行多处理(请参阅此处的 https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.differential_evolution.html#r108fc14fa019-1)。我的问题是,当我启用多处理功能时,我不知道如何更新全局/共享变量。
上面的网页指出:
“如果 workers 是 int,则总体将细分为 workers 部分并并行评估(使用 multiprocessing.Pool
)[...]”
所以我推断我必须找到一种在使用 multiprocessing.pool
时修改共享变量的方法。在这方面,我找到了以下解决方案:
Shared variable in python's multiprocessing
multiprocessing.Pool with a global variable
Why multiprocessing.Pool cannot change global variable?
Python sharing a dictionary between parallel processes
我认为最后一个适合我的情况。但是,我不确定如何设置我的代码和 differential_evolution
函数的工作人员选项。
任何帮助将不胜感激。
我的代码类似于:
def run_external_model(q):
global dict_obj, dict_dep_var
....
obj, dep_var = post_process_model(q)
dict_var_dep[str(q)] = dep_var
dict_obj[str(q)] = obj
def obj(q):
global dict_obj
if str(q) not in list(dict_obj.keys()):
run_external_model(q)
return dict_obj[str(q)]
def constraint(q):
global dict_dep_var
if str(q) not in list(dict_dep_var.keys()):
run_external_model(q)
return dict_dep_var[str(q)]
dict_obj = {}
dict_dep_var = {}
nlcs = scipy.optimize.NonLinearConstraint(constraint, 0., np.inf)
q0 = np.array([q1, .... , qn])
b = np.array([(0, 100.)] * len(q0))
solution = scipy.optimize.differential_evolution(objective, bounds=(b), constraints=(nlcs), seed=1)
以上代码适用于单核。我正在尝试一种解决方案来共享字典 dict_obj 和 dict_dep_var