Input Statements

The two functions in this section, @READLN (read line) and @REAMRM (read to record marker) are for programmatically reading text input data in calc sections.  This contrasts with input functions in data sections.  Data section input cannot be programmatically controlled and will be executed regardless whenever the model is solved.  With @READLN and @REAMRM, you may dynamically test conditions to determine if and/or how the text reads are executed.  You may also dynamically specify how much text to read based on things such as the dimensions of the current model.

@READLN( [‘FILE_NAME’][, LINES])

The @READLN function reads a specified number of lines (LINES) from a text file ('FILE_NAME').  The file name argument is optional, and if it is omitted the last file name used in either a @READLN or @READRM will be substituted.  The number of lines argument, LINES, can be a constant or a scalar variable giving the number of lines to read.  If LINES is omitted, then a single line will be read.

@READRM( [‘FILE_NAME’][, 'RECORD_MARKER'])

The @READRM function reads from a text file ('FILE_NAME') until either it encounters any specified record marker string or the end of the file.  The file name argument is optional, and if it is omitted the last file name used in either a @READLN or @READRM will be substituted.  The record marker string may also be omitted, in which case, @READRM will read to the end of the file.

We will now illustrate the use of these input functions with the following transportation model, TRAN, found in the LINGO samples model set:

MODEL:

! A 3 Warehouse, 4 Customer

  Transportation Problem;

SETS:

  WAREHOUSE / WH1, WH2, WH3/   : CAPACITY;

  CUSTOMER   / C1, C2, C3, C4/ : DEMAND;

  ROUTES( WAREHOUSE, CUSTOMER) : COST, VOLUME;

ENDSETS

 

! The objective;

[OBJ] MIN = @SUM( ROUTES: COST * VOLUME);

 

! The demand constraints;

@FOR( CUSTOMER( J): [DEM]

 @SUM( WAREHOUSE( I): VOLUME( I, J)) >=

  DEMAND( J));

 

! The supply constraints;

@FOR( WAREHOUSE( I): [SUP]

 @SUM( CUSTOMER( J): VOLUME( I, J)) <=

  CAPACITY( I));

 

! Here are the parameters;

DATA:

  CAPACITY =   30, 25, 21 ;

  DEMAND =   15, 17, 22, 12;

  COST =      6,  2,  6,  7,

              4,  9,  5,  3,

              8,  8,  1,  5;

ENDDATA

END

Model: TRAN

In this model, we see that all the data (the set names and the parameters) are explicitly contained in the model.  This is really only practical for small models.  For models with large amounts of data, we would typically want to keep the model separate from the data, given that the data tends to change frequently, while the model does not.  Here is a version of the same model that removes the data, placing it in an external text file, and a calc section has been added to replace the original data section.  The calc section uses @READLN and @READRM to read the data:

MODEL:

! A 3 Warehouse, 4 Customer

  Transportation Problem;

! Illustrates use of the file reading functions:

  @READLN and @READRM;

SETS:

  WAREHOUSE    : CAPACITY;

  CUSTOMER     : DEMAND;

  ROUTES( WAREHOUSE, CUSTOMER) : COST, VOLUME;

ENDSETS

 

CALC:

  !Read 1 line with number of warehouses

    and number of customers;

  NW, NC = @READLN( 'TRANREAD.LDT', 1);

  ! Read NW lines of warehouses;

  WAREHOUSE = @READLN( , NW);

  ! Read NC lines of customers;

  CUSTOMER = @READLN( , NC);

  ! Read cost data up to record

     marker: '~';

  COST = @READRM( , '~');

  ! Read capacities up to

     record marker;

  CAPACITY = @READRM( , '~');

  ! Read demand data up to end-of-file;

  DEMAND   = @READRM();

ENDCALC

 

! The objective;

[OBJ] MIN = @SUM( ROUTES: COST * VOLUME);

 

! The demand constraints;

@FOR( CUSTOMER( J): [DEM]

 @SUM( WAREHOUSE( I): VOLUME( I, J)) >=

  DEMAND( J));

 

! The supply constraints;

@FOR( WAREHOUSE( I): [SUP]

 @SUM( CUSTOMER( J): VOLUME( I, J)) <=

  CAPACITY( I));

 

END

Model: TRANREAD

The data file used for the model is:

3 4  !4 warehouses, 3 customers;

W1   !List of warehouse;

W2

W3

C1   !List of sustomers ;

C2

C3

C4

6  2  6  7

4  9  5  3

8  8  1  5 ~

30 25 21 ~

15 17 22 12

A brief description of the input statements used follows:

First, we have an @READLN that reads one line containing the number of customers and warehouses. Note that we specify the input file name, given that this is the first call to one of the input functions.
Second, now that we know the number of warehouses and customers, we use @READLN to read NW warehouses and another @READLN to read NC customers.  Here, we do not have to specify the file name and are letting it default to the previous name.
Finally, there are three calls to @READRM to read in the cost data, warehouse capacities and customer demands.  The first two calls specify an end-of-record marker (here we use a tilde), but the final call has no record marker specified, meaning we simply read to the end of the file.