在时间阈值后停止Scipydifferential_evolution()

问题描述 投票:0回答:1

我的问题已经部分回答here。我只需要将答案扩展到另一个Scipy函数即可。 (Windows 10上为Scipy 1.4.0,Python 3.7)

参考@ali_m给出的答案,我试图将相同的想法应用于也具有differential_evolution()参数的callback Scipy函数。

我想确保我的Scipy differential_evolution()函数在一定时间限制后停止运行。在这种情况下,我选择了具有40个输入参数和0.3秒阈值的Rosenbrock函数,以突出显示发生的情况。

import numpy as np
from scipy.optimize import differential_evolution, rosen
import time
import warnings

class TookTooLong(Warning):
    pass

class MinimizeStopper(object):
    def __init__(self, max_sec=0.3):
        self.max_sec = max_sec
        self.start = time.time()
    def __call__(self, xk=None, convergence=None):
        elapsed = time.time() - self.start
        if elapsed > self.max_sec:
            warnings.warn("Terminating optimization: time limit reached",
                          TookTooLong)
        else:
            print("Elapsed: %.3f sec" % elapsed)

n_var = 40 

upper_bound_array = np.ones(n_var) * 5
lower_bound_array = np.ones(n_var) * -5
bounds = Bounds(lower_bound_array, upper_bound_array)

# function call
res = differential_evolution(Rosen, bounds, strategy='best1bin',disp=False,
                                    callback=MinimizeStopper(), 
                                    maxiter=1000000) 

结果是我没有错误,但是似乎Scipy Optimize()中使用的相同逻辑在这里不起作用。更具体地说,当我运行程序时,即使在发出警告之后,该程序也会默默地继续计算所有必要的迭代,直到优化问题收敛为止。

有人知道为什么在这种情况下不能像在minimize()情况下那样工作吗?非常感谢您的帮助。

提前感谢

python time limit threshold differential-evolution
1个回答
0
投票

问题是callback必须返回TrueFalse,因为是否必须分别停止优化。

在您的情况下,MinimizeStopper不返回任何内容,它基本上只是发出警告。因此,您还必须对True / False返回值进行硬编码。

尝试这个

class MinimizeStopper(object):
    def __init__(self, max_sec=0.3):
        self.max_sec = max_sec
        self.start = time.time()

    def __call__(self, xk=None, convergence=None):
        elapsed = time.time() - self.start
        if elapsed > self.max_sec:
            print("Terminating optimization: time limit reached")
            return True
        else:
            # you might want to report other stuff here
            # print("Elapsed: %.3f sec" % elapsed)
            return False

应考虑以下几点:

  1. 除非将polish=False指定为differential_evolution()的输入,否则在停止扩展后仍将执行抛光操作:这会增加额外的时间
  2. callback在完成对每一代的评估之后触发:当迭代花费大量时间时,这可能会超过限制。
© www.soinside.com 2019 - 2024. All rights reserved.