SOLVE Statement in a LOOP

In my model I would like to explore the effect of fixing a variable. I am trying to do this this way:


Solve Model USING RMIP MAXIMIZING F ;
Scalar Relaxed ;
Relaxed = F.L ;

loop (i,
loop(j,
loop(k,

  • fix variable W(i,j,k) to 1.0
    

W.FX(i,j,k) = 1.0 ;
SOLVE Model USING RMIP MAXIMIZING F ;

  • if the relaxed value when W(i,j,k)=1 worsens, then
    
  • set W(i,j,k)=0.0 and try the next W(i,j,k)
    if( ((F.L < Relaxed)),
    W.FX(i,j,k) = 0.0 ;
    )
    )
    )
    ) ;
    SOLVE Model USING MIP MAXIMIZING F ;


    W(i,j,k) are variables that appear in the model. i,j,k are sets that are used in the model.

GAMS terminates with the error: "Loop controlling index appears in model equation(s). "

How can I design the loop, so it is correct?

Hi
Perhaps you could loop over the aliases of i, j, and k and use the ord-function to fix variables:

alias(i,ii), (j,jj), (k,kk);

loop(ii, 
	loop(jj,  
		loop(kk,
			W.FX(i,j,k)$(ord(i) = ord(ii) and ord(j) = ord(jj) and ord(k) = ord(kk)) = 1.0;
			... etc.

Note, that when you no longer want to fix a variable, you should set the proper uppper and lower bound of the unfixed variable.
Cheers
Renger

Hi Renger

Sorry to bother you again. I implemented the code the way you suggested. The code gets compiled without errors but then it exhibits a strange execution behaviour. The inner loop is not executed correctly. I use the parameter run to break the inner loop, as I am using an older version of GAMS that doesn’t support break.

I found this link talking about problems with the loop execution.
https://www.gams.com/latest/testlib_ml/libhtml/testlib_nest2.html

Do you think we have here another instance of such a problem or have I just made a mistake in my coding?

The logic of my code is: some of the elements of set i are performed on ressource j others do not.
If not performing an instance of a job doen’t worsen the relaxation value of the MILP, if fix it to zero (I set W=0) otherwise I don’t touch it.

Can you see an obvious mistake in my code? A mistake that would cause the inner loop to terminate too early?
Perhaps something with the IFs in the inner loop?

set i /H,R1,R2,R3,Sep/ ; !! i are jobs
set j /H,U1,U2, Stil/ ; !! j are resources
set k /1*5/; !! k are job instances


SOLVE Part USING RMIP MAXIMIZING F ;
Scalar Relaxed ;
Relaxed = F.L ;

scalar run /1/ ;
alias (i, ii), (j, jj), (k, kk) ;

loop(jj,
loop( ii$(Ji(jj,ii) eq 1) ,
loop(kk,

if( (run = 1),
W.FX(i,j,k)$(ord(i) = ord(ii) and ord(j) = ord(jj) and ord(k) = ord(kk)) = 0.0;
SOLVE Part USING RMIP MAXIMIZING F ;
) ; !! if
if( (F.L < Relaxed),

  • restore bounds for W(i,j,k) and termine the inner loop by setting run = 0
    W.LO(i,j,k)(ord(i) = ord(ii) and ord(j) = ord(jj) and ord(k) = ord(kk)) = 0.0; W.UP(i,j,k)(ord(i) = ord(ii) and ord(j) = ord(jj) and ord(k) = ord(kk)) = 1.0 ;
    run = 0 ;
    ) ; !! if

) ; !! kk
run = 1 ;
) ; !! ii
) ; !! jj

Hello Renger

The problem lies in the IF Statement

if( (F.L < Relaxed),

The floating point arithmetic does here harm. If I reformulate to

if( (F.L < (Relaxed + 0.0001)),

then everything works fine.

Thank you

Clement