Python:使用 scipy.optimize.differential_evolution 的多处理能力共享字典

时间:2021-07-23 05:56:43

标签: python scipy multiprocessing differential-evolution

我正在使用模块 scipy.optimize.differential_evolution 运行优化问题。我写的代码比较复杂,我尝试总结一下我遇到的困难:

  1. 目标函数是使用外部数值模型计算的(即我没有优化分析函数)。为此,我创建了一个运行模型的特定函数和另一个对结果进行后处理的函数。
  2. 我正在用一些约束来约束我的问题。约束不是约束问题的实际参数,而是约束一些只能在我的外部数值模型模拟结束时获得的因变量。每个约束都用一个单独的函数定义

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

0 个答案:

没有答案
相关问题