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

使用Gurobi Solver求解线性规划时遇TypeError错误求助

问题排查与修正

错误核心原因

  • 你调用model.addVars()得到的x是Gurobi的tupledict对象,并非普通Python列表或numpy数组。当你在c1函数里将变量与numpy数组运算后,返回的是gurobipy.LinExpr对象,该对象不支持索引访问(即不能用[i]),这就是触发TypeError: 'gurobipy.LinExpr' object is not subscribable的直接原因。
  • 额外问题:代码中存在大量重复的数据加载逻辑,既冗余又易出错;约束c2是全局CFE目标约束,不需要循环添加500次。

修正步骤

  1. 提前预处理数据:一次性提取所有需要用到的切片数据,避免在每个函数里重复操作。
  2. 直接用Gurobi变量构建表达式:不要试图将Gurobi变量转成numpy数组,而是通过循环或Gurobi内置方法直接构建目标函数与约束。
  3. 修正约束逻辑:c1是500个逐时段的能量平衡约束,需逐个构建;c2是单个全局约束,无需循环。

修正后的完整代码

import pandas as pd
import gurobipy as gp
from gurobipy import GRB
import numpy as np

# 预处理数据(仅执行一次)
TEST = pd.read_excel('/Users/Desktop/project/Datasets/Test2031.xlsx')
TEST_matrix = TEST.to_numpy()
load_slice = TEST_matrix[:500, 0].flatten()
wind_slice = TEST_matrix[:500, 1].flatten()
solar_slice = TEST_matrix[:500, 2].flatten()
gridPrice_slice = TEST_matrix[:500, 4].flatten()

COSTWIND = 70
COSTSOLAR = 70
target = 0.85    # CFE目标值

# 创建Gurobi模型
model = gp.Model()

# 定义变量:明确含义,避免索引混淆
x1 = model.addVar(lb=0, ub=10000000, name="Wind_MW")
x2 = model.addVar(lb=0, ub=10000000, name="Solar_MW")
y = model.addVars(500, lb=0, ub=10000000, name="Grid_MWh")
z = model.addVars(500, lb=0, ub=10000000, name="Excess_WindSolar_MWh")

# 构建目标函数
obj = (x1 * COSTWIND * np.sum(wind_slice) +
       x2 * COSTSOLAR * np.sum(solar_slice) +
       gp.quicksum(gridPrice_slice[t] * y[t] for t in range(500)))
model.setObjective(obj, GRB.MINIMIZE)

# 添加逐时段能量平衡约束(原c1)
for t in range(500):
    model.addConstr(
        x1 * wind_slice[t] + x2 * solar_slice[t] + y[t] - z[t] == load_slice[t],
        name=f"Energy_Balance_{t}"
    )

# 添加全局CFE目标约束(原c2)
total_generation = x1 * np.sum(wind_slice) + x2 * np.sum(solar_slice)
total_excess = gp.quicksum(z[t] for t in range(500))
total_load = np.sum(load_slice)
model.addConstr(
    (total_generation - total_excess) / total_load >= target,
    name="CFE_Target"
)

# 执行优化
model.optimize()

# 输出结果
if model.status == GRB.OPTIMAL:
    print("找到最优解")
    print("目标函数值:", model.objVal)
    print("变量解:")
    print(f"风电装机容量 (MW): {x1.x}")
    print(f"光伏装机容量 (MW): {x2.x}")
    # 若需查看逐时段购电/弃电量,可取消以下注释
    # for t in range(500):
    #     print(f"时段{t}购电量(MWh): {y[t].x}, 弃电量(MWh): {z[t].x}")
else:
    print("优化失败,状态码:", model.status)

关键改进点说明

  • 变量命名清晰:用x1、x2、y[t]、z[t]替代模糊的索引命名,便于理解维护。
  • 规避LinExpr索引错误:通过循环逐个构建约束,不再将LinExpr当作数组处理。
  • 简化表达式构建:使用Gurobi的quicksum替代numpy的sum,更适配Gurobi变量运算。
  • 修正约束逻辑:c2改为单个全局约束,符合CFE目标(总有效发电量/总负荷)的定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:15:11