停止Scipy在设定时间后最小化

时间:2014-07-18 12:47:08

标签: python scipy

我在Python 3.4上使用Scipy模块中的最小化,特别是:

resultats=minimize(margin_rate, iniprices, method='SLSQP',
jac=margin_rate_deriv, bounds=pricebounds, options={'disp': True,
'maxiter':2000}, callback=iter_report_margin_rate)

可以设置最大迭代次数(如上所述),但有没有办法告诉最小化在给定的设定时间后停止搜索解决方案?我查看了最小化的一般选项以及SLSQP求解器的特定选项,但无法解决。

由于

2 个答案:

答案 0 :(得分:7)

如果执行时间超过某个阈值,您可以使用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))

答案 1 :(得分:3)

没有。你可以做的是在一个单独的过程中启动优化器,跟踪它运行的时间并在必要时终止它:

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)