Creating a set with two-dimensional entries using a loop

25 views
Skip to first unread message

Jan Harmuth

unread,
Jun 9, 2021, 4:59:10 PM6/9/21
to AMPL Modeling Language
Hello all,

I have several quantities and would like to simplify the creation for large instances by using a loop. The following information is given:

set S := 1 .. 4;

set Sn{S};
set Sn[1] := 1 2;
set Sn[2] := 2 1;
set Sn[3] := 3 4;
set Sn[4] := 4 3;

set W := {i in S, j in S};

set An{W} within {i in S, j in S};

Now I am trying to create a loop that will create the set An entries below so that they do not have to be entered manually.

set An[1,1] := (1,1) (1,2) (2,1) (2,2);
set An[1,2] := (1,1) (1,2) (2,1) (2,2);
set An[1,3] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4); 
set An[1,4] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4);
set An[2,1] := (1,1) (2,1) (1,2) (2,2);
set An[2,2] := (1,1) (1,2) (2,1) (2,2);
set An[2,3] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4);
set An[2,4] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4);
set An[3,1] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4);
set An[3,2] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4);
set An[3,3] := (3,3) (3,4) (4,3) (4,4);
set An[3,4] := (3,3) (3,4) (4,3) (4,4);
set An[4,1] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4);
set An[4,2] := (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4);
set An[4,3] := (3,3) (3,4) (4,3) (4,4);
set An[4,4] := (3,3) (3,4) (4,3) (4,4);

I hope for your help so that I can also handle large instances.

Many thanks in advance.

AMPL Google Group

unread,
Jun 10, 2021, 12:41:16 PM6/10/21
to AMPL Modeling Language
You do not give a rule for deciding, given an i and a j, what set to assign to An[i,j]. Here is an example however of an AMPL loop that gives the assignments shown in your example:

set S := 1 .. 4;
set W := {i in S, j in S};
set An {W} within {i in S, j in S};

for {i in S, j in S}
   let An[i,j] :=
      if {i}union{j} within 1..2 then {1..2,1..2} 
      else if {i}union{j} within 3..4 then {3..4,3..4} 
      else {1..4,1..4};

In this simple case, you can use an indexed let statement rather than a loop:

let {i in S, j in S} An[i,j] :=
   if {i}union{j} within 1..2 then {1..2,1..2} 
   else if {i}union{j} within 3..4 then {3..4,3..4} 
   else {1..4,1..4};

For larger instances, your rule might be more complicated, but these examples should give you an idea of what you can do. If you can use the indexed let statement, it will be faster than the loop when S is large, but to express complicated rules the loop might be necessary.


--
Robert Fourer
am...@googlegroups.com
{#HS:1538824149-104887#}
Reply all
Reply to author
Forward
0 new messages