我的问题已经部分地得到了这里的回答。我只需要把答案扩展到另一个Scipy函数。(Windows1.4.0,Python3.7)
参照我给出的答案,我尝试将同样的想法应用于differential_evolution() Scipy函数,该函数也有callback参数。
我想确保我的differential_evolution()函数在一定的时间限制后停止运行。在本例中,我选择了Rosenbrock函数,输入参数为40个,阈值为0.3秒,以突出显示所发生的事情。
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) 因此,我没有错误,但似乎在这里使用的同样的minimize()逻辑不起作用。更确切地说,当我运行程序时,即使在引发警告之后,程序也会默默地继续计算所有必要的迭代,直到优化问题收敛为止。
有人知道为什么在这种情况下,它不像minimize()那样工作吗?我非常感谢你的帮助。
提前感谢
发布于 2020-03-26 09:13:20
问题是,callback必须返回True或False,这取决于是否必须停止优化(分别)。
在您的示例中,MinimizeStopper不返回任何内容,它基本上只会引发警告。因此,您也必须硬编码真假返回。
试试这个
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有几件事应该考虑:
polish=False作为differential_evolution()的输入,否则抛光操作在停止演化后仍会执行:这会增加额外的时间。callback是在完成每一代的评估之后触发的:当迭代需要大量时间时,这可能会超过极限。https://stackoverflow.com/questions/60854268
复制相似问题