Using @FILE in a Transportation Model

As an example, we will use the Wireless Widgets transportation model developed in Getting Started with LINGO. It is reproduced its original form below:

! A 6 Warehouse 8 Vendor Transportation Problem;

SETS:

  WAREHOUSES / WH1 WH2 WH3 WH4 WH5 WH6/: CAPACITY;

  VENDORS / V1 V2 V3 V4 V5 V6 V7 V8/   : DEMAND;

  LINKS( WAREHOUSES, VENDORS): COST, VOLUME;

ENDSETS

! The objective;

  MIN = @SUM( LINKS( I, J):

   COST( I, J) * VOLUME( I, J));

! The demand constraints;

  @FOR( VENDORS( J):

   @SUM( WAREHOUSES( I): VOLUME( I, J)) =

    DEMAND( J));

! The capacity constraints;

  @FOR( WAREHOUSES( I):

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

    CAPACITY( I));

! Here is the data;

DATA:

  CAPACITY = 60 55 51 43 41 52;

  DEMAND = 35 37 22 32 41 32 43 38;

  COST = 6 2 6 7 4 2 5 9

         4 9 5 3 8 5 8 2

         5 2 1 9 7 4 3 3

         7 6 7 3 9 2 7 1

         2 3 9 5 7 2 6 5

         5 5 2 2 8 1 4 3;

ENDDATA

Model: WIDGETS

Note that data appears two places in the model. First, there are the lists of warehouses and vendors in the sets section. Second, there is data on capacity, demand, and shipping costs in the data section.

In order to completely isolate the data from our model, we would like to move it to an external text file and modify the model, so it will draw the data from the text file using the @FILE function. The following modified version of the model has all the data removed. Changes are represented in bold type.

! A 6 Warehouse 8 Vendor Transportation Problem;

SETS:

  WAREHOUSES / @FILE( 'WIDGETS2.LDT')/: CAPACITY;

  VENDORS / @FILE( 'WIDGETS2.LDT')/   : DEMAND;

  LINKS( WAREHOUSES, VENDORS): COST, VOLUME;

ENDSETS

! The objective;

  MIN = @SUM( LINKS( I, J):

   COST( I, J) * VOLUME( I, J));

! The demand constraints;

  @FOR( VENDORS( J):

   @SUM( WAREHOUSES( I): VOLUME( I, J)) =

    DEMAND( J));

! The capacity constraints;

  @FOR( WAREHOUSES( I):

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

    CAPACITY( I));

! Here is the data;

DATA:

  CAPACITY = @FILE( 'WIDGETS2.LDT');

  DEMAND = @FILE( 'WIDGETS2.LDT');

  COST = @FILE( 'WIDGETS2.LDT');

ENDDATA

Model: WIDGETS2

The model is now set to draw all data from the file WIDGETS2.LDT. The contents of this data file appear below:

!List of warehouses;

WH1 WH2 WH3 WH4 WH5 WH6 ~

 

!List of vendors;

V1 V2 V3 V4 V5 V6 V7 V8 ~

 

!Warehouse capacities;

60 55 51 43 41 52 ~

 

!Vendor requirements;

35 37 22 32 41 32 43 38 ~

 

!Unit shipping costs;

6 2 6 7 4 2 5 9

4 9 5 3 8 5 8 2

5 2 1 9 7 4 3 3

7 6 7 3 9 2 7 1

2 3 9 5 7 2 6 5

5 5 2 2 8 1 4 3

File: WIDGETS2.LDT

Note:        We use the convention of placing the extension of .LDT on all LINGO data files.

Sections of the data file between end-of-record marks (~) are called records. If an included file has no end-of-record marks, LINGO reads the whole file as a single record. Notice that, with the exception of the end-of-record marks, the model text and data appear just as they would if they were in the model itself.

Also, notice how the end-of-record marks in the include file work along with the @FILE function calls in the model. The first call to @FILE opens WIDGETS2.LDT and includes the first record. The second call includes the second record, and so on.

The last record in the file does not need an end-of-record mark. When LINGO encounters an end-of-file, it includes the last record and closes the file. If you end the last record in an include file with an end-of-record mark, LINGO will not close the file until it is done solving the current model. This could cause problems if multiple data files are opened in the model—files that remain open can cause the limit on open files to be exceeded.

When using the @FILE function, think of the contents of the record (except for any end-of-record mark) as replacing the text @FILE( 'filename') in the model. This way, you can include a whole statement, part of a statement, or a whole series of statements in a record. For example, the first two records of the WIDGETS2.LDT file in the above example:

!List of warehouses;

WH1 WH2 WH3 WH4 WH5 WH6 ~

 

!List of vendors;

V1 V2 V3 V4 V5 V6 V7 V8 ~

are included in the model in the sets section as follows:

WAREHOUSES / @FILE( 'WIDGETS2.LDT')/: CAPACITY;

VENDORS / @FILE( 'WIDGETS2.LDT')/   : DEMAND;

The net effect of these @FILE calls is to turn the model statements into:

WAREHOUSES / WH1 WH2 WH3 WH4 WH5 WH6/: CAPACITY;

VENDORS / V1 V2 V3 V4 V5 V6 V7 V8/   : DEMAND;

Comments in the include file are ignored. The maximum number of include files a model can simultaneously reference is 16.