From 21b86ea823b6aab3e59c0b8932c6d3649c09ccde Mon Sep 17 00:00:00 2001 From: David Tonhofer Date: Wed, 21 Jul 2021 17:04:06 +0200 Subject: [PATCH] bandits.mzn adapted to what's in the slides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduced SIZE and POINT as used on the slides. Changed comments for clarity: "points" ↔ "tunnel exits" and "cells" ↔ "huts" Changed i,j, to x,y in forall to correspond to predicate call Added symmetry-breaking constraint to make the solution canonical. With Gecode: Row: [2, 7, 7] Col: [5, 2, 8] Cost: 19 ---------- Row: [3, 5, 7] Col: [6, 2, 6] Cost: 18 ---------- ========== Finished in 325msec --- predicates/bandits/bandits.mzn | 41 +++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/predicates/bandits/bandits.mzn b/predicates/bandits/bandits.mzn index ac3e026..1ceb84f 100644 --- a/predicates/bandits/bandits.mzn +++ b/predicates/bandits/bandits.mzn @@ -1,33 +1,42 @@ include "globals.mzn"; int: size; +set of int: SIZE = 1..size; + int: nPts; +set of int: POINT = 1..nPts; + int: mDist; -array[1..size,1..size] of int: cost; +array[SIZE,SIZE] of int: cost; -array[1..nPts] of var 1..size: ptR; -array[1..nPts] of var 1..size: ptC; +array[POINT] of var SIZE: ptR; +array[POINT] of var SIZE: ptC; -% all points different -constraint let {array [1..nPts] of var 1..size*size: points = - [(ptR[i]-1)*size + ptC[i] | i in 1..nPts]} in +% all tunnel exits must be different +constraint let { array [POINT] of var 1..size*size: points = + [(ptR[i]-1)*size + ptC[i] | i in POINT] } in alldifferent(points); -% diggable spots -%constraint forall(i in 1..nPts)(not((ptR[i] mod 2) = 0 /\ (ptC[i] mod 2) = 0)); -constraint forall(i in 1..nPts)((ptR[i] mod 2) = 1 \/ (ptC[i] mod 2) = 1); +% all tunnel exits must be diggable +%constraint forall(i in POINT)(not((ptR[i] mod 2) = 0 /\ (ptC[i] mod 2) = 0)); +constraint forall(i in POINT)((ptR[i] mod 2) = 1 \/ (ptC[i] mod 2) = 1); -% all cells covered +% a hut at (x,y) must be within mDist Manhattan Distance of some tunnel exit predicate covered(var int: x, var int: y) = - let {var 1..nPts: i, - var int: dist = abs(x-ptR[i]) + abs(y-ptC[i])} in + let {var POINT: i, + var int: dist = abs(x-ptR[i]) + abs(y-ptC[i])} in dist <= mDist; -constraint let {array [1..(size div 2)] of 1..size-1: - huts = [i*2|i in 1..(size div 2)]} in - forall(i,j in huts)(covered(i,j)); -var int: tCost = sum(i in 1..nPts)(cost[ptR[i],ptC[i]]); +% huts is a 1-D array of hut coords along one axis +constraint let {array [1..(size div 2)] of 1..size-1: huts = + [i*2|i in 1..(size div 2)]} in + forall(x,y in huts)(covered(x,y)); + +% Break symmetry by demanding that tunnel exit points have a canonical ordering +constraint forall(i in 1..nPts-1)(ptR[i]*size+ptC[i] < ptR[i+1]*size+ptC[i+1]); + +var int: tCost = sum(i in POINT)(cost[ptR[i],ptC[i]]); solve minimize tCost; output["Row: \(ptR)\nCol: \(ptC)\nCost: \(tCost)"];