Page 1 of 2

How to loop the matrix

Posted: Tue Feb 19, 2019 4:59 am
by LiangYu
Dear All.
About a few days ago, I asked a similar question.
I used to ask the scalar loop(Thanks Mr. Michael solve this problem), now I have problems when it becomes a matrix.
This is a scalar solution.
Untitled_9.gms
(3.66 KiB) Downloaded 289 times
The key code is this paragraph

Code: Select all

scalar minc1 /inf/, bestns1 /1/,n1;

while(bestns1 < 10,
bestns1=bestns1+1;
ns1.fx=bestns1;


option optcr=0.0001;
  solve exchanger1 using minlp minimizing c1;
* Optimal or feasible solution
  if ((exchanger1.modelstat=1 or exchanger1.modelstat=8)and(c1.l<minc1),
    minc1 = c1.l;
    n1=bestns1;
  );
);

display minc1,n1;


Now I want to ask how to make a code when it comes to solving seven kinds of data at the same time.(7 kinds of data brought to the above file can have 7 answers)
Untitled_8.gms
(5.16 KiB) Downloaded 267 times
Would not describe the part of the code. (I don't know how to turn "" ns1.fx(heatx)"" into scalar)
Meaning is probably like this.

Code: Select all

parameters
minc1(heatx) /ex1*ex7 inf/
bestns1(heatx)/ex1*ex7 1/
;
bestns1(heatx)$(r(heatx) ne 1)=1;

parameter n1,bestp121,bestft1,besta1;

while(bestns1(heatx)<10,
ns1.fx(heatx)=bestns1(heatx)+1;
solve exchanger1 using minlp minimizing z1;
if ((exchanger1.modelstat=1 or exchanger1.modelstat=8) and (c1.l(heatx) < minc1(heatx)),
minc1(heatx)  = c1.l(heatx);
n1(heatx)=bestns1(heatx);
bestp121(heatx)=p121.l(heatx);
bestft1(heatx)=ft1.l(heatx);
besta1(heatx)=a1.l(heatx);
  );
);

option decimals = 4;
display minc1,n1,bestp121,bestft1,besta1;

Re: How to loop the matrix

Posted: Thu Feb 21, 2019 9:26 am
by Renger
Hi

You have to be clear about your stopping condition: does the while loop have to stop as soon as one of the bestns1(heatx) is above 10? Or if all bestns1 are equal to 9?

Let us assume it is the first stopping criterion, then you probably would change the code like this:

Code: Select all

while(smax(heatx, bestns1(heatx)) < 10,
(smax gives you the maximum of a vector).

If it is the last option:

Code: Select all

while(smin(heatx, bestns1(heatx)) < 10,
In both cases, I assume that bestns1 will reach 10 finally for all heatx (otherwise your model will run forever).
If this could happen, you have to add another while condition to stop the iterations (perhaps the sum over all bestns1 doesn't change anymore:

Code: Select all

parameter 
sumbestns  /1/, 
submbestnsprevious /0/;

while(sumbestns ne submbestnsprevious, 
   submbestnsprevious = sumbestns;
solve...
  sumbestns = sum(heatx, bestns(heatx));
  ...
  );
  
I hope this answers your question.

Cheers
Renger

Re: How to loop the matrix

Posted: Thu Feb 21, 2019 10:16 am
by LiangYu
My problem is the first one, let it stop the loop before 10, and find the best answer among them.
Untitled_8.gms
(5.23 KiB) Downloaded 280 times
I use this code. but the model is run forever.

Code: Select all

parameters
minc1
bestns1
mc1
cc1
;
bestns1(heatx)$(r(heatx) ne 1)=1;
minc1(heatx)$(r(heatx) ne 1)=inf;
mc1=sum(heatx,minc1(heatx));
cc1=sum(heatx,c1.l(heatx));

parameter n1,bestp121,bestft1,besta1;

while((smax(heatx, bestns1(heatx)) < 10),
ns1.fx(heatx)=bestns1(heatx)+1;

solve exchanger1 using minlp minimizing z1;
if ((exchanger1.modelstat=1 or exchanger1.modelstat=8) and (cc1 < mc1),
minc1(heatx)  = c1.l(heatx);
n1(heatx)=bestns1(heatx);
bestp121(heatx)=p121.l(heatx);
bestft1(heatx)=ft1.l(heatx);
besta1(heatx)=a1.l(heatx);
  );
);

option decimals = 4;
display minc1,n1,bestp121,bestft1,besta1;
Sorry, Renger. this code, I don't know which side to enter.

Code: Select all

parameter 
sumbestns  /1/, 
submbestnsprevious /0/;

while(sumbestns ne submbestnsprevious, 
   submbestnsprevious = sumbestns;
solve...
  sumbestns = sum(heatx, bestns(heatx));
  ...
  );
  
Thank you.

Re: How to loop the matrix

Posted: Thu Feb 21, 2019 11:28 am
by Renger
Hi
You should send me a model version that actually solves, or has no solution, but doesn't stop because of having negative numbers in the log function by initializing the model properly.
Or send the model that runs indefinitely
Cheers
Renger

Re: How to loop the matrix

Posted: Fri Feb 22, 2019 4:15 am
by LiangYu
Renger, Thank you again.
I am missing a small piece of code and it can converge.

If I want to find the best value in these loop ranges, how should I modify my IF sentence? Because it is showing the answer is the maximum value of the loop 10.

the full file.
Untitled_8.gms
(5.12 KiB) Downloaded 265 times
This is sets code

Code: Select all

parameters
minc1
bestns1
sumz1
sumc1
;
bestns1(heatx)$(r(heatx) ne 1)=1;
minc1(heatx)$(r(heatx) ne 1)=inf;
summz1=sum(heatx,minc1(heatx));
sumc1=sum(heatx,c1.l(heatx));

parameter n1;

while((smax(heatx, bestns1(heatx)) < 10),
bestns1(heatx)$(r(heatx) ne 1)=bestns1(heatx)+1;
ns1.fx(heatx)=bestns1(heatx);

solve exchanger1 using minlp minimizing z1;

if ((exchanger1.modelstat=1 or exchanger1.modelstat=8) and (sumc1 < sumz1),
minc1(heatx)  = c1.l(heatx);
n1(heatx)=bestns1(heatx);

  );
);

display minc1,n1;
---- 154 PARAMETER minc1

ex1 112371.675, ex3 260081.845, ex4 333833.750, ex5 291600.978
ex6 275433.284, ex7 412156.453


---- 154 PARAMETER n1

ex1 10.000, ex3 10.000, ex4 10.000, ex5 10.000, ex6 10.000
ex7 10.000

this is scalar code ( but it can find out the best value from 1 to 10 in the loop)
Untitled_9.gms
(3.67 KiB) Downloaded 243 times

Code: Select all

scalar minc1 /inf/, bestns1 /1/,n1;

while(bestns1 < 10,
bestns1=bestns1+1;
ns1.fx=bestns1;

  solve exchanger1 using minlp minimizing c1;
* Optimal or feasible solution
  if ((exchanger1.modelstat=1 or exchanger1.modelstat=8)and(c1.l<minc1),
    minc1 = c1.l;
    n1=bestns1;
  );
);

display minc1,n1;
132 PARAMETER minc1 = 109064.251
PARAMETER n1 = 6.000

Re: How to loop the matrix

Posted: Fri Feb 22, 2019 4:20 pm
by Renger
Hi
As you don't loop over a set, it is difficult to write a parameter with all the results directly.
I would do it like this:

Code: Select all

set loopnr Loop number /1*100/;;

parameter loopcount  /1/;

parameter results(loopnr, *,*);

while(...
	solve model
	loopcount = loopcount + 1;
	results(loopnr, "Mincl")$(loopnr.val = loopcount) = cl.l;
	results(loopnr, "nsl")$(loopnr.val = loopcount) = bestns1;
	...
This would give you all the results in a nice parameter and you can look for the best solution.

Hope this helps
Cheers
Renger

Re: How to loop the matrix

Posted: Fri Feb 22, 2019 5:09 pm
by LiangYu
I am very sorry, my degree is not good.

Is it convenient to enter the complete code?

Thank you very much for guiding me very patiently, Renger.
Untitled_8.gms
(5.13 KiB) Downloaded 225 times

Code: Select all

parameters
minc1
bestns1
sumz1
sumc1
;
bestns1(heatx)$(r(heatx) ne 1)=1;
minc1(heatx)$(r(heatx) ne 1)=inf;
sumz1=sum(heatx,minc1(heatx));
sumc1=sum(heatx,c1.l(heatx));

parameter n1;

while((smax(heatx, bestns1(heatx)) < 10),
bestns1(heatx)$(r(heatx) ne 1)=bestns1(heatx)+1;
ns1.fx(heatx)=bestns1(heatx);

solve exchanger1 using minlp minimizing z1;

if ((exchanger1.modelstat=1 or exchanger1.modelstat=8) and (sumc1 < sumz1),
minc1(heatx)  = c1.l(heatx);
n1(heatx)=bestns1(heatx);
  );
);

display minc1,n1;

Re: How to loop the matrix

Posted: Sat Feb 23, 2019 5:19 pm
by Renger

Code: Select all

set loopnr Loop number /1*100/;;

parameter loopcount  /1/;

parameter results(loopnr, *,*);

while((smax(heatx, bestns1(heatx)) < 10),
bestns1(heatx)$(r(heatx) ne 1)=bestns1(heatx)+1;
ns1.fx(heatx)=bestns1(heatx);

solve exchanger1 using minlp minimizing z1;
    loopcount = loopcount + 1;
    results(loopnr, "Mincl")$(loopnr.val = loopcount) = cl.l;
    results(loopnr, "nsl")$(loopnr.val = loopcount) = bestns1;

if ((exchanger1.modelstat=1 or exchanger1.modelstat=8) and (sumc1 < sumz1),
minc1(heatx)  = c1.l(heatx);
n1(heatx)=bestns1(heatx);
  );
);

display minc1,n1, results;

Re: How to loop the matrix

Posted: Sat Feb 23, 2019 5:31 pm
by LiangYu
Sorry, It says Different dimensions.
The following two codes:
************************************************
results(loopnr, "Mincl")$(loopnr.val = loopcount) = c1.l;
results(loopnr, "nsl")$(loopnr.val = loopcount) = bestns1;
************************************************

Code: Select all

set loopnr Loop number /1*100/;;

parameter loopcount  /1/;

parameter results(loopnr, *,*);

parameters
minc1
bestns1
sumz1
sumc1
;
bestns1(heatx)$(r(heatx) ne 1)=1;
minc1(heatx)$(r(heatx) ne 1)=inf;
sumz1=sum(heatx,minc1(heatx));
sumc1=sum(heatx,c1.l(heatx));

parameter n1;

while((smax(heatx, bestns1(heatx)) < 10),
bestns1(heatx)$(r(heatx) ne 1)=bestns1(heatx)+1;
ns1.fx(heatx)=bestns1(heatx);

solve exchanger1 using minlp minimizing z1;
    loopcount = loopcount + 1;
    results(loopnr, "Mincl")$(loopnr.val = loopcount) = c1.l;
    results(loopnr, "nsl")$(loopnr.val = loopcount) = bestns1;

if ((exchanger1.modelstat=1 or exchanger1.modelstat=8) and (sumc1 < sumz1),
minc1(heatx)  = c1.l(heatx);
n1(heatx)=bestns1(heatx);
  );
);

display minc1,n1, results;

Re: How to loop the matrix

Posted: Sun Feb 24, 2019 10:54 am
by Renger
Sorry, it should have been results(loopnr, *) as definition.
R