language Essence 1.3

$Problem Tank Allocation$
$Problem details available at http://www.csplib.org/Problems/prob051/$
$Essence model by Andrew Martin$
$Licenced under CC-BY-4.0 : http://creativecommons.org/licenses/by/4.0/$ SIMPLIFICATIONS -
$rather than tracking invividual volumes in each tank,$ sum all available volume available
$this must be >= the volume to ship$
$this prevents solver checking every permutaion with$ the same tank allocation but different levels

$letting numCargos be 1 currently breaks savillerow when parsing incompatabilities$ constraining to >=2
given numCargos : int(2..)

given numTanks : int(1..)

letting dCargos be domain int(1..numCargos)
letting dAllCargos be domain int(0..numCargos)
letting dTanks be domain int(1..numTanks)

given capacities : matrix indexed by [dTanks] of int(1..)

given neighbours : matrix indexed by [dTanks] of set of dTanks

given impossibleCargos : matrix indexed by [dTanks] of set of dAllCargos

given volumeToShip : matrix indexed by [dCargos] of int(1..)

given incompatibilities : set of set (size 2) of dCargos

$a tank can contain one cargo type or it can be empty (cargo 0) find allocation : matrix indexed by [dTanks] of dAllCargos$ maximising number of empty tanks
maximising (sum tank : dTanks . toInt(allocation[tank] = 0))

such that

$volumeToShip of cargo X <= amount of cargo X included in allocation forAll cargo : dCargos . (sum tank : dTanks . capacities[tank] * toInt(allocation[tank] = cargo) ) >= volumeToShip[cargo] such that$ no tank can be allocated a cargo in its impossibleCargos
forAll tank : dTanks .
!(allocation[tank] in impossibleCargos[tank])

/\

\$ no tank can be neigbors with a tank containing incompatible cargo
forAll neighbour in neighbours[tank] .
!({allocation[tank], allocation[neighbour]} in incompatibilities)