GAMS条件参数TWC(j)实现求助:基于HS(j)的分段取值
Hey there! Let's sort out this conditional logic issue you're hitting in GAMS. The problem with your current approach is that using HS.l(j) (the level value from a prior iteration) in a $ condition doesn't work for endogenous variables like HS(j)—since HS(j)'s value isn't known when the model starts solving, you can't base a parameter or constraint on it that way. Instead, we need to model this piecewise condition explicitly within the optimization constraints. Here are two reliable methods to implement what you need:
Method 1: Binary Variable + Big-M Constraints (Most Compatible)
This approach uses a binary variable to track whether HS(j) meets the 1000 threshold, then links that binary to the cost term in your objective.
Define a binary variable:
binary variable y(j);y(j)will be 1 whenHS(j) ≥ 1000, and 0 whenHS(j) < 1000.Add constraints to link
y(j)andHS(j):
Choose a scalarMthat's larger than the maximum possible valueHS(j)could take (e.g., 1e6 if your HS values don't go beyond that):scalar M / 1000000 /; HS_Threshold_Low(j).. HS(j) >= 1000 * y(j); HS_Threshold_High(j).. HS(j) <= 1000 + M * (1 - y(j));- The first constraint ensures that if
y(j)=1,HS(j)must be at least 1000. - The second constraint ensures that if
y(j)=0,HS(j)can't exceed 1000 (theM*(1-y(j))term drops out wheny(j)=1, so no upper bound is enforced there).
- The first constraint ensures that if
Update your objective function:
Replace theTWC(j)*HS(j)term with3.21*y(j)*HS(j). This automatically handles the conditional logic:- When
HS(j) ≥1000,y(j)=1, so the term becomes3.21*HS(j) - When
HS(j) <1000,y(j)=0, so the term equals 0
- When
Method 2: Piecewise Linear Function (For Solvers That Support It)
If you're using a solver that handles piecewise linear functions (like CPLEX or Gurobi), you can define the conditional cost directly as a piecewise linear term:
Define the piecewise linear points:
We need to mapHS(j)values to the corresponding cost term (TWC(j)*HS(j)):parameter pwl_points(4,2); pwl_points(1,1) = 0; pwl_points(1,2) = 0; # HS=0 → cost=0 pwl_points(2,1) = 1000; pwl_points(2,2) = 0; # HS=1000 (below threshold) → cost=0 pwl_points(3,1) = 1000; pwl_points(3,2) = 3210; # HS=1000 (at threshold) → cost=3.21*1000=3210 pwl_points(4,1) = 1e6; pwl_points(4,2) = 3.21e6; # Max HS → cost=3.21*maxHSIntegrate into your objective:
Use GAMS'piecewisefunction to include this in your objective equation:equation obj_def; obj_def.. z =e= [your other objective terms] - piecewise(pwl_points, HS(j));
Why Your Initial Approach Failed
Just to clarify why your original equation didn't work: HS.l(j) refers to the solution value of HS(j) from a previous solve, not the value it will take in the current optimization run. GAMS evaluates $ conditions before solving the model, so it can't use an unknown variable value to set a parameter or constraint dynamically. We have to model this logic as part of the problem's constraints instead of relying on iteration-level values.
内容的提问来源于stack exchange,提问作者Gigi Botte

