GEKKO求解混合整数非线性规划模型遇「模型不足」错误求助
解决GEKKO "Insufficient Model" 错误的方案
核心问题分析
报错显示模型未识别到变量和方程,主要原因是方程添加方式错误,同时存在未定义的参数变量问题。
具体修复步骤
1. 修正方程添加方法
GEKKO中,m.Equation()用于添加单个方程,添加多个方程需使用m.Equations()(复数形式)。你的代码中三次使用m.Equation([...])传递方程列表,导致方程未被正确添加到模型中。
修改如下:
# 原代码 m.Equation([xyi[i] <= d[i] for i in range(ni)]) m.Equation([sum([ Lkj[k][j]*y[j][k] for j in range(nj)]) <= h1*w1 for k in range(nk)]) m.Equation([sum([Lkj[k][j]*y[j][k] for k in range(nk)]) == s/7 - P[j] for j in range(nj)]) # 修改后 m.Equations([xyi[i] <= d[i] for i in range(ni)]) m.Equations([sum([ Lkj[k][j]*y[j][k] for j in range(nj)]) <= h1*w1 for k in range(nk)]) m.Equations([sum([Lkj[k][j]*y[j][k] for k in range(nk)]) == s/7 - P[j] for j in range(nj)])
2. 定义未声明的参数变量
代码中引用了w、h、sum_total、PPP、VV、sumP这些变量,但未给出定义。必须在创建Gekko常量/参数前为这些变量赋值,例如:
# 示例赋值(根据实际问题替换) w = 100 h = 50 sum_total = 10000 PPP = [10]*ni # 假设每个P[i]为10 VV = [5]*ni # 假设每个V[i]为5 sumP = [2000]*nj # 假设每个sumP[j]为2000
3. 优化模型规模(可选但关键)
你的模型包含超过95万个整数变量(x的维度是4550×35×6),远远超出常规求解器的处理能力。建议:
- 先使用小规模测试集(例如
ni=10、nk=2、nj=2)验证模型正确性 - 考虑模型简化,减少变量维度或使用启发式算法辅助求解
- 若必须保留原规模,需使用支持大规模MINLP的商业求解器
完整修复后的代码示例
# ___Initialize model___ m = GEKKO() # ___Global options_____ m.options.SOLVER = 1 # 使用APOPT求解MINLP # 定义未声明的参数(根据实际问题修改) ni = 10 # 先使用小规模测试 nj = 2 nk = 2 w = 100 h = 50 sum_total = 1000 PPP = [10]*ni VV = [5]*ni sumP = [200]*nj # variables: x = m.Array(m.Var, (ni,nk,nj), lb=0, integer=True) #integer variable y = m.Array(m.Var, (nj,nk), lb=0, ub=1, integer=True) #binary variable # Parameters: w1 = m.Const(w) h1 = m.Const(h) Psum_total = m.Const(value=sum_total) P = m.Array(m.Param, ni) for i in range(ni): P[i].value = PPP[i] V = m.Array(m.Param, ni) for i in range(ni): V[i].value = VV[i] d = m.Array(m.Param, ni) for i in range(ni): d[i] = 50 Psum_vetor = m.Array(m.Param, nj) for j in range(nj): Psum_vetor[j].value = sumP[j] #Intermediate Lkj = [[m.Intermediate(m.sum([P[i]*x[i][k][j] for i in range(ni)])) for j in range(nj)] for k in range(nk)] xyi = [m.Intermediate(m.sum([x[i][k][j]*y[j][k] for k in range(nk) for j in range(nj)])) for i in range(ni)] z = m.Intermediate(m.sum([xyi[i]*V[i] for i in range(ni)])) s = Psum_total for k in range(nk): for j in range(nj): s += Lkj[k][j] # Equations(使用m.Equations复数形式) m.Equations([xyi[i] <= d[i] for i in range(ni)]) m.Equations([sum([Lkj[k][j]*y[j][k] for j in range(nj)]) <= h1*w1 for k in range(nk)]) m.Equations([sum([Lkj[k][j]*y[j][k] for k in range(nk)]) == s/7 - P[j] for j in range(nj)]) m.Obj(-z) m.options.IMODE = 3 m.solve(disp=True) print("x values:") for i in range(ni): for k in range(nk): for j in range(nj): if x[i][k][j].value[0] > 0: print(f"x[{i}][{k}][{j}] = {x[i][k][j].value[0]}")
验证说明
先运行小规模测试代码确认模型能正常求解,再逐步扩大规模。若仍有问题,检查方程逻辑是否符合装箱问题的约束条件(例如每个物品是否被正确分配到箱子等)。
内容的提问来源于stack exchange,提问作者NBC
相关产品推荐
相关产品推荐

