Python 如何在docplex中异步中止解算?

Python 如何在docplex中异步中止解算?,python,docplex,Python,Docplex,我有两个使用docplex同时运行的解算,我想在另一个解算完成后立即停止其中一个解算。有办法结束一个解算吗?您可以使用get\u cplex()函数返回的低级引擎对象来完成此操作。这是的类的一个实例。您可以使用函数将安装到该实例中 如果对所有Cplex实例使用相同的中止程序,则最终可以调用中止程序abort()函数来停止所有解算 请注意,中止请求并不总是立即处理。CPLEX引擎确认中止之前可能会有一点延迟。谢谢,我可以使用以下代码添加该功能: from docplex.mp.progress i

我有两个使用docplex同时运行的解算,我想在另一个解算完成后立即停止其中一个解算。有办法结束一个解算吗?

您可以使用
get\u cplex()
函数返回的低级引擎对象来完成此操作。这是的类的一个实例。您可以使用函数将安装到该实例中

如果对所有
Cplex
实例使用相同的中止程序,则最终可以调用中止程序
abort()
函数来停止所有解算


请注意,中止请求并不总是立即处理。CPLEX引擎确认中止之前可能会有一点延迟。

谢谢,我可以使用以下代码添加该功能:

from docplex.mp.progress import ProgressListener, ProgressClock
class AutomaticAborter(ProgressListener):
    """ a simple implementation of an automatic search stopper.
    """
    def __init__(self):
        super(AutomaticAborter, self).__init__(ProgressClock.All)
        self.last_obj = None
        self.last_obj_time = None
        self.con = 0
        
    def notify_start(self):
        super(AutomaticAborter, self).notify_start()
        self.last_obj = None
        self.last_obj_time = None    
        self.con = 0
    def is_improving(self, new_obj, eps=1e-4):
        last_obj = self.last_obj
        return last_obj is None or (abs(new_obj- last_obj) >= eps)
            
    def notify_progress(self, pdata):
        super(AutomaticAborter, self).notify_progress(pdata)
        global con_f
        if pdata.has_incumbent and self.is_improving(pdata.current_objective):
            self.last_obj = pdata.current_objective
            self.last_obj_time = pdata.time
            print('----> #new objective={0}, time={1}s'.format(self.last_obj, self.last_obj_time))
        else:
            # a non improving move
            last_obj_time = self.last_obj_time
            this_time = pdata.time
            if last_obj_time is not None:
                self.con=con_f
                if con_f>0:
                    print('!! aborting cplex, con_f >{}'.format(self.con))
                    self.abort()
                else:
                    print('----> running {}'.format(con_f))
con_f=0

solver.add_progress_listener(AutomaticAborter())
solver1.add_progress_listener(AutomaticAborter())

def work(worker_queue, id, stop_event):
    while not stop_event.is_set():

        if id==1:
            work.msol=solver.solve(clean_before_solve=True,log_output=True)
        else:
            work.msol1=solver1.solve(clean_before_solve=True,log_output=True)
        # put worker ID in queue
        if not stop_event.is_set():
            worker_queue.put(id)
        break
# queue for workers
worker_queue = Queue()

# indicator for other threads to stop
stop_event = threading.Event()

# run workers
threads = []
threads.append(Thread(target=work, args=(worker_queue, 1, stop_event)))
threads.append(Thread(target=work, args=(worker_queue, 2, stop_event)))

for thread in threads:
    thread.start()
# this will block until the first element is in the queue
first_finished = worker_queue.get()

print(first_finished, 'was first!')

con_f=1


# signal the rest to stop working
stop_event.set()```

谢谢你,但是你有这样的例子吗。我尝试在线程完成后立即将solver.get_cplex(cplex.cplex().use_aborter(cplex.aborter().abort())添加到线程中,但它似乎不起作用您必须在开始求解之前安装aborter,并保留对该aborter的引用。然后,当您想要中止求解时,调用该中止程序的
abort()
方法。您可以查看cplex附带的
mipex4.py
示例(当然,您应该在本示例之后调用
abort()
)。