@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.