FICO Xpress Optimization Examples Repository
 FICO Optimization Community FICO Xpress Optimization Home

Ground transport

Description
E‑1 E‑2 E‑3 Problem name and type, features Difficulty Car rental: Transport problem *** data preprocessing, set operations, sqrt and ^2, if-then-elif Choosing the mode of transport: Minimum cost flow ** formulation with extra nodes for modes of transport; encoding of arcs, finalize, union of sets, nodes labeled with strings Depot location: Facility location problem *** modeling flows as fractions, definition of model cuts Heating oil delivery: Vehicle routing problem (VRP) **** elimination of inadmissible subtours, cuts; selection with `|', definition of model cuts Combining different modes of transport *** modeling implications, weak and strong formulation of bounding constraints; triple indices Fleet planning for vans *** maxlist, minlist, max, min

Further explanation of this example: 'Applications of optimization with Xpress-MP', Chapter 10: Ground transport

Source Files

Data Files

e4deliver.mos

```(!******************************************************
Mosel Example Problems
======================

file e4deliver.mos
``````````````````
Heating oil delivery (Traveling Salesman Problem)

(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002
*******************************************************!)

model "E-4 Oil delivery"
uses "mmxprs"

declarations
NS = 7
SITES = 1..NS                       ! Set of locations, 1=refinery
CLIENTS = 2..NS

DEM: array(SITES) of integer        ! Demands
DIST: array(SITES,SITES) of integer ! Distances between locations
CAP: integer                        ! Lorry capacity

prec: array(SITES,SITES) of mpvar   ! 1 if i immediately precedes j,
! 0 otherwise
quant: array(CLIENTS) of mpvar      ! Quantity delivered up to i
end-declarations

initializations from 'e4deliver.dat'
DEM DIST CAP
end-initializations

! Objective: total distance driven
Length:= sum(i,j in SITES | i<>j) DIST(i,j)*prec(i,j)

! Enter and leave every city only once (except the depot)
forall(j in CLIENTS) sum(i in SITES| i<>j) prec(i,j) = 1
forall(i in CLIENTS) sum(j in SITES| i<>j) prec(i,j) = 1

! If i is the first client of a tour, then quant(i)=DEM(i)
forall(i in CLIENTS) quant(i) <= CAP + (DEM(i)-CAP)*prec(1,i)

! If j comes just after i in a tour, then quant(j) is greater than the
! quantity delivered during the tour up to i plus the quantity to be
! delivered at j (to avoid loops and keep capacity limit of the tanker)
forall(i,j in CLIENTS| i<>j) quant(j) >= quant(i) + DEM(j) - CAP +
CAP*prec(i,j) + (CAP-DEM(j)-DEM(i))*prec(j,i)

! If i is not the first client of a tour, quant(i) is larger than the sum
! of the quantities to deliver to i and to his predecessor on the tour
(!
declarations
modcut: array(CLIENTS) of linctr
end-declarations

forall(i in CLIENTS) do
modcut(i):= quant(i) >= DEM(i) + sum(j in SITES| i<>j) DEM(j)*prec(j,i)
setmodcut(modcut(i))
end-do
!)

forall(i in CLIENTS) do
quant(i) <= CAP
quant(i) >= DEM(i)
end-do

forall(i,j in SITES | i<>j) prec(i,j) is_binary

! Uncomment the following line to see the Optimizer log
! setparam("XPRS_VERBOSE",true)

! Solve the problem
minimize(Length)

! Solution printing
writeln("Total distance: ", getobjval)
forall(i in CLIENTS)
if(getsol(prec(1,i))>0) then
ct:=DEM(i)
writeln(1, " -> ", i)
p:=i
while(p<>1) do
n:= integer(round(sum(j in SITES) j*getsol(prec(p,j))))
writeln(p, " -> ", n)
ct+=DEM(n)
p:=n
end-do
writeln("Quantity delivered: ", ct)
end-if

end-model

```