How to update parameters iteratively within a Loop?

Problems with syntax of GAMS
Post Reply
GabrielYin
User
User
Posts: 72
Joined: 6 years ago
Location: Dallas, TX, USA
Contact:

How to update parameters iteratively within a Loop?

Post by GabrielYin »

Hi All,

Sorry for asking so many questions but I really need help. I tried to use iteratively updated parameters to do my algorithm, named Column and Constraint Generation, which has been enlightened by the Benders Decomposition. Then I am a little bit confused about how I can update my parameters from the previous one with some conditions. These parameters are all Binary. Here shows how I define the iteration set:

Code: Select all

Set itera /itera1*itera50/;

Set columnset(itera)        dynamic set;
columnset(itera) = no;

Parameter L_avail;            * this is my planned updating parameter

Loop(itera,                       * Here is how I insert the 1st iteration result, "L_avail0(l)" is a fixed parameter.
        if(ord(itera) ge 2,
        break;);
        L_avail(l, itera) = L_avail0(l);
);
Then I modeled my problem with these updating parameters, and here shows parts of the equations definition:

Code: Select all

... ...
Llim10(l, columnset)..      f(l) =g= - L_avail(l, columnset) * LDATA(l, 'FLmax');
Llim20(l, columnset)..      f(l) =l= L_avail(l, columnset) * LDATA(l, 'FLmax');
... ...
These codes ensured that in each iteration these constraints would be added repeatedly with different parameters.

Then I tried to use the following codes to update my parameters.

Code: Select all

Loop(itera,
         if(ord(itera) ge 2,                         * bc the 1st results have been stored and fixed.
               Solve ... ...
               Loop(l,
                     if(xl.l(l) = 1,                    * xl.l are solutions.
                     L_avail(l, itera) = 1);        * update
         );
);
What I got in 1st iteration are like follows. There is no problem since my xl.l results were l1, l2, l4, l5 = 1.000, l3 = 0.

Code: Select all

---- 445 PARAMETER L_avail 

    itera1

l1 1.000
l2 1.000
l4 1.000
l5 1.000
When it came to the 2nd iteration, problem occurred.

Code: Select all

---- 420 PARAMETER L_avail 

    itera1     itera2

l1 1.000
l2 1.000
l3              1.000
l4 1.000
l5 1.000 
The results for xl.l were only l3 = 1, but it seemed that it could only adapt the xl.l results without inheriting the itera1's result. What I imagined to go is itera2 would firstly copy the itera1, then apply the xl.l. Then my ideal result should be like follows.

Code: Select all

---- 420 PARAMETER L_avail 

    itera1 itera2

l1 1.000 1.000
l2 1.000 1.000
l3          1.000
l4 1.000 1.000
l5 1.000 1.000
How can I achieve that? Sorry for posting too many codes, but my goal is simple. I know I cannot achieve this by adding a simple one line code like:

Code: Select all

L_avail(l, itera) = L_avail(l, itera-1)
Loop(l,
        if(xl.l(l) = 1, 
        L_avail(l, itera) = 1); 
);
Thanks for reading all of these.
User avatar
bussieck
Moderator
Moderator
Posts: 1033
Joined: 7 years ago

Re: How to update parameters iteratively within a Loop?

Post by bussieck »

Hi,

why does your last suggestion not work? This code does what you want to accomplish:

Code: Select all

Set itera /itera1*itera5/;
set l / l1*l10 /;
$onempty
Parameter L_avail(l,itera) / /;
variable xl(l);
loop(itera,
  if (ord(itera)>1,
     L_avail(l, itera) = L_avail(l, itera-1);
     xl.l(l) = 1$(uniform(0,1)<0.2);
*     Loop(l,
*           if(xl.l(l) = 1, 
*           L_avail(l, itera) = 1));
* I prefer parallel assignment statements over loops, and better round your variable levels if they come from a solver!
     L_avail(l, itera)$round(xl.l(l)) = 1;
  else
     L_avail(l, itera) = 1$(uniform(0,1)<0.2);
  )
  display xl.l, L_avail;
);
-Michael
GabrielYin
User
User
Posts: 72
Joined: 6 years ago
Location: Dallas, TX, USA
Contact:

Re: How to update parameters iteratively within a Loop?

Post by GabrielYin »

Thank you sir, it worked as I expected. Why I could not get the same output before was I messed up with the iteration. Actually I had one set of parameters which should be returned to all 0 at the beginning of one iteration, and one set of parameters which are free. Both of the two sets of parameters are going to be updated based on two solutions from one subproblem and one master problem in my algorithm as described in this post.

Nevertheless, this problem has been solved! Thanks a lot!
Jarenka
User
User
Posts: 64
Joined: 5 years ago

Re: How to update parameters iteratively within a Loop?

Post by Jarenka »

Dear,

I have a similar problem, but instead of updating parameter I would like to write it in in a matrix/array at each iteration.
My code is the following:

Code: Select all

*parameters xNpjf(P,Jn);
set ITR /ITR0 * ITR5/;
parameter mat_xNpjf(P,Jn,ITR);

loop(ITR,
          solve $include "C:\Users\is\Documents\gamsdir\projdir\Model.gms"
          mat_xNpjf(P,Jn,ITR) = xNpjf(P,Jn);
);
display mat_xNpjf;
The program doesn't work because of this:

Code: Select all

solve $include "C:\Users\is\Documents\gamsdir\projdir\Model.gms"
. I tried to exclude the link, and the program, at each iteration, writes the values of xNpjf into the matrix/array. So basically it works - giving me the same value of xNpjf at each iteration.

What I want here is that every time the loop iterate it gives me a new value of xNpjf, which is calculated in a previous section/model (the link). And I want this value to be written in mat_xNpjf.
How to include a link in a loop in such a way that every time it iterates it goes to the model, recalculates xNpjf and writes it to the mat_xNpjf?

Best Regards
GabrielYin
User
User
Posts: 72
Joined: 6 years ago
Location: Dallas, TX, USA
Contact:

Re: How to update parameters iteratively within a Loop?

Post by GabrielYin »

Jarenka wrote: 5 years ago Dear,

I have a similar problem, but instead of updating parameter I would like to write it in in a matrix/array at each iteration.
My code is the following:

Code: Select all

*parameters xNpjf(P,Jn);
set ITR /ITR0 * ITR5/;
parameter mat_xNpjf(P,Jn,ITR);

loop(ITR,
          solve $include "C:\Users\is\Documents\gamsdir\projdir\Model.gms"
          mat_xNpjf(P,Jn,ITR) = xNpjf(P,Jn);
);
display mat_xNpjf;
The program doesn't work because of this:

Code: Select all

solve $include "C:\Users\is\Documents\gamsdir\projdir\Model.gms"
. I tried to exclude the link, and the program, at each iteration, writes the values of xNpjf into the matrix/array. So basically it works - giving me the same value of xNpjf at each iteration.

What I want here is that every time the loop iterate it gives me a new value of xNpjf, which is calculated in a previous section/model (the link). And I want this value to be written in mat_xNpjf.
How to include a link in a loop in such a way that every time it iterates it goes to the model, recalculates xNpjf and writes it to the mat_xNpjf?

Best Regards
Hey Jarenka,

What I know for now is GAMS does not support using user-defined functions. I understand what you tried to do, because it is just like Matlab and Python, but GAMS might not be able to do this.

What you can try is, write the link out of the loop, create a new loop and loop index for it, export everything to the new loop and your link then import the values back. Maybe using GDX file is good for this.

Cheers!
Gabriel
Jarenka
User
User
Posts: 64
Joined: 5 years ago

Re: How to update parameters iteratively within a Loop?

Post by Jarenka »

Dear GabrielYin,

Yes, I did it as you said and it works.!

I am very used to R-program and SAS, so for me it is something new.

Thank you for your help!!
Post Reply