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
相关产品推荐
相关产品推荐

