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

10 投票
2 回答
7320 浏览
提问于 2025-04-18 13:50

我在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)

撰写回答