@FOR Set Looping Function

The @FOR function is used to generate constraints across members of a set. Whereas scalar based modeling languages require you to explicitly enter each constraint, the @FOR function allows you to enter a constraint just once, and LINGO does the work of generating an occurrence of the constraint for each set member. Thus, the @FOR statement provides the set-based modeler with a very powerful tool.

To illustrate the use of @FOR, consider the following set definition:

SETS:

  TRUCKS / MAC, PETERBILT, FORD, DODGE/: HAUL;

ENDSETS

Specifically, we have a primitive set of four trucks with a single attribute titled HAUL. If attribute HAUL is used to denote the amount a truck hauls, then we can use the @FOR function to limit the amount hauled by each truck to 2,500 pounds with the following expression:

@FOR( TRUCKS( T): HAUL( T) <= 2500);

In this case, it might be instructive to view the constraints that LINGO generates from our expression. You can do this by using the Solver|Generate|Display model command under Windows, or by using the GENERATE command on other platforms. Running this command, we find that LINGO generates the following four constraints:

HAUL( MAC) <=   2500

HAUL( PETERBILT) <=   2500

HAUL( FORD) <=   2500

HAUL( DODGE) <=   2500

In other words, as we anticipated, LINGO generated one constraint for each truck in the set limiting it to a load of 2,500 pounds.

Here is a model that uses an @FOR statement (listed in bold) to compute the reciprocal of any five numbers placed into the VALUE attribute:

MODEL:

SETS:

  NUMBERS /1..5/: VALUE, RECIPROCAL;

ENDSETS

DATA:

  VALUE = 3 4 2 7 10;

ENDDATA

  @FOR( NUMBERS( I):

     RECIPROCAL( I) = 1 / VALUE( I)

  );

END

Solving this model gives the following values for the reciprocals:

RECIPROCAL( 1)       0.3333333

RECIPROCAL( 2)       0.2500000

RECIPROCAL( 3)       0.5000000

RECIPROCAL( 4)       0.1428571

RECIPROCAL( 5)       0.1000000

Since the reciprocal of zero is not defined, we could put a conditional qualifier on our @FOR statement that causes us to skip the reciprocal computation whenever a zero is encountered. The following @FOR statement accomplishes this:

@FOR( NUMBERS( I) | VALUE( I) #NE# 0:

  RECIPROCAL( I) = 1 / VALUE( I)

);

The conditional qualifier (listed in bold) tests to determine if the value is not equal (#NE#) to zero. If so, the computation proceeds.

This was just a brief introduction to the use of the @FOR statement. There are many additional examples in other sections.