4

我正在使用模块运行优化问题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)。我的问题是,当我启用多处理功能时,我不知道如何更新全局/共享变量。

上面的网页指出: “如果工人是一个整体,则人口被细分为工人部分并并行评估(使用multiprocessing.Pool)[...]”

所以我推断我必须找到一种在使用时修改共享变量multiprocessing.pool的方法。在这方面,我找到了以下解决方案:

python多处理中的共享变量

具有全局变量的 multiprocessing.Pool

为什么 multiprocessing.Pool 不能更改全局变量?

Python 在并行进程之间共享字典

我认为最后一个适合我的情况。但是,我不确定如何设置我的代码和该differential_evolution函数的 workers 选项。任何帮助将不胜感激。

我的代码是这样的:

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 的解决方案

4

0 回答 0