Download
language Essence 1.3
$The simplest version of the capacitated vehicle routing problem.
$One depot, multiple drop off locations.
$Set of vehicles with capacity limits, shipping goods  from depot to drop off locations.
$Vehicles make only one trip.
$One order per drop off location.


$locations:
given numberLocations : int(1..)
$one order per location
$ location 0 is depot location 
letting locDomain  be domain int (0..numberLocations) $0 is included as distances from depot is needed
letting plannedLocDomain  be domain int(1..numberLocations)
given orderWeights : function (total) plannedLocDomain --> int(1..)

given costs : function (total)  tuple (locDomain,locDomain) --> int(0..)


$Vehicles 
given vehicleCapacity : int(1..)

$  Maximum total cost is the cost of putting each item onto its own vehicle and driving from depot and back.
letting maxTotalCost be sum([costs((0, i)) | i : plannedLocDomain])*2

letting totalOrderWeight be sum([weight | (_,weight) <- orderWeights])

letting minVehicles be totalOrderWeight / vehicleCapacity + toInt(totalOrderWeight % vehicleCapacity != 0)

find plan : set (minSize minVehicles, maxSize numberLocations) of
                sequence (maxSize numberLocations, injective, minSize 1) of plannedLocDomain

find optVar : int(0..maxTotalCost)
such that
   optVar = sum route in plan . (
                   sum([ costs(tuple(route(i-1), route(i)))
                       | i : int(2..numberLocations),
                       i<=|route|
                       ])
                   + costs((0, route(1)))
                   + costs((route(|route|), 0))
               )

minimising optVar

$add capacity restriction 
such that
forAll route in plan .
    (sum (_,order) in route . orderWeights(order))
    <= vehicleCapacity 

$all orders delivered once
such that
allDiff([loc | route <- plan, (_,loc) <- route]) 
such that
(sum p in plan .
    |p|)
    = numberLocations

$Implied constraint, commented out 
    $ such that
    $ forAll order : plannedLocDomain .
    $     1 = sum([toInt(order = loc) | route <- plan, (_,loc) <- route])