【问题标题】:Capture timeout exception with Mosek + Cvxpy使用 Mosek + Cvxpy 捕获超时异常
【发布时间】:2021-09-08 13:35:21
【问题描述】:

我们正在使用 Cvxpy 和 Mosek 解决我们的大规模 MI 优化问题。

Mosek 消耗的运行时间通常比我们规定的两小时超时时间要长。

有没有办法系统地捕捉那些超时异常?

最小可重现示例:

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])
# try:
prob.solve(cp.MOSEK, mosek_params={mosek.dparam.optimizer_max_time: 0.01})   # set verbose=True (to see actual error in solver logs)
# except Timeout exception
#     print('Timeout occured')

print(prob.value)

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

execute_other_important_stuff()  # Not executed currently

【问题讨论】:

    标签: cvxpy mosek


    【解决方案1】:

    当 MOSEK 因超时而终止时,永远不会有任何异常 - 您设置了超时,因此在该点终止是正常情况,而不是异常情况。我不确定您指的是什么“错误”。

    如果你的意思是这样的

    Cannot unpack invalid solution: Solution(status=UNKNOWN
    

    那么它与超时本身无关,而是与没有可用的解决方案有关(但是,唯一可用的“解决方案”具有 UNKNOWN 状态),CVXPY 通过抛出异常来处理这个问题。所以问题是,在这 2 个小时之后,您的问题是否有任何解决方案?如果是,则应该毫无问题地退回。如果没有,您可能会看到上面的内容,我猜唯一的方法是抓住ValueError CVXPY 碰巧抛出。

    如果您使用的是本机 Mosek 接口,那么您可以找出为什么它会从各种响应代码中终止,但我 CVXPY 不会传播它们。

    【讨论】:

    • 嗨 Michal,我们指的是 cvxpy 在超时时抛出的错误:即 cvxpy.error.SolverError: Solver 'MOSEK' failed。尝试 ....(即当我们运行上述最小可重现示例时)。
    • 捕获像ValueErrorcvxpy.error.SolverError 这样的通用异常的唯一问题是它们是通用的,并没有告知终止的实际具体原因。
    • 如果瓶颈是 - Cvxpy 不支持捕获那些超时接口,那么我们也可以创建一个自定义的 Cvxpy 来做到这一点?
    • CVXPY 不传播原因。 CVXPY 甚至不知道您通过 Mosek 参数设置了一些时间限制。如果没有解决方案可以报告,那么从 CVXPY 的角度来看,SolverError 似乎是一个足够好的消息。如果有任何解决方案报告 CVXPY 应该这样做。日志说什么,MOSEK真的在时限内找不到解决办法吗?
    • 可能problem.solver_stats.solve_time 仍在设置中,您可以在异常处理程序中检查它。
    【解决方案2】:

    我不确定这是否是 Cvxpy 问题。

    但是,一般评论是 Mosek 无法连续检查时间限制,因此很可能会随着时间的推移而结束。

    例如,对于 SDP,它必须计算一个可能很大的矩阵的特征值,并且在完成之前无法检查时间限制。

    【讨论】:

    • 很抱歉给您带来了困惑。通过这句话:“Mosek 通常会消耗更高的运行时间” - 我们只是表示优化算法没有在规定的超时时间内完成(并且 Mosek 正确识别 - 达到 7200 的最大时间量)
    • 目的只是系统地捕获该异常(可能是 try-except 之类的),即不让程序因错误而终止。
    【解决方案3】:

    我对它发生的原因没有其他见解(除了ErlingMOSEK 建议的内容),但您可以使用signals 库来强制停止.solve 方法。

    这是一种独立的方式,可确保您在明智的情况下可以停止该功能。 请参阅Timeout a function call中的示例

    【讨论】:

    • 感谢@Roim!这将是一个完美的方法,只是:Total Function Time = Queue Wait Time + Actual optimization Time,我们只想应用超时其中的一个组件,即Actual optimization Time
    猜你喜欢
    • 1970-01-01
    • 2020-10-23
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 2010-09-06
    • 2011-11-02
    相关资源
    最近更新 更多