1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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 . (allocation[tank] = 0)) such that $ volumeToShip of cargo X <= amount of cargo X included in allocation forAll cargo : dCargos . ( sum tank : dTanks . capacities[tank] * (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) |