Skip to main content

Hi, 

Is there any way of looping through a for-loop backwards? 

The subset is ordered by user, for example {1,4,3,5}. I want to loop backwards so from 5 to 3 to 4 to 1. 

 

 

Hello,

 

Sure. 


The idea is to create a subset that is ordered. Given some set in which you want to visit the elements according to some order, say s_a, create a subset, say s_b as follows:

Set s_b {

    SubsetOf: s_a;

    Index: i_b;

    OrderBy: -i_a;

}

and assign s_a to s_b.

Next, you can visit the elements in reverse order by using the index i_b.

 

Details in the enclosed project. 

You may also want to checkout the order by attribute: https://documentation.aimms.com/language-reference/non-procedural-language-components/set-declaration/set-declaration-and-attributes.html#:~:text=an%20existing%20identifier.-,The%20OrderBy%20attribute,-With%20the%20OrderBy

 

With kind regards,

 

Chris


HI @Chris Kuip

That sounds logical, thank you! 

The problem is that I need the reverse order of a subset. The subset that I created with your help in another topic: Read data Excel in an order | AIMMS Community 

I cannot create a subset of a subset as far as I know. Is there any way to tackle this problem in another way or can I create a subset of a subset? 

Kind regards,

Mirthe


Hello Mirthe,

 

You can create subsets of subsets. See the enclosed example.

 

 

With kind regards,

 

Chris


Hi @Chris Kuip , 

Also if the first subset has an index domain? 

In my case: 

I have articles p and jobs j. Each article follows a specific job route so I created a subset Article_ProductionRoutes(p) from the set job. Now I want to have the subset Article_ProductionRouteBackwards(p) from subset Article_ProductionRoutes(p). However, I cannot select the subset Article_ProductionRoutes when it has an index domain. I can when I remove the index domain, however, this is not what I want. 

 

Kind regards, 

Mirthe


Hi Mirthe,

 

Indeed, you cannot declare an indexed set to be a subset of another indexed set.

However, you can declare two indexed sets to be the subset of the same set. Once you have done that you can use the elements in the existing indexed set in the new indexed set; and also you can use the ordering of the existing indexed set in the new indexed set.

Enclosed find an adapted example of 

 

In that example we constructed the indexed set:
 

    Set s_let {

        IndexDomain: i_rowno;

        SubsetOf: s_alphabet;

        OrderBy: user;

        InitialData: data{};

    }


To revert the data in s_let, we create a new set as follows:

    Set s_tel {

        IndexDomain: i_rowno;

        SubsetOf: s_alphabet;

        OrderBy: -ord(i_let,s_let(i_rowno));

        Definition: s_let(i_rowno);

    }


Remarks:

  1. the two sets have the same index domain and the same subset of.
  2. s_let has an order by: "user”, and s_tel uses an expression.
  3. the data for s_let is specified in a procedure, the data for s_tel is defined in its definition attribute.
  4. the expression in the order by of s_tel uses ord with two arguments, the second one is the set.  This is allowed to be an indexed set.

With kind regards,

 

Chris


Hi @Chris Kuip , 

That worked, thank you very much for the clear answer!


Hi @Chris Kuip , one additional question. 

I created the subset TimeBucketsBackwards (index: tb) to loop over. 

Now I want to loop only from the due date of an order (which is a parameter: p_DueDatePO(p))  of a order backwards to 1. 

I thought about: for tb in {DueDatePO(p)..1} do 

However, this does not work and I get the following error: The data type numeric expression DueDatePO(p) cannot be turned into an element valued expression (use functions ElementRange/StringToElement or root set Integers).

I am having troubles implementing one of the functions. 

Do you have a suggestion to implement this loop starting from the value of p_DueDatePO(p) to 1. 

 

 


Hi Mirthe, 


Instead of {p..q} (where q < p), you can use ElementRange(p,q,incr:-1), for instance as follows:
​​​​​

 

    Procedure MainExecution {

        Body: {

            p := 3 ;

            q := 1 ;

            s := ElementRange(

                From    :  p, 

                To      :  q, 

                Incr    :  -1 );

            for i in S do 

                e := i ;

                display e ;

            endfor ;

        }

        Parameter p;

        Parameter q;

        Set s {

            SubsetOf: Integers;

            Index: i;

            Parameter: e;

            OrderBy: user;

        }

    }

 

Note that the ordering is retained because the set S is declared as order by user.

 

With kind regards,

 

Chris


Reply


Didn't find what you were looking for? Try searching on our documentation pages:

AIMMS Developer & PRO | AIMMS How-To | AIMMS SC Navigator