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

Pyomo多时段混合整数优化建模:目标函数构建求助

解决Pyomo多时段混合整数优化的目标函数与索引问题

核心问题分析

你遇到的list indices must be integers or slices, not str错误,本质是用字符串索引Python原生列表(比如用时段/技术名称当索引),但列表仅支持整数索引;而Pyomo确实不兼容直接用numpy数组作为变量/参数的载体,因为它的建模逻辑依赖自身的集合(Set)体系管理索引关系。

分步解决方案

1. 用Pyomo集合重构模型基础结构

抛弃原生列表,改用Pyomo的Set定义技术和时段维度,从根源避免索引混乱:

from pyomo.environ import *

# 初始化模型
model = ConcreteModel()

# 定义集合:4种技术、12个时段
model.TECHS = Set(initialize=['tech1', 'tech2', 'tech3', 'tech4'])
model.TIMES = Set(initialize=range(1, 13))  # 对应1-12时段

# 定义容量变量:每个技术-时段组合的容量值
model.x = Var(model.TECHS, model.TIMES, domain=NonNegativeReals)

# 定义二进制选择变量:标记某时段是否启用该技术
model.y = Var(model.TECHS, model.TIMES, domain=Binary)

2. 用Pyomo参数导入价格数据

把你的价格列表转换成字典格式(键为技术-时段元组),再传入Pyomo的Param,彻底解决索引类型错误:

# 假设你已有按技术、时段顺序排列的价格列表,先转成字典
price_dict = {}
# 示例转换逻辑(根据你的实际列表结构调整)
tech_list = ['tech1', 'tech2', 'tech3', 'tech4']
for tech_idx, tech in enumerate(tech_list):
    for time_idx, t in enumerate(model.TIMES):
        # 替换成你的价格列表取值,比如your_price_list[tech_idx][time_idx]
        price_dict[(tech, t)] = your_price_data[tech_idx][time_idx]

# 定义价格参数
model.price = Param(model.TECHS, model.TIMES, initialize=price_dict)

3. 编写合法的目标函数

基于Pyomo集合和参数直接构建目标,不会出现类型冲突:

# 目标:最小化总容量成本(若为最大化收益,将sense改为maximize即可)
def total_cost_rule(model):
    return sum(model.x[tech, t] * model.price[tech, t] 
               for tech in model.TECHS 
               for t in model.TIMES)

model.total_cost = Objective(rule=total_cost_rule, sense=minimize)

4. 添加互斥约束

实现“同时段技术1与2互斥、技术3与4互斥”的要求:

# 技术1与技术2同时段互斥约束
def tech1_tech2_excl_rule(model, t):
    return model.y['tech1', t] + model.y['tech2', t] <= 1

model.tech1_tech2_excl = Constraint(model.TIMES, rule=tech1_tech2_excl_rule)

# 技术3与技术4同时段互斥约束
def tech3_tech4_excl_rule(model, t):
    return model.y['tech3', t] + model.y['tech4', t] <= 1

model.tech3_tech4_excl = Constraint(model.TIMES, rule=tech3_tech4_excl_rule)

# 容量与选择变量绑定:仅当启用技术时,容量可大于0
def capacity_bind_rule(model, tech, t):
    # YOUR_MAX_CAP替换为该技术的最大允许容量
    return model.x[tech, t] <= model.y[tech, t] * YOUR_MAX_CAP

model.capacity_bind = Constraint(model.TECHS, model.TIMES, rule=capacity_bind_rule)

关键注意事项

  • 永远不要用字符串索引Python原生列表,Pyomo建模优先用Set+Param/Var的索引体系,这是Pyomo的核心设计逻辑。
  • 如需使用numpy数据,必须先转换成字典格式(键为集合索引元组),再传入Pyomo组件,避免兼容性问题。
  • 必须添加容量变量与二进制变量的绑定约束,否则模型无法将“技术选择”和“容量分配”关联起来。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:35:40