! Container routing problem in LINGO;
! We are given a
+ number of units that must be shipped from i to j each period,
+ the lead time to ship from i to j,
+ the capacity of the containers that carry the units to be shipped.
The containers must satisfy conservation of flow as they move
about the system, i.e., they cannot be created or destroyed,
except in period 1 in which we insert as many containers as
we wish at each city. A container may physically correspond to
whatever the user wishes, e.g., actual containers, trucks,
railroad cars, airplanes, etc.
This is a discrete time model where the unit of time is
called a "period". A period could be a hour, a half day,
a day, etc., whatever the user decides. The model need not
know what unit of time the user chose, as long as the user
is consistent.
A crucial piece of input data is the travel time matrix.
It is a matrix of integers specifying how many periods it takes
a container to be moved from one city to another.
A variety of objectives are possible. Below we choose
the objective of minimizing the number of containers needed
in total;
! Keywords: Routing, Container routing, Lead times;
SETS:
PERIOD;
CITY: CINIT;
CXC( CITY, CITY): LT;
CXCDM( CITY, CITY, PERIOD): DM;
CXCXP( CITY, CITY, PERIOD): XC;
ENDSETS DATA:
CONCAP = 22; ! Container capacity;
PERIOD = 1..6; ! Number of periods we are modeling in this run;
CITY = C1 C2 C3 C4; ! Names of the cities;
LT = 1 2 2 3 ! Travel time matrix in periods;
2 1 4 2
2 4 1 3
3 2 3 1 ;
! Set of demands to be carried, in the form:
From_city, To_city, Period_to_start_Shipment, Units_to_ship;
CXCDM DM =
C1 C2 1 20
C1 C3 2 31
C1 C4 3 25
C3 C2 1 17
C4 C1 2 18
;
ENDDATA
! Parameters:
LT(i,j) = number of periods to move a container from i to j,
DM(i,j,t) = number of units of goods that need to be moved
from i to j, starting at i in period t,
;
! Variables:
XC(i,j,t) = number of containers moved from i to j
starting at i in period t,
CINIT(i) = number of containers initially at i,
;
SUBMODEL MOVEM:
! Minimize the number of containers we need to insert in
system at beginning;
[OBJ] MIN = @SUM( CITY( i): CINIT(i));
! Conservation of flow for containers,
for every city k in every period t, the number
of containers arriving must equal the number
of containers departing. Note that the
"departure" XC(i,k,t), where k = i, corresponds
to the container staying at i in period t;
@FOR( CITY(k):
! Period 1 is special;
[CONFLO1] CINIT(k) = @SUM( CITY(j): XC(k,j,1));
! For periods > 1;
@FOR( PERIOD(t)  t #GT# 1:
! Incoming containers = outgoing;
[CONFLO] @SUM( CXCXP( i, k, t1)  t1 + LT(i,k) #EQ# t: XC(i,k,t1))
= @SUM( CITY(J): XC(k,j,t));
);
);
! For each shipment we must make, we must assign enough containers,
i.e., container_capacity*number_containers >= units_to_be_carried;
@FOR( CXCDM( i,j,t):
[CAP] CONCAP*XC(i,j,t) >= DM(i,j,t);
);
! Containers moved must be integral;
@FOR( CXCXP(i,j,t): @GIN( XC(i,j,t)));
ENDSUBMODEL
CALC:
@SET( 'TERSEO', 2); ! Set output level to really terse;
@SOLVE( MOVEM); ! Solve the submodel;
! Write a little report;
@WRITE(' Solution to the container routing problem.', @NEWLINE(1));
@WRITE(' Number containers needed = ', @SUM(CITY(i): CINIT(i)), @NEWLINE(1));
@WRITE(' Initial allocations are: ', @NEWLINE(1));
@FOR( CITY(i)  CINIT(i) #GT# .5:
@WRITE(' ',CITY(i),' ', CINIT(i), @NEWLINE(1));
);
@WRITE(@NEWLINE(1),' The container movements are: ', @NEWLINE(1),
' Period From To No. containers', @NEWLINE(1));
@FOR( PERIOD(t):
@FOR( CXCXP(i,j,t)  XC(i,j,t) #GT# .5:
@WRITE( ' ',@FORMAT(t,'3.0f'),' ', CITY(i),' ', CITY(j),' ',
@FORMAT(XC(i,j,t),'4.0f'), @NEWLINE(1));
);
);
! Optionally, generate an explicit display of the model;
! @WRITE( @NEWLINE(2), ' Here is the explicit model:', @NEWLINE(1));
! @GEN( MOVEM);
ENDCALC
