scipy.optimize.milp未遵守time_limit参数,超时后长时间无法返回的问题求助
大家好,我最近在用scipy的milp函数求解混合整数线性规划问题,遇到了一个特别头疼的问题:明明已经设置了time_limit参数(比如我设的是540秒),而且求解报告已经打印出来了(不管是找到最优解还是触发时间限制),但函数就是不立刻返回,要等很久(甚至1500秒)才会继续执行后面的代码,比如我在函数调用后写的打印耗时的语句。哪怕是处理小数据集,虽然返回速度会快一些,但还是会出现这种“求解报告出来后挂起”的情况。
先贴一下我看到的求解报告内容:
Status Optimal
Primal bound -39
Dual bound -39
Gap 0% (tolerance: 0.01%)
P-D integral 0
Solution status feasible
-39 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing
12.29 (total)
0.00 (presolve)
0.00 (solve)
0.00 (postsolve)
Max sub-MIP depth 12
Nodes 1
Repair LPs 0 (0 feasible; 0 iterations)
LP iterations 29704 (total)
0 (strong br.)
2544 (separation)
18467 (heuristics)
我已经尝试过简化输入数据来降低求解难度,确实小数据集的返回速度会快一些,但哪怕是小数据集,还是会出现求解完成后挂起的情况。我当前使用的scipy版本是1.15.2。
下面是我初始化和调用MILP的核心代码:
def solve_and_extract(df_chunk, time_limit): n = len(df_chunk) if n < 10: return [], df_chunk.copy(), False m = n // 10 caps = df_chunk['Col1'].astype(float).to_numpy() fr = df_chunk['Col2'].astype(float).to_numpy() c = np.concatenate([np.zeros(n*m), -np.ones(m), np.zeros(n)]) integrality = np.ones(n*m + m + n, dtype=int) bounds = Bounds(0, 1) A_link1 = np.zeros((n, n*m + m + n)); b_link1 = np.zeros(n) A_link2 = np.zeros((n, n*m + m + n)); b_link2 = np.zeros(n) for i in range(n): A_link1[i, i + np.arange(m)*n] = 1 A_link1[i, n*m + m + i] = -1 A_link2[i, i + np.arange(m)*n] = -1 A_link2[i, n*m + m + i] = 1 A2a = np.zeros((m, n*m + m + n)); b2a = np.zeros(m) A2b = np.zeros((m, n*m + m + n)); b2b = np.zeros(m) for j in range(m): A2a[j, j*n:(j+1)*n] = 1 A2a[j, n*m + j] = -10 A2b[j, j*n:(j+1)*n] = -1 A2b[j, n*m + j] = 10 A3 = np.zeros((m, n*m + m + n)); b3 = np.zeros(m) A4 = np.zeros((m, n*m + m + n)); b4 = np.zeros(m) A5 = np.zeros((m, n*m + m + n)); b5 = np.zeros(m) A6 = np.zeros((m, n*m + m + n)); b6 = np.zeros(m) for j in range(m): A3[j, j*n:(j+1)*n] = caps A3[j, n*m + j] = -maxc*10 A4[j, j*n:(j+1)*n] = -caps A4[j, n*m + j] = minc*10 A5[j, j*n:(j+1)*n] = fr A5[j, n*m + j] = -max_fr*10 A6[j, j*n:(j+1)*n] = -fr A6[j, n*m + j] = min_fr*10 A_sym = np.zeros((m-1, n*m + m + n)); b_sym = np.zeros(m-1) for j in range(m-1): A_sym[j, n*m + j] = 1 A_sym[j, n*m + j+1] = -1 A7 = np.zeros((1, n*m + m + n)) A7[0, n*m + m:] = +1 A7[0, n*m:n*m+m] = -10 constraints = [ LinearConstraint(A2a, -np.inf, b2a), LinearConstraint(A2b, -np.inf, b2b), LinearConstraint(A3, -np.inf, b3), LinearConstraint(A4, -np.inf, b4), LinearConstraint(A5, -np.inf, b5), LinearConstraint(A6, -np.inf, b6), LinearConstraint(A7, -np.inf, 0), LinearConstraint(A_link1, -np.inf, b_link1), LinearConstraint(A_link2, -np.inf, b_link2), LinearConstraint(A_sym, b_sym, np.inf) ] res = milp( c=c, integrality=integrality, bounds=bounds, constraints=constraints, options={"disp": True, "time_limit": time_limit} ) # 后续处理逻辑...
请问各位,有没有办法优化这种情况?为什么milp函数在求解报告输出后还会挂起这么久?是我的代码结构有问题,还是scipy的MILP求解器本身存在潜在问题?有没有可以调整的参数或者技巧,能让函数在求解完成后立刻返回?
内容来源于stack exchange

