使用 Mosek + Cvxpy 捕获超时异常
Capture timeout exception with Mosek + Cvxpy
我们正在使用 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 无法连续检查时间限制,因此它很可能会随着时间的推移而过去。
例如,对于 SDP,它必须计算一个可能很大的矩阵的特征值,并且在完成之前无法检查时间限制。
我没有其他见解(除了 ErlingMOSEK suggested) on why it happened, but you can use signals 库强制 .solve
方法停止。
这是一种独立的方法,可确保您可以在任何时候明智地停止该功能。
请参阅 Timeout a function call
中的示例
当 MOSEK 由于超时而终止时,永远不会有任何异常 - 您设置了超时,因此在该点终止是正常情况,而不是异常情况。我不确定您指的是什么“错误”。
如果你的意思是
Cannot unpack invalid solution: Solution(status=UNKNOWN
那么它与超时本身无关,而是与没有可用解决方案的事实有关(但是,唯一可用的“解决方案”具有 UNKNOWN 状态),CVXPY 通过抛出异常来处理此问题。所以问题是,在这 2 个小时之后,是否找到了解决问题的方法?如果是,则应该毫无问题地退回。如果没有,您可能会看到上面的内容,我猜唯一的方法是捕捉 ValueError
CVXPY 恰好抛出。
如果您使用的是本机 Mosek 界面,那么您可以找出它因各种响应代码而终止的原因,但我 CVXPY 不会传播它们。
我们正在使用 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 无法连续检查时间限制,因此它很可能会随着时间的推移而过去。
例如,对于 SDP,它必须计算一个可能很大的矩阵的特征值,并且在完成之前无法检查时间限制。
我没有其他见解(除了 ErlingMOSEK suggested) on why it happened, but you can use signals 库强制 .solve
方法停止。
这是一种独立的方法,可确保您可以在任何时候明智地停止该功能。 请参阅 Timeout a function call
中的示例当 MOSEK 由于超时而终止时,永远不会有任何异常 - 您设置了超时,因此在该点终止是正常情况,而不是异常情况。我不确定您指的是什么“错误”。
如果你的意思是
Cannot unpack invalid solution: Solution(status=UNKNOWN
那么它与超时本身无关,而是与没有可用解决方案的事实有关(但是,唯一可用的“解决方案”具有 UNKNOWN 状态),CVXPY 通过抛出异常来处理此问题。所以问题是,在这 2 个小时之后,是否找到了解决问题的方法?如果是,则应该毫无问题地退回。如果没有,您可能会看到上面的内容,我猜唯一的方法是捕捉 ValueError
CVXPY 恰好抛出。
如果您使用的是本机 Mosek 界面,那么您可以找出它因各种响应代码而终止的原因,但我 CVXPY 不会传播它们。