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

GEKKO资源优化问题:权重比值计算致目标值NaN的修复请求

资源优化问题GEKKO求解NaN问题修复

问题背景

现有资源优化问题:2名工人、4项任务,每项任务仅分配给一名工人,每名工人仅承接一项任务,目标是最大化总奖励。决策变量包括:

  • 0-1分配矩阵:任务与工人的分配关系
  • 权重数组:每项任务的相对权重
    工人奖励计算逻辑为:任务权重 / 总权重 × 对应任务奖励,总奖励为两人奖励之和。

原始代码

import numpy as np
from gekko import GEKKO

rewards = np.array([[2,5,8,10],[1,5,7,11]])

m = GEKKO(remote=False)

allocation = m.Array(m.Var,(2,4),lb=0,ub=1, integer=True)
weights = m.Array(m.Var,4,lb=0,ub=1)


def reward(allocation, weights, rewards):
    temp=np.copy(allocation)
    #sum_ = np.sum(weights)
    for i in range(allocation.shape[1]):
        temp[:, i] *= weights[i]#/sum_
    
    total_rewards = np.sum(temp.flatten() * rewards.flatten())
    return total_rewards


for j in range(4):
    m.Equation(m.sum(allocation[:,j])<=1) 


m.Maximize(reward(allocation, weights, rewards))

m.options.SOLVER = 1        # change solver (1=APOPT,3=IPOPT)
#m.open_folder()
m.solve()

print('allocation', allocation)
print('weights', weights)
print('Objective: ' + str(m.options.objfcnval))

问题现象

  • 注释sum_时输出正常:
----------------------------------------------------------------
 APMonitor, Version 1.0.1
 APMonitor Optimization Suite

 ----------------------------------------------------------------
 
 
 --------- APM Model Size ------------
 Each time step contains
   Objects      :            0
   Constants    :            0
   Variables    :           16
   Intermediates:            0

   Connections  :            0
   Equations    :            5
   Residuals    :            5
 
 Number of state variables:             16
 Number of total equations: -            4
 Number of slack variables: -            4
 ---------------------------------------
 Degrees of freedom       :              8
 
 ----------------------------------------------
 Steady State Optimization with APOPT Solver
 ----------------------------------------------
Iter:     1 I:  0 Tm:      0.00 NLPi:    4 Dpth:    0 Lvs:    3 Obj: -1.63E+01 Gap:       NaN
--Integer Solution:   0.00E+00 Lowest Leaf:  -1.63E+01 Gap:   2.00E+00
Iter:     2 I:  0 Tm:      0.00 NLPi:    2 Dpth:    1 Lvs:    2 Obj:  0.00E+00 Gap:  

2.00E+00
Iter:     3 I:  0 Tm:      0.00 NLPi:    3 Dpth:    1 Lvs:    4 Obj: -2.60E+01 Gap:  2.00E+00
--Integer Solution:  -26.00E+00 Lowest Leaf:  -2.60E+01 Gap:   0.00E+00
Iter:     4 I:  0 Tm:      0.00 NLPi:    1 Dpth:    2 Lvs:    4 Obj: -2.60E+01 Gap:  0.00E+00
 Successful solution
 
 ---------------------------------------------------
 Solver         :  APOPT (v1.0)

 Solution time  :   1.729999999224674E-002 sec
 Objective      :   -26.0000000000000     
 Successful solution
 ---------------------------------------------------
 

allocation [[[1.0] [1.0] [1.0] [0.0]]
 [[0.0] [0.0] [0.0] [1.0]]]
weights [[1.0] [1.0] [1.0] [1.0]]
Objective: -26.0

注:此输出中工人1承接3项任务,违反“每名工人仅能承接一项任务”的约束,说明原始代码缺少该约束。

  • 取消注释sum_时出现NaN:
----------------------------------------------------------------


APMonitor, Version 1.0.1
 APMonitor Optimization Suite
 ----------------------------------------------------------------
 
 
 --------- APM Model Size ------------
 Each time step contains
   Objects      :            0
   Constants    :            0
   Variables    :           16
   Intermediates:            0
   Connections  :            0
   Equations    :            5
   Residuals    :            5
 
 Number of state variables:             16
 Number of total equations: -            4
 Number of slack variables: -            4
 ---------------------------------------
 Degrees of freedom       :              8
 
 ----------------------------------------------
 Steady State Optimization with APOPT Solver
 ----------------------------------------------
Iter:     1 I:  0 Tm:      0.01 NLPi:    2 Dpth:    0 Lvs:    0 Obj:       NaN Gap:  0.00E+00
 Successful solution
 
 ---------------------------------------------------
 Solver         :  APOPT (v1.0)

     Solution time  :   2.390000000013970E-002 sec
     Objective      :                      NaN
     Successful solution
     ---------------------------------------------------
     
    
    allocation [[[0.0] [0.0] [0.0] [0.0]]
     [[0.0] [0.0] [0.0] [0.0]]]
    weights [[0.0] [0.0] [0.0] [0.0]]
    Objective: nan

问题分析与修复

核心问题

  1. 除以0风险:总权重sum_可能为0,直接导致NaN。
  2. 符号变量处理错误:用np.sum()处理GEKKO变量数组,numpy无法识别GEKKO的符号变量,应使用GEKKO内置的m.sum()。
  3. 约束缺失:原始代码仅限制每项任务最多分配给一名工人,未限制每名工人最多承接一项任务,导致分配结果不符合问题要求。
  4. numpy操作破坏符号结构:np.copy()、flatten()等numpy操作会将GEKKO的符号变量转换为数值数组,导致优化器无法正确构建目标函数。

修复后的代码

import numpy as np
from gekko import GEKKO

rewards = np.array([[2,5,8,10],[1,5,7,11]])

m = GEKKO(remote=False)

# 0-1分配矩阵
allocation = m.Array(m.Var,(2,4),lb=0,ub=1, integer=True)
# 权重数组,设置下限避免全0
weights = m.Array(m.Var,4,lb=1e-6,ub=1)

# 计算总权重,使用GEKKO的sum函数
total_weight = m.sum(weights)

# 定义总奖励:用GEKKO的符号运算替代numpy操作
total_reward = 0
for worker in range(2):
    for task in range(4):
        # 任务权重/总权重 × 该任务对应奖励 × 是否分配
        total_reward += (weights[task]/total_weight) * rewards[worker][task] * allocation[worker][task]

# 约束1:每项任务最多分配给一名工人
for task in range(4):
    m.Equation(m.sum(allocation[:,task]) <= 1)

# 约束2:每名工人最多承接一项任务
for worker in range(2):
    m.Equation(m.sum(allocation[worker,:]) <= 1)

# 最大化总奖励
m.Maximize(total_reward)

# 使用APOPT求解混合整数规划
m.options.SOLVER = 1
m.solve()

# 打印结果
print("分配矩阵:")
for row in allocation:
    print([x.value[0] for x in row])
print("\n权重数组:")
print([w.value[0] for w in weights])
print(f"\n最大化总奖励: {m.options.objfcnval:.4f}")

修复说明

  1. 给weights设置下限1e-6,避免总权重为0;同时用m.sum()计算总权重,确保符号运算正确。
  2. 用循环构建目标函数,避免numpy的数组操作,保证GEKKO能正确识别符号变量关系。
  3. 添加工人承接任务数的约束,确保每个工人最多接一项任务。
  4. 优化结果打印方式,更清晰展示数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:35:08