Originally posted by: ThomasSuf
Hello,
again I found some strange behaviour in the scripting log since the update to version 12.7. In my big MILP I'm using some piecewise functions, so I made up a small example model to test the behaviours of different piecewise formulations. It results that depending on the formulation the information shown in the scripting log are erroneous while the objective value is correct in both cases. Below you find my code as well as the scripting logs and I attached the .mod-file as well.
What I want to do:
I want to minimize the cost for opening and closing production stations. Therefore, I have a Boolean decision variable SA which represents if the station is open (1) or closed (0). Opening a station costs 50 MU and closing a station results in earnings of 20 MU because of selling equipment. When the difference of the last period and the actual period equals -1 a station will be opened, if it equals 1 it will be closed and if it equals 0 the status stays as it is. I tried two piecewise formulations which should behave equally:
1. Linear interpretation: Since my decision variable can take only the values -1, 0 and 1 this problem can be interpreted as a piecewise linear function. The slope from -1 to 0 equals the opening cost and the slope from 0 to 1 the closing cost/earnings.
2. Stepwise interpretation: In reality this problem is a stepwise function. So I formulated two jumps at -0,1 and 0,1. /*EDIT: Here I took a different anchor point (0, 0) but the problem still exists when I take the same anchor point in both versions, too. */
The problem
Although both versions give the same objective value (not considering some rounding issues in the second version) the export in the scripting log isn't consistent. While the 1st version shows the actual reconfiguration cost, the 2nd versions displays the reconfiguration cost in each period as 0.
My questions:
a) Is there an error in my code or is this behaviour a bug?
b) Is the rounding error normal for this formulation or just coincidence?
Thanks in advance!
Best regards,
Thomas
Code:
int MaxT = 4; //planing horizon
range T = 1..MaxT; //set of all discrete periods
range T0 = 0..MaxT;
{string} S = {"test"}; //set of all stations
int SA_Init[S] = [0]; //inital configuration of s
float copcs[S,1..2] = [[-50,-20]]; //cost for opening/closing a station
dvar boolean SA[T0][S]; //activity of station s
dexpr float C_ReconfigurationS[t in T] =
//sum(s in S) piecewise{0 -> -1; copcs[s,1]-> 0; copcs[s,2]->1; 0} (1,copcs[s,2]) (SA[t-1,s]-SA[t,s]); //linear interpretation
sum(s in S) piecewise{0->-0.1; copcs[s,1]->-0.1; 0->0.1; copcs[s,2]->0.1; 0} (0,0) (SA[t-1,s]-SA[t,s]); //stepwise interpretation
minimize sum(t in T) C_ReconfigurationS[t];
subject to {
forall(s in S)
InitSA:
SA[0,s]==SA_Init[s];
forall(t in T, s in S)
open2:
SA[2,s]==1;
}
execute{
for(var t in T)
{ for(var s in S)
{ writeln("t:" + t + " SA:" + SA[t][s] + " Cost:" + C_ReconfigurationS[t])}
} }
Scripting log:
1st version:
// solution (optimal) with objective 30
t:1 SA:0 Cost:0
t:2 SA:1 Cost:50
t:3 SA:1 Cost:0
t:4 SA:0 Cost:-20
2nd version:
// solution (optimal) with objective 29.99999964
t:1 SA:0 Cost:0
t:2 SA:1 Cost:0
t:3 SA:0 Cost:0
t:4 SA:0 Cost:0
#DecisionOptimization#OPLusingCPLEXOptimizer