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

Gekko求解复杂MINLP任务调度模型性能优化问询

问题背景
  • 求解一个MINLP模型,用于给不同日程的人员分配任务,需根据可用时间限制每人每个日程的最大任务数。
  • 模型索引:i=人员,z=日程,j=任务,a=任务执行顺序。
  • 目标函数包含四类成本:
    • 任务耗时超计划成本
    • 任务耗时不足计划成本
    • 后续任务延迟成本
    • 人员空闲时间成本
  • 决策变量:
    • TC:各任务的执行时长(同一任务对所有人员时长一致)
    • C:任务是否按指定顺序执行的0-1变量(部分日程可执行多任务)
  • 问题:小规模数据集求解需10分钟,但较大数据集超出140分钟时限,需支持更大规模数据;已尝试简化模型、调整Gekko参数,不确定是模型定义(数学/概念层面)问题,还是有其他性能优化方法。

当前尝试代码

tc_var = {}
for index in index_f_a:
    tc_var[index] = m.Var(value=25, name='tc_var_{}'.format(index), lb=15, ub=45, integer=False)

s_var = {}
for index in index_f_h:
     s_var[index] = m.Var()

for i, z in index_f_h:
    m.Equation(tmd[(i, z)]*0.8 + s_var[(i, z)] == np.sum([index_a_v[(i, z)][-1][1]*tc_var[(i, j)] for j in list(set([x[0] for x in index_a_v[(i, z)]]))]) )
    m.Equation(s_var[(i, z)] >= 0)

def k1(i, z, j, a):
    a_dif = tce[(i, z, j, a)] - tc_var[(i, j)].VALUE
    return a_dif if a_dif > 0 else 0

def k2(i, z, j, a):
    a_dif = tc_var[(i, j)].VALUE - tce[(i, z, j, a)]
    return a_dif if a_dif > 0 else 0

def k3(i, z, j, a):
    a_dif = np.sum([tce[(i, z, j, a2)] for a2 in index_f_h_a_v1[i, z, j]]) - (a-1)*tc_var[(i, j)].VALUE 
    return a_dif if a_dif > 0 else 0

def k4(i, z):
    a_dif = tmd[(i, z)] - np.sum([index_a_v[(i, z)][-1][1]*tc_var[(i, j)].VALUE for j in list(set([x[0] for x in index_a_v[(i, z)]]))])
    return a_dif if a_dif > 0 else 0


m.Minimize(m.sum([k1(i, z, j, a)*KCA 
              + k2(i, z, j, a)*KCI 
              + k3(i, z, j, a)*KME 
              for i, z, j, a in index_f_h_a_v])
       + m.sum([k4(i, z) for i, z in index_f_h]) * KI 
            )

m.options.MAX_TIME=600 
m.options.MAX_ITER=5000
m.options.REDUCE=3

m.solver_options = ['minlp_gap_tol 1.0e-2',
                'minlp_branch_method 1',
                'minlp_max_iter_with_int_sol 500']

最终修正方案

代码核心问题是错误使用决策变量的.VALUE属性:在Gekko中,.VALUE仅代表变量的初始值或求解后的结果,求解过程中不能用它构建模型逻辑表达式,否则会导致求解器无法正确解析模型,既影响结果正确性,也会大幅降低求解性能。

需用Gekko内置的m.max2()函数替代Python原生条件判断,将非线性逻辑转化为求解器可处理的数学表达式,修正后的成本函数示例如下:

def k1(i, z, j, a):
    return m.max2(tce[(i, z, j, a)] - tc_var[(i, j)], 0)

def k2(i, z, j, a):
    return m.max2(tc_var[(i, j)] - tce[(i, z, j, a)], 0)

def k3(i, z, j, a):
    sum_tce = np.sum([tce[(i, z, j, a2)] for a2 in index_f_h_a_v1[i, z, j]])
    return m.max2(sum_tce - (a-1)*tc_var[(i, j)], 0)

def k4(i, z):
    sum_tc = np.sum([index_a_v[(i, z)][-1][1]*tc_var[(i, j)] for j in list(set([x[0] for x in index_a_v[(i, z)]]))])
    return m.max2(tmd[(i, z)] - sum_tc, 0)

额外优化手段(针对大规模数据集):

  • 精简变量与约束:排查冗余变量或可合并的约束,对重复求和逻辑预计算中间变量。
  • 调优求解器参数:
    • 适当调大minlp_gap_tol(如1e-2至1e-1),在可接受精度范围内减少求解时间。
    • 尝试不同minlp_branch_method(0=深度优先,1=广度优先),匹配问题特性选择分支策略。
  • 优化初始值:给决策变量设置更贴近最优解的初始值,帮助求解器快速收敛。
  • 线性化处理:将可转化的非线性逻辑改为线性约束,降低求解计算负担。

内容的提问来源于stack exchange,提问作者Rita s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:27:45