Stop Scipy minimize after set time

前端 未结 2 835
再見小時候
再見小時候 2020-12-03 15:46

I use minimize from the Scipy module on Python 3.4, specifically:

resultats=minimize(margin_rate, iniprices, method=\'SLSQP\',
jac=margin_rate_deriv, bounds=         


        
相关标签:
2条回答
  • 2020-12-03 16:11

    You can use the callback argument to raise a warning or exception if the execution time exceeds some threshold:

    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))
    
    0 讨论(0)
  • 2020-12-03 16:12

    No. What you can do is start the optimizer in a separate process, keep track of how long it has been running and terminate it if necessary:

    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)
    
    0 讨论(0)
提交回复
热议问题