【问题标题】:Stop Scipy differential_evolution() after a time threshold在时间阈值后停止 Scipy different_evolution()
【发布时间】:2020-03-26 18:35:35
【问题描述】:

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

参考@ali_m 给出的答案,我尝试将相同的想法应用于同样具有callback 参数的differential_evolution() 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 minimize() 中使用的相同逻辑在这里不起作用。更具体地说,当我运行程序时,即使在引发了警告之后,程序也会默默地继续计算所有必要的迭代,直到优化问题收敛。

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

提前致谢

【问题讨论】:

    标签: python time limit threshold differential-evolution


    【解决方案1】:

    问题是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:当迭代需要大量时间时,这可能会超过限制。

    【讨论】:

      猜你喜欢
      • 2014-09-09
      • 2020-08-31
      • 1970-01-01
      • 2022-10-18
      • 1970-01-01
      • 2018-10-27
      • 1970-01-01
      • 2022-10-21
      • 2020-07-11
      相关资源
      最近更新 更多