Python线性优化问题未遵循约束条件的排查求助
问题原因与解决办法
你的问题核心是约束条件的系数量级差异过大,导致interior-point求解器出现数值稳定性问题,无法正确满足大系数约束。
第二条约束的系数是1e7、1e8量级,而其他约束的系数大多在1e-1到1e2之间,量级差了6-7个数量级。求解器在计算时会因为数值精度丢失,忽略这条约束的限制,最终输出不满足条件的结果。
解决办法
方法1:缩放约束条件,统一量级
把第二条约束的左右两边同时除以1e7,将系数缩小到和其他约束相近的量级,从根源上消除数值差异问题:
- 原约束:
1.26013470e+07*x1 + 2.37672878e+08*x2 ≤ 50000000 - 缩放后:
1.26013470*x1 + 23.7672878*x2 ≤ 5
修改后的代码:
from scipy.optimize import linprog x1_bounds = (None, None) c_2 = [1, 1] # 缩放第二条约束的系数和右侧值 a_2_scaled = [ [4.87892727e+01, 2.97284721e+02], [1.26013470, 23.7672878], # 除以1e7 [-2.48999371e-01, -1.77252972e+00], [-3.16435265e-01, -5.22468352e+00], [-9.00000000e-01, 1.00000000e-01], [1.00000000e-01, -9.00000000e-01], [2.00000000e-01, -8.00000000e-01], [-8.00000000e-01, 2.00000000e-01], [-1.00000000e+00, 0.00000000e+00], [0.00000000e+00, -1.00000000e+00], [1.00000000e+00, 0.00000000e+00], [0.00000000e+00, 1.00000000e+00] ] b_2_scaled = [2000, 5, -1, -1.91, 0, 0, 0, 0, -0.25, -0.06, 3.0, 0.3] # 50000000/1e7=5 # 使用稳定性更好的highs方法 res = linprog(c_2, A_ub=a_2_scaled, b_ub=b_2_scaled, bounds=[x1_bounds, x1_bounds], method="highs") print(res.x) # 验证约束是否满足 print(1.26013470*res.x[0] +23.7672878*res.x[1])
方法2:直接更换求解器为highs
Scipy的highs方法基于HiGHS求解器,在处理数值差异大的线性规划问题时,稳定性远优于interior-point,直接更换方法即可解决问题:
from scipy.optimize import linprog x1_bounds = (None, None) c_2 = [1, 1] a_2 = [[ 4.87892727e+01, 2.97284721e+02], [ 1.26013470e+07, 2.37672878e+08], [-2.48999371e-01, -1.77252972e+00], [-3.16435265e-01, -5.22468352e+00], [-9.00000000e-01, 1.00000000e-01], [ 1.00000000e-01, -9.00000000e-01], [ 2.00000000e-01, -8.00000000e-01], [-8.00000000e-01, 2.00000000e-01], [-1.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, -1.00000000e+00], [ 1.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, 1.00000000e+00]] b_2 = [2000, 50000000, -1, -1.91, 0, 0, 0, 0, -0.25, -0.06, 3.0, 0.3] # 更换为highs方法 res = linprog(c_2, A_ub=a_2, b_ub=b_2, bounds=[x1_bounds, x1_bounds], method="highs") print(res.x) # 验证约束是否满足 print(1.26013470e+07*res.x[0] +2.37672878e+08*res.x[1])
内容的提问来源于stack exchange,提问作者Javier Andres Marino Villalba
相关产品推荐
相关产品推荐

