使用Benders分解法求解整数规划问题时遇CPLEX错误2002
问题:Benders分解报错
CPLEX Error 2002: Invalid Benders decomposition 尝试用Benders分解求解整数规划,将变量x₁、x₂归入主问题,y₁、y₂、y₃归入子问题,但运行代码时触发CPLEX Error 2002: Invalid Benders decomposition。原代码如下:
from docplex.mp.model import Model # Creating model my_bdrex=Model('My Benders Model',log_output=True) # Defining variables x_1=my_bdrex.integer_var(name='x_1', lb=0) x_2=my_bdrex.integer_var(name='x_2', lb=0) y_1=my_bdrex.integer_var(name='y_1', lb=0) y_2=my_bdrex.integer_var(name='y_2', lb=0) y_3=my_bdrex.integer_var(name='y_3', lb=0) # Adding constraints my_bdrex.add_constraint(2*x_1+4*x_2+4*y_1-2*y_2+3*y_3<=12) my_bdrex.add_constraint(3*x_1+5*x_2+2*y_1+3*y_2-y_3<=10) my_bdrex.add_constraint(x_1<=2) my_bdrex.add_constraint(x_2<=2) # Defining the objective function objective_bdrex=4*x_1+7*x_2+2*y_1-3*y_2+y_3 # Solving the Model my_bdrex.maximize(objective_bdrex) my_bdrex.parameters.benders.strategy = 1 x_1.benders_annotation=0 x_2.benders_annotation=0 y_1.benders_annotation=1 y_2.benders_annotation=1 y_3.benders_annotation=1 my_bdrex_MP.print_information() print(my_bdrex_MP.export_as_lp_string()) my_bdrex_MP.solve(clean_before_solve=True) my_bdrex_MP.print_solution()
错误原因分析
子问题变量类型不兼容:默认Benders分解要求子问题变量为连续型,原代码中
y₁、y₂、y₃被定义为整数变量,这会导致CPLEX无法生成有效的子问题对偶。若需整数子问题,需额外设置相关参数,但通常优先将子问题变量改为连续型验证分解逻辑。约束结构不符合Benders规则:Benders分解要求主问题约束仅包含主变量(
x₁、x₂),子问题约束可包含主变量(作为参数)和子变量(y系列)。原代码中前两个约束同时混合主、子变量,且未标注约束的Benders归属,CPLEX无法自动识别分解结构。未定义变量引用错误:代码中错误使用了未初始化的
my_bdrex_MP,实际应使用创建的模型实例my_bdrex。
修正后的代码
from docplex.mp.model import Model # 创建模型 my_bdrex = Model('My Benders Model', log_output=True) # 定义变量:主变量为整数,子变量改为连续型 x_1 = my_bdrex.integer_var(name='x_1', lb=0) x_2 = my_bdrex.integer_var(name='x_2', lb=0) y_1 = my_bdrex.continuous_var(name='y_1', lb=0) y_2 = my_bdrex.continuous_var(name='y_2', lb=0) y_3 = my_bdrex.continuous_var(name='y_3', lb=0) # 添加约束:分离主问题约束和子问题约束 # 主问题约束(仅含主变量) my_bdrex.add_constraint(x_1 <= 2, name='main_c1') my_bdrex.add_constraint(x_2 <= 2, name='main_c2') # 子问题约束(含主变量作为参数,子变量) sub_c1 = my_bdrex.add_constraint(4*y_1 - 2*y_2 + 3*y_3 <= 12 - 2*x_1 -4*x_2, name='sub_c1') sub_c2 = my_bdrex.add_constraint(2*y_1 + 3*y_2 - y_3 <= 10 -3*x_1 -5*x_2, name='sub_c2') # 标注约束的Benders归属:主约束归0,子约束归1 sub_c1.benders_annotation = 1 sub_c2.benders_annotation = 1 # 定义目标函数 objective_bdrex = 4*x_1 +7*x_2 +2*y_1 -3*y_2 + y_3 my_bdrex.maximize(objective_bdrex) # 设置Benders策略:1表示自动生成割平面 my_bdrex.parameters.benders.strategy = 1 # 标注变量的Benders归属:主变量0,子变量1 x_1.benders_annotation = 0 x_2.benders_annotation = 0 y_1.benders_annotation = 1 y_2.benders_annotation = 1 y_3.benders_annotation = 1 # 执行求解 my_bdrex.print_information() print(my_bdrex.export_as_lp_string()) solution = my_bdrex.solve(clean_before_solve=True) my_bdrex.print_solution()
内容的提问来源于stack exchange,提问作者Mohammad Samiullah
相关产品推荐
相关产品推荐

