You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Cvxpy结合Mosek求解优化问题时如何捕获超时异常

解决方案

方案1:捕获Mosek超时异常+判断求解状态(推荐优先使用)

Mosek触发你设置的optimizer_max_time阈值后,会主动终止求解过程,此时要么抛出cvxpy.SolverError异常,要么返回的问题状态为cvxpy.TIME_LIMIT,你只需要通过try-except块捕获异常,同时判断求解后的状态即可识别超时场景,也能保证后续代码正常执行。

修改后的可运行代码如下:

import cvxpy as cp
import numpy as np
import mosek

m = 15
n = 10
np.random.seed(1)
s0 = np.random.randn(m)
lamb0 = np.maximum(-s0, 0)
s0 = np.maximum(s0, 0)
x0 = np.random.randn(n)
A = np.random.randn(m, n)
b = A @ x0 + s0
c = -A.T @ lamb0

# Define and solve the CVXPY problem.
x = cp.Variable(n)
prob = cp.Problem(cp.Minimize(c.T@x),
                 [A @ x <= b])
timeout_flag = False
try:
    # 注意:optimizer_max_time单位为秒,2小时对应设置为7200
    prob.solve(cp.MOSEK, mosek_params={mosek.dparam.optimizer_max_time: 0.01})
except cp.SolverError as e:
    if "time limit" in str(e).lower():
        timeout_flag = True
        print('Timeout occured')
    else:
        # 其他求解错误逻辑可自行补充
        raise e

# 额外判断求解状态是否为超时
if prob.status == cp.TIME_LIMIT:
    timeout_flag = True
    print('Timeout occured from status check')

print(prob.value)

def execute_other_important_stuff():
    print("Hello world")

execute_other_important_stuff()  # 现在可以正常执行

注意:optimizer_max_time参数的单位为秒,2小时的超时阈值需要设置为7200,请不要填错单位。

方案2:进程级超时兜底(应对极端卡死场景)

如果遇到Mosek本身异常卡死、没有触发自带超时逻辑的极端情况,可以用多进程封装求解逻辑,在进程层设置超时时间,到点直接终止求解进程,完全避免主程序被卡住:

import cvxpy as cp
import numpy as np
import mosek
from multiprocessing import Process, Queue

def solve_process(queue):
    m = 15
    n = 10
    np.random.seed(1)
    s0 = np.random.randn(m)
    lamb0 = np.maximum(-s0, 0)
    s0 = np.maximum(s0, 0)
    x0 = np.random.randn(n)
    A = np.random.randn(m, n)
    b = A @ x0 + s0
    c = -A.T @ lamb0

    x = cp.Variable(n)
    prob = cp.Problem(cp.Minimize(c.T@x), [A @ x <= b])
    try:
        prob.solve(cp.MOSEK, mosek_params={mosek.dparam.optimizer_max_time: 0.01})
        queue.put((prob.status, prob.value))
    except Exception as e:
        queue.put(("error", str(e)))

if __name__ == "__main__":
    q = Queue()
    p = Process(target=solve_process, args=(q,))
    p.start()
    # 进程层超时设置,单位为秒,2小时设为7200,可略大于Mosek自带超时做兜底
    p.join(timeout=1)
    
    if p.is_alive():
        p.terminate()
        p.join()
        print("Timeout occured from process level")
        timeout_flag = True
    else:
        res = q.get()
        print(f"Solve finished, status: {res[0]}, value: {res[1]}")
    
    def execute_other_important_stuff():
        print("Hello world")
    execute_other_important_stuff()

内容的提问来源于stack exchange,提问作者pqrz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:06:03