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

含GEKKO未知变量的NumPy数组数学运算方法及Gekko整数规划目标函数问题求助

解决Gekko中未知变量与NumPy数组运算及整数规划目标函数问题

首先,你遇到的核心问题是:Gekko的未知变量(Var)不能直接参与NumPy的数值运算,因为Gekko需要构建优化问题的符号表达式,而NumPy是针对确定数值的运算,在变量未求解前会引发错误。下面我们一步步修正你的代码,并解释关键要点。

原代码的主要问题

  1. 错误的数组索引:w1[:,0] 是无效的,因为 w1 是一维NumPy数组(形状为 (3,)),没有第二维索引,应该直接用 w1[i] 访问单个元素。
  2. 误用NumPy函数处理Gekko变量:d.min(axis=1).sum() 这类NumPy操作无法处理Gekko的Var对象,必须改用Gekko内置的符号函数来构建目标函数。
  3. 目标函数的构建方式错误:直接将包含NumPy运算的函数返回值传给 m.Obj(),会导致Gekko无法识别符号表达式,进而求解失败。

修正后的代码及解释

from gekko import GEKKO
import numpy as np

# 初始化数据
d_initial = np.array([10, 30, 50])  # 对应原d[:,0]的初始值
w1 = np.array([0, 1.2, 2])
w2 = np.array([0, 2, 0])
w3 = np.array([0.1, 0, 0.2])

# 初始化Gekko模型
m = GEKKO(remote=False)
m.options.SOLVER = 1  # 使用APOPT求解器,支持整数规划

# 定义整数变量
x1 = m.Var(value=1, lb=1, ub=3, integer=True)
x2 = m.Var(value=1, lb=1, ub=4, integer=True)
x3 = m.Var(value=1, lb=1, ub=5, integer=True)

# 构建每个行的剩余值(对应原d[:,1]的每个元素)
d_residual = []
for i in range(3):
    # 计算d_i = d_initial[i] - w1[i]*x1 - w2[i]*x2 - w3[i]*x3
    res = m.Intermediate(d_initial[i] - w1[i]*x1 - w2[i]*x2 - w3[i]*x3)
    d_residual.append(res)

# 构建目标函数:每行取d_initial[i]和residual的最小值,再求和
obj = 0
for i in range(3):
    # 使用Gekko的min2函数计算两个值的最小值(符号化操作)
    row_min = m.min2(d_initial[i], d_residual[i])
    obj += row_min

# 设置目标函数(默认是最小化,若需最大化可加负号)
m.Obj(obj)

# 求解
m.solve(disp=True)  # 打开disp=True便于查看求解过程

# 输出结果
print('Results')
print('x1: ' + str(x1.value[0]))
print('x2: ' + str(x2.value[0]))
print('x3: ' + str(x3.value[0]))
print('Objective: ' + str(m.options.objfcnval))

关键要点说明

  1. 使用m.Intermediate处理中间表达式:
    对于涉及Gekko变量的数组运算,我们需要用m.Intermediate将每个元素的表达式包装为Gekko可识别的符号变量,而不是直接用NumPy数组存储。

  2. 用Gekko内置函数替代NumPy函数:

    • 求最小值用m.min2(a, b)(针对两个值)或m.min3(a,b,c),多值最小可嵌套使用;
    • 求和直接用Python的+累加,或者m.sum()函数(例如m.sum(row_mins),其中row_mins是Gekko变量的列表);
    • 其他运算如最大值、绝对值等,都有对应的Gekko内置函数(m.max2、m.abs等)。
  3. 整数规划求解器选择:
    你设置的m.options.SOLVER=1是正确的,APOPT求解器支持整数变量(Integer Programming),而默认的IPOPT求解器仅支持连续变量。

关于Gekko变量与NumPy数组运算的通用建议

  • 避免直接将GekkoVar对象放入NumPy数组进行运算,而是逐个处理每个元素,用m.Intermediate保存符号表达式;
  • 所有需要参与优化的运算,都必须使用Gekko的符号函数,确保优化器能正确构建问题的梯度和约束;
  • 如果需要批量处理数组,可以用循环遍历每个元素,构建对应的Gekko中间变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 09:22:30