Pyomo建模报错求助:约束定义与参数计算问题
解决方案
错误1:NameError: name 'techs' is not defined
问题原因:约束函数里把m.TAC[techs,suppliers]放在了sum表达式外面,而techs和suppliers是sum循环内的局部变量,循环结束后就不存在了,导致外部引用时找不到变量。正确逻辑应该是对每个amount_installed_techs项乘以对应的TAC,再求和。
修正后的约束函数:
def total_TACperyear(m, years): return sum(m.amount_installed_techs[tech, supp, years] * m.TAC[tech, supp] for tech in m.techs for supp in m.suppliers) <= m.totalTACperyear[years]
错误2:TypeError: 无法从float类型数据创建Set
问题原因:demandsperyear函数里错误使用了m.years(这是Pyomo的Set对象),而不是当前的参数years(具体年份数值)。计算增长时应该用当前迭代的年份值,而非整个年份集合。
修正后的参数初始化函数:
def demandsperyear(m, demand, product, year): if year == 1: return m.initial_demand[demand, product] # 这里用参数year,而非m.years;若为复利增长,可改为 (1 + m.growth[demand, product])**(year-1) return m.initial_demand[demand, product] * (1 + m.growth[demand, product] * (year - 1))
完整修正代码
from pyomo.environ import * # 定义模型 m = AbstractModel() # 定义集合 m.techs = Set() m.products = Set() m.suppliers = Set() m.demands = Set() m.years = Set() # 定义参数 m.initial_demand = Param(m.demands, m.products) m.growth = Param(m.demands, m.products) m.yields = Param(m.techs, m.products, m.suppliers) m.emission = Param(m.techs, m.suppliers) m.TAC = Param(m.techs, m.suppliers) m.max_installed = Param(m.techs, m.suppliers) m.totalTACperyear = Param(m.years) m.totalCO2peryear = Param(m.years) # 定义变量 m.installed_techs = Var(m.techs, m.suppliers, m.years, within=Binary) m.amount_installed_techs = Var(m.techs, m.suppliers, m.years, bounds=(0, None)) m.totalTAC = Var(bounds=(None, None)) m.totalCO2 = Var(bounds=(None, None)) # 目标函数 def total_TAC(m): return sum(m.totalTACperyear[year] for year in m.years) m.economics = Objective(rule=total_TAC, sense=minimize) # CO2总量约束 def total_CO2(m): return m.totalCO2 == sum(m.totalCO2peryear[year] for year in m.years) m.totalCO2_cons = Constraint(rule=total_CO2) # 年度TAC约束(修正后) def total_TACperyear(m, years): return sum(m.amount_installed_techs[tech, supp, years] * m.TAC[tech, supp] for tech in m.techs for supp in m.suppliers) <= m.totalTACperyear[years] m.TACperyear_cons = Constraint(m.years, rule=total_TACperyear) # 产品需求参数计算(修正后) def demandsperyear(m, demand, product, year): if year == 1: return m.initial_demand[demand, product] # 线性增长示例,若为复利则改为 (1 + m.growth[demand, product])**(year-1) return m.initial_demand[demand, product] * (1 + m.growth[demand, product] * (year - 1)) m.product_demands = Param(m.demands, m.products, m.years, initialize=demandsperyear) # 数据字典 data = {None: { 'techs' : {None: ['tek_A', 'tek_B', 'tek_C']}, 'products' : {None: ['prod_A', 'prod_B', 'prod_C']}, 'suppliers' : {None: ['daerah_A', 'daerah_B', 'daerah_C']}, 'demands' : {None: ['daerah_A', 'daerah_B', 'daerah_C']}, 'years' : {None: list(range(1, 31))}, 'initial_demand': {('daerah_A','prod_A'): 10, ('daerah_A','prod_B'): 10, ('daerah_A','prod_C'): 10, ('daerah_B','prod_A'): 20, ('daerah_B','prod_B'): 20, ('daerah_B','prod_C'): 20, ('daerah_C','prod_A'): 12, ('daerah_C','prod_B'): 12, ('daerah_C','prod_C'): 12}, 'growth': {('daerah_A','prod_A'): 0.02, ('daerah_A','prod_B'): 0.02, ('daerah_A','prod_C'): 0.02, ('daerah_B','prod_A'): 0.02, ('daerah_B','prod_B'): 0.02, ('daerah_B','prod_C'): 0.02, ('daerah_C','prod_A'): 0.02, ('daerah_C','prod_B'): 0.02, ('daerah_C','prod_C'): 0.02}, 'max_installed' : {('tek_A','daerah_A'): 100, ('tek_A','daerah_B'): 100, ('tek_A','daerah_C'): 100, ('tek_B','daerah_A'): 100, ('tek_B','daerah_B'): 100, ('tek_B','daerah_C'): 100, ('tek_C','daerah_A'): 100, ('tek_C','daerah_B'): 100, ('tek_C','daerah_C'): 100}, 'TAC' : {('tek_A','daerah_A'): 100, ('tek_A','daerah_B'): 100, ('tek_A','daerah_C'): 100, ('tek_B','daerah_A'): 100, ('tek_B','daerah_B'): 100, ('tek_B','daerah_C'): 100, ('tek_C','daerah_A'): 100, ('tek_C','daerah_B'): 100, ('tek_C','daerah_C'): 100}, 'emission' : {('tek_A','daerah_A'): 20, ('tek_A','daerah_B'): 20, ('tek_A','daerah_C'): 20, ('tek_B','daerah_A'): 20, ('tek_B','daerah_B'): 20, ('tek_B','daerah_C'): 20, ('tek_C','daerah_A'): 20, ('tek_C','daerah_B'): 20, ('tek_C','daerah_C'): 20}, 'yields': {('tek_A','prod_A','daerah_A'):8, ('tek_A','prod_A','daerah_B'):8, ('tek_A','prod_A','daerah_C'):8, ('tek_A','prod_B','daerah_A'):8, ('tek_A','prod_B','daerah_B'):8, ('tek_A','prod_B','daerah_C'):8, ('tek_A','prod_C','daerah_A'):8, ('tek_A','prod_C','daerah_B'):8, ('tek_A','prod_C','daerah_C'):8, ('tek_B','prod_A','daerah_A'):8, ('tek_B','prod_A','daerah_B'):8, ('tek_B','prod_A','daerah_C'):8, ('tek_B','prod_B','daerah_A'):8, ('tek_B','prod_B','daerah_B'):8, ('tek_B','prod_B','daerah_C'):8, ('tek_B','prod_C','daerah_A'):8, ('tek_B','prod_C','daerah_B'):8, ('tek_B','prod_C','daerah_C'):8, ('tek_C','prod_A','daerah_A'):8, ('tek_C','prod_A','daerah_B'):8, ('tek_C','prod_A','daerah_C'):8, ('tek_C','prod_B','daerah_A'):8, ('tek_C','prod_B','daerah_B'):8, ('tek_C','prod_B','daerah_C'):8, ('tek_C','prod_C','daerah_A'):8, ('tek_C','prod_C','daerah_B'):8, ('tek_C','prod_C','daerah_C'):8}, 'totalTACperyear': {year: 10**6 for year in range(1, 31)}, 'totalCO2peryear': {year: 10**6 for year in range(1, 31)} }} instance = m.create_instance(data)
内容的提问来源于stack exchange,提问作者Zulfan
相关产品推荐
相关产品推荐

