GEKKO资源优化代码添加任务约束后求解失败问题求助
GEKKO整数规划求解失败问题分析与调试方案
问题原因分析
你添加的任务约束存在逻辑矛盾:
- 工人约束要求2名工人各完成1项任务,总共仅能完成2项任务;
- 但新增的3个等式约束
x1j + x2j == 1要求所有3项任务必须被分配,这在只有2名工人的场景下完全不可能满足,导致模型无可行解,因此求解器返回“Solution Not Found”。
修正后的可行代码
将任务约束从“必须分配”改为“最多分配1次”(符合2工人3任务的实际场景),如果需要恰好分配2项任务(匹配工人数量),可额外添加总任务数约束:
m = GEKKO() # 决策变量 x11 = m.Var(value=0, lb=0,ub=1,integer=True) # 工人1选任务1 x12 = m.Var(value=0, lb=0,ub=1,integer=True) # 工人1选任务2 x13 = m.Var(value=0, lb=0,ub=1,integer=True) # 工人1选任务3 x21 = m.Var(value=0, lb=0,ub=1,integer=True) # 工人2选任务1 x22 = m.Var(value=0, lb=0,ub=1,integer=True) # 工人2选任务2 x23 = m.Var(value=0, lb=0,ub=1,integer=True) # 工人2选任务3 # 奖励常数 S11 = m.Const(value=2) S12 = m.Const(value=5) S13 = m.Const(value=8) S21 = m.Const(value=1) S22 = m.Const(value=5) S23 = m.Const(value=7) # 约束条件 # 工人约束:每人仅选1项任务 m.Equation(x11 + x12 + x13 == 1) m.Equation(x21 + x22 + x23 == 1) # 任务约束:每项任务最多分配给1名工人 m.Equation(x11 + x21 <= 1) m.Equation(x12 + x22 <= 1) m.Equation(x13 + x23 <= 1) # 可选:若要求恰好分配2项任务(匹配工人数量),添加此约束 # m.Equation((x11+x21)+(x12+x22)+(x13+x23) == 2) # 目标函数:最大化总奖励(GEKKO默认最小化,因此取负值) m.Obj(-(x11*S11 + x12*S12 + x13*S13 + x21*S21 + x22*S22 + x23*S23)) m.options.IMODE = 3 m.options.SOLVER = 1 m.solve(disp=True) print('Results') print('x11:', x11.value[0]) print('x12:', x12.value[0]) print('x13:', x13.value[0]) print('x21:', x21.value[0]) print('x22:', x22.value[0]) print('x23:', x23.value[0]) print('总奖励:', -m.options.objfcnval)
GEKKO整数规划求解错误调试方法
- 约束逻辑校验:将数学约束翻译为自然语言,检查是否符合实际业务场景,比如本例中“3项任务必须全部分配给2名工人”显然违反常识。
- 查看不可行性报告:求解器生成的
infeasibilities.txt文件会列出未满足的约束,可通过apm_get(server, app, 'infeasibilities.txt')命令获取,定位矛盾约束。 - 逐步添加约束测试:从可行的基础模型开始,逐步添加约束,每次求解后检查是否可行,快速定位导致矛盾的约束。
- 放松约束验证:将等式约束改为不等式(如
==改为<=),若求解成功,说明原等式约束过于严格,存在矛盾。 - 自由度检查:查看求解器输出的自由度信息,若自由度为正但仍无可行解,大概率存在隐含约束矛盾。
- 简化模型测试:减少变量或约束数量,构建最小化的测试模型,验证求解逻辑是否正确,再逐步扩展到原模型。
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

