this repo has no description
at develop 3.9 kB view raw
1% battleships.mzn.model 2% Ralph Becket <rafe@csse.unimelb.edu.au> 3% Wed Dec 10 13:51:12 EST 2008 4% vim: ft=zinc ts=4 sw=4 et tw=0 5% 6% A battleships puzzle involves working out where each of a fleet of ships 7% lies on a square grid. Clues are given in two ways: some parts of the 8% grid may be revealed as containing open water or part of a ship; and the 9% total number of parts of ships appearing in a row or column may also be 10% specified. Individual ships are always surrounded by open water, even 11% at the corners. 12% 13% The following example is taken from 14% http://wpc.puzzles.com/history/tests/1999qtest/test.htm 15% 16% w _ _ _ _ w _ _ _ 2 Fleet: 17% S w _ _ _ _ _ _ _ 2 1 battleship SSSS 18% _ _ _ _ _ _ _ _ _ 3 2 cruisers SSS SSS 19% w _ _ _ _ _ _ w _ 2 3 destroyers SS SS SS 20% _ _ _ _ _ _ _ _ _ 2 4 submarines S S S S 21% _ w S w _ _ _ _ _ 1 22% _ _ w _ _ _ _ S _ 5 23% _ _ _ _ _ _ _ _ _ 1 24% _ _ _ _ _ _ _ _ _ 2 25% 26% 4 0 3 2 2 2 1 4 2 27% 28% In this model, each square on the grid is a number from 0..4 29% (0 being water, 4 denoting the bows of a battleship). A Cruiser, 30% for instance, is described by a contiguous pattern 0 1 2 3 0 on 31% the board. Consider the following neighbourhood: 32% 33% a b c 34% d x e 35% f g h 36% 37% Precisely one of the following must hold: 38% - x is 0 39% - x is b + 1 and d = e = 0 40% - x is d + 1 and b = g = 0 41% 42% We also need to specify constraints on diagonally adjacent squares: 43% - if x < b then d = e = 0 44% - if x < d then b = g = 0 45% 46% The column (row) constraints specify how many non-zero elements a 47% column (row) must have. 48% 49% The fleet constraints specify how many instances of each positive number 50% must appear on the board. 51 52include "count.mzn"; 53 54% Parameter: the length of side of the grid. 55% 56int: n; 57 58% Parameter: the number of ships of each class. 59% 60int: n_classes; 61set of int: class = 1..n_classes; 62array [class] of int: class_sizes; 63 64set of int: sq = {0} union class; 65 66% The row and column sums. 67% 68array [row] of var 0..n: row_sums; 69array [col] of var 0..n: col_sums; 70 71% We extend the board by one in each direction to add a sea border. 72% 73set of int: row = 1..n; 74set of int: col = 1..n; 75set of int: ROW = 0..(n + 1); 76set of int: COL = 0..(n + 1); 77array [ROW, COL] of var sq: a; 78 79% Add the sea border to the board. 80% 81constraint forall (r in {0, n + 1}, c in COL) (a[r, c] = 0); 82constraint forall (r in ROW, c in {0, n + 1}) (a[r, c] = 0); 83 84% Add the ship constraints. 85% 86constraint 87 forall (r in row, c in col) ( 88 ( 89 a[r, c] = 0 90 ) 91 \/ 92 ( 93 a[r, c] = a[r, c - 1] + 1 94 /\ a[r - 1, c] = 0 95 /\ a[r + 1, c] = 0 96 ) 97 \/ 98 ( 99 a[r, c] = a[r - 1, c] + 1 100 /\ a[r, c - 1] = 0 101 /\ a[r, c + 1] = 0 102 ) 103 ); 104 105% Add the diagonal constraints. 106% 107constraint 108 forall (r in row, c in col) ( 109 ( 110 a[r, c] < a[r, c - 1] 111 ) 112 -> 113 ( 114 a[r - 1, c] = 0 115 /\ a[r + 1, c] = 0 116 ) 117 ); 118 119constraint 120 forall (r in row, c in col) ( 121 ( 122 a[r, c] < a[r - 1, c] 123 ) 124 -> 125 ( 126 a[r, c - 1] = 0 127 /\ a[r, c + 1] = 0 128 ) 129 ); 130 131% Add the row and column constraints. 132% 133constraint 134 forall (r in row) (count([a[r, c] | c in col], 0, n - row_sums[r])); 135 136constraint 137 forall (c in col) (count([a[r, c] | r in row], 0, n - col_sums[c])); 138 139% Add the fleet constraints (a_flat is the 1D flattenning of the board, a). 140% 141array [1..(n * n)] of var sq: a_flat = [a[r, c] | r in row, c in col]; 142 143constraint 144 forall (s in class) ( 145 count(a_flat, s, sum (i in class where i >= s) (class_sizes[i])) 146 ); 147 148solve 149 :: int_search(a_flat, first_fail, indomain_max, complete) 150 satisfy; 151 152output [ show(a[r, c]) ++ if c = n then "\n" else " " endif 153 | r in row, c in col 154 ]; 155