在设定时间后停止Scipy最小化
我在Python 3.4中使用了Scipy模块里的minimize函数,具体代码如下:
resultats=minimize(margin_rate, iniprices, method='SLSQP',
jac=margin_rate_deriv, bounds=pricebounds, options={'disp': True,
'maxiter':2000}, callback=iter_report_margin_rate)
我可以设置最大迭代次数(就像上面那样),但是有没有办法让minimize在给定的时间后停止寻找解决方案呢?我查看了minimize的一般选项以及SLSQP求解器的具体选项,但还是没搞明白。
谢谢
2 个回答
12
你可以使用 callback
这个参数来设置一个警告或者错误,如果执行时间超过了某个限制的话:
import numpy as np
from scipy.optimize import minimize, rosen
import time
import warnings
class TookTooLong(Warning):
pass
class MinimizeStopper(object):
def __init__(self, max_sec=60):
self.max_sec = max_sec
self.start = time.time()
def __call__(self, xk=None):
elapsed = time.time() - self.start
if elapsed > self.max_sec:
warnings.warn("Terminating optimization: time limit reached",
TookTooLong)
else:
# you might want to report other stuff here
print("Elapsed: %.3f sec" % elapsed)
# example usage
x0 = [1.3, 0.7, 0.8, 1.9, 1.2]
res = minimize(rosen, x0, method='Nelder-Mead', callback=MinimizeStopper(1E-3))
6
不可以。你可以做的是在一个单独的进程中启动优化器,记录它运行了多长时间,如果需要的话就把它结束掉:
from multiprocessing import Process, Queue
import time
import random
from __future__ import print_function
def f(param, queue):
#do the minimization and add result to queue
#res = minimize(param)
#queue.put(res)
#to make this a working example I'll just sleep a
#a random amount of time
sleep_amount = random.randint(1, 10)
time.sleep(sleep_amount)
res = param*sleep_amount
queue.put(res)
q = Queue()
p = Process(target=f, args=(2.2, q))
max_time = 3
t0 = time.time()
p.start()
while time.time() - t0 < max_time:
p.join(timeout=1)
if not p.is_alive():
break
if p.is_alive():
#process didn't finish in time so we terminate it
p.terminate()
result = None
else:
result = q.get()
print(result)