Constraint Names

LINGO gives you the ability to name the constraints in your model. This is a good practice for two reasons. First, the constraint names are used in solution reports making them easier to interpret. Secondly, many of LINGO's error messages refer to a given constraint by name. If you don't name your constraints, tracking down the source of these errors may, at best, be difficult.

Note: LINGO does not require you to name your constraints. However, if you do not name your constraints, LINGO defaults to using a name that corresponds to the internal index of the constraint. This internal index may have little to do with the order in which you defined the constraint, thus making the job of interpreting solution reports and error messages difficult. Therefore, it is strongly recommended that you always use constraint names in your models.

Naming a constraint is quite simple. All you need do is insert a name in square brackets at the very start of the constraint. The name must obey the standard requirements for a LINGO name. More specifically, all names must begin with an alphabetic character (A-Z). Subsequent characters may be either alphabetic, numeric (0-9), or the underscore (_). Names may be up to 64 characters in length. Some examples of constraint names follow:

Example 1:        [OBJECTIVE] MIN = X;

assigns the name OBJECTIVE to the model's objective row,

Example 2:        @FOR( CUSTOMERS( J): [DEMAND_ROW]

@SUM( SOURCES( I): SHIP( I, J)) >=

 DEMAND( J));

assigns the name DEMAND_ROW to the demand constraints in a transportation model.

To further illustrate the use of row names, we have updated the WIDGETS model to include constraint names (shown in bold):

MODEL:

! A 6 Warehouse 8 Vendor Transportation Problem;

SETS:

  WAREHOUSES: CAPACITY;

  VENDORS: DEMAND;

  LINKS( WAREHOUSES, VENDORS): COST, VOLUME;

ENDSETS

DATA:

  !set members;

  WAREHOUSES = WH1 WH2 WH3 WH4 WH5 WH6;

  VENDORS = V1 V2 V3 V4 V5 V6 V7 V8;

 

  !attribute values;

  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

! The objective;

  [OBJECTIVE] MIN = @SUM( LINKS( I, J):

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

! The demand constraints;

  @FOR( VENDORS( J): [DEMAND_ROW]

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

    DEMAND( J));

! The capacity constraints;

  @FOR( WAREHOUSES( I): [CAPACITY_ROW]

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

    CAPACITY( I));

END

WIDGETS with Constraint Names

The row section of the solution report is now considerably easier to interpret:

               Row   Slack or Surplus   Dual Price

         OBJECTIVE        664.0000        1.000000

   DEMAND_ROW( V1)       0.0000000       -4.000000

   DEMAND_ROW( V2)       0.0000000       -5.000000

   DEMAND_ROW( V3)       0.0000000       -4.000000

   DEMAND_ROW( V4)       0.0000000       -3.000000

   DEMAND_ROW( V5)       0.0000000       -7.000000

   DEMAND_ROW( V6)       0.0000000       -3.000000

   DEMAND_ROW( V7)       0.0000000       -6.000000

   DEMAND_ROW( V8)       0.0000000       -2.000000

CAPACITY_ROW( WH1)       0.0000000        3.000000

CAPACITY_ROW( WH2)        22.00000        0.000000

CAPACITY_ROW( WH3)       0.0000000        3.000000

CAPACITY_ROW( WH4)       0.0000000        1.000000

CAPACITY_ROW( WH5)       0.0000000        2.000000

CAPACITY_ROW( WH6)       0.0000000        2.000000

Row Report for WIDGETS with Constraint Names

Note that each row now has a name rather than a simple index number. Furthermore, if the constraint is generated over a set using the @FOR function, LINGO qualifies the constraint name by appending the corresponding set member name in parentheses.