使用Pyomo与Python计算两个索引参数比率时遇TypeError的技术求助
Hey there! Let's break down why you're hitting this error and walk through how to fix it.
The Root Cause
Your model.Dmem and model.Cmem are IndexedParams—they're collections of parameters tied to specific sets (model.nf and model.ns respectively). Pyomo can't directly apply the / operator to these whole collections because it doesn't know how to map elements between the two different sets, or whether you want element-wise ratios, a total aggregate ratio, etc.
Solutions Based on Your Use Case
1. Element-wise Ratios (Same Set or Defined Mapping)
If model.nf and model.ns are the same set, or you have a clear mapping between elements of nf and ns, create an indexed Expression (or Param, if the value is fixed) to calculate ratios for each element:
Example for Same Set
# Assuming model.nf and model.ns are the same set (e.g., named 'model.n') model.ame = Expression(model.n, rule=lambda m, i: m.Cmem[i] / m.Dmem[i])
Example with a Custom Mapping
If elements of nf map to specific elements of ns, first define the mapping, then compute ratios:
# Step 1: Define a mapping from nf elements to ns elements model.f_to_s_map = Param(model.nf, within=model.ns, initialize=lambda m, f: "your_mapped_s_element_here") # Step 2: Calculate ratios using the mapping model.ame = Expression(model.nf, rule=lambda m, f: m.Cmem[m.f_to_s_map[f]] / m.Dmem[f])
2. Aggregate Total Ratio
If you want the ratio of total capacity to total demand (sum of all Cmem values divided by sum of all Dmem values), use Pyomo's summation function first:
from pyomo.environ import summation # Calculate total values first model.total_capacity = Expression(expr=summation(model.Cmem)) model.total_demand = Expression(expr=summation(model.Dmem)) # Compute the aggregate ratio model.ame = Expression(expr=model.total_capacity / model.total_demand)
Important Note: Handle Division by Zero
Make sure to account for cases where Dmem[i] might be 0 to avoid runtime errors. Add a conditional check in your rule:
# Example with division-by-zero safeguard model.ame = Expression(model.n, rule=lambda m, i: m.Cmem[i] / m.Dmem[i] if m.Dmem[i] != 0 else 0) # Replace 0 with a reasonable default value for your use case
内容的提问来源于stack exchange,提问作者Waqas Swati

