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

如何通过Python调用CPLEX获取无界问题的极射线?

如何获取CPLEX无界问题的极射线?

问题背景

尝试用Python API运行一个CPLEX无界问题,示例代码如下:

import docplex.mp.model as cpx
from docplex.util.status import JobSolveStatus

my_bdrex_SP=cpx.Model('My Benders Model Sub Problem')

# 添加变量
v_1=my_bdrex_SP.continuous_var(name='v_1', lb=0)
v_2=my_bdrex_SP.continuous_var(name='v_2', lb=0)

# 定义目标函数
objective_SP=0*v_1-6*v_2

# 添加约束
my_bdrex_SP.add_constraint(4*v_1+2*v_2>=2)
my_bdrex_SP.add_constraint(-2*v_1+3*v_2>=-3)
my_bdrex_SP.add_constraint(3*v_1-1*v_2>=1)

# 求解问题
my_bdrex_SP.minimize(objective_SP)
my_bdrex_SP.solve()

my_bdrex_SP.print_solution()
print(my_bdrex_SP.get_solve_status())

该问题实际为无界问题,但CPLEX返回状态为unbounded or infeasible。为获取可行性割平面需要提取极射线,使用以下代码时出现错误:

ray = my_bdrex_SP.get_engine().get_cplex().solution.advanced.get_ray()

错误信息:

cplex.exceptions.errors.CplexSolverError: CPLEX Error 1217: No solution exists.

解决方案

要正确获取无界问题的极射线,需遵循以下步骤:

1. 提前设置CPLEX参数启用射线计算

在求解前,设置CPLEX的advance参数为1,确保求解器在检测到无界时自动计算并存储极射线:

my_bdrex_SP.parameters.advance.set(1)

2. 检查求解状态,明确问题类型

求解后先判断状态,避免在不可行问题上尝试获取射线(不可行问题不存在极射线):

status = my_bdrex_SP.get_solve_status()
if status == JobSolveStatus.UNBOUNDED:
    cplex_instance = my_bdrex_SP.get_engine().get_cplex()
    ray = cplex_instance.solution.advanced.get_ray()
    print("极射线:", ray)
elif status == JobSolveStatus.INFEASIBLE:
    print("问题不可行,无射线可获取")
else:
    print("问题有可行解,无需射线")

3. 完整修改后的代码

整合上述步骤的完整代码如下:

import docplex.mp.model as cpx
from docplex.util.status import JobSolveStatus

my_bdrex_SP=cpx.Model('My Benders Model Sub Problem')

# 添加变量
v_1=my_bdrex_SP.continuous_var(name='v_1', lb=0)
v_2=my_bdrex_SP.continuous_var(name='v_2', lb=0)

# 定义目标函数
objective_SP=0*v_1-6*v_2

# 添加约束
my_bdrex_SP.add_constraint(4*v_1+2*v_2>=2)
my_bdrex_SP.add_constraint(-2*v_1+3*v_2>=-3)
my_bdrex_SP.add_constraint(3*v_1-1*v_2>=1)

# 设置参数启用射线计算
my_bdrex_SP.parameters.advance.set(1)

# 求解问题
my_bdrex_SP.minimize(objective_SP)
my_bdrex_SP.solve()

# 检查状态并处理
status = my_bdrex_SP.get_solve_status()
print("求解状态:", status)

if status == JobSolveStatus.UNBOUNDED:
    cplex_instance = my_bdrex_SP.get_engine().get_cplex()
    ray = cplex_instance.solution.advanced.get_ray()
    print("极射线结果:", ray)
else:
    my_bdrex_SP.print_solution()

说明

  • advance参数设为1是关键,它让CPLEX在检测到无界问题时主动计算极射线,否则get_ray()会因无存储的射线而报错。
  • 必须先明确求解状态,原返回的unbounded or infeasible是模糊状态,需区分无界和不可行两种情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:30:31