this repo has no description
at develop 4.9 kB view raw
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Copyright: 7 * Christian Schulte, 2011 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#include <gecode/driver.hh> 35#include <gecode/int.hh> 36#include <gecode/minimodel.hh> 37 38using namespace Gecode; 39 40/** 41 * \brief %Example: Dominating Queens 42 * 43 * Place a number of queens on a n times n chessboard such that 44 * each squares is either attacked or occupied by a queen. 45 * 46 * The model is taken from: C. Bessiere, E. Hebrard, B. Hnich, 47 * Z. Kiziltan, and T. Walsh, Filtering Algorithms for the NValue 48 * Constraint, Constraints, 11(4), 271-293, 2006. 49 * 50 * \ingroup Example 51 * 52 */ 53class DominatingQueens : public IntMinimizeScript { 54protected: 55 /// Size of the board 56 const int n; 57 /// Fields on the board 58 IntVarArray b; 59 /// Number of queens 60 IntVar q; 61 /// Compute coordinate pair from \a x and \a y 62 int xy(int x, int y) const { 63 return y*n + x; 64 } 65 /// Compute x coordinate from pair \a xy 66 int x(int xy) const { 67 return xy % n; 68 } 69 /// Compute y coordinate from pair \a xy 70 int y(int xy) const { 71 return xy / n; 72 } 73 /// Compute set of fields that can be attacked by \a xy 74 IntSet attacked(int xy) { 75 IntArgs a; 76 for (int i=0; i<n; i++) 77 for (int j=0; j<n; j++) 78 if ((i == x(xy)) || // Same row 79 (j == y(xy)) || // Same column 80 (abs(i-x(xy)) == abs(j-y(xy)))) // Same diagonal 81 a << DominatingQueens::xy(i,j); 82 return IntSet(a); 83 } 84public: 85 /// The actual problem 86 DominatingQueens(const SizeOptions& opt) 87 : IntMinimizeScript(opt), 88 n(opt.size()), b(*this,n*n,0,n*n-1), q(*this,1,n) { 89 90 // Constrain field to the fields that can attack a field 91 for (int i=0; i<n*n; i++) 92 dom(*this, b[i], attacked(i)); 93 94 // At most q queens can be placed 95 nvalues(*this, b, IRT_LQ, q); 96 97 /* 98 * According to: P. R. J. Östergard and W. D. Weakley, Values 99 * of Domination Numbers of the Queen's Graph, Electronic Journal 100 * of Combinatorics, 8:1-19, 2001, for n <= 120, the minimal number 101 * of queens is either ceil(n/2) or ceil(n/2 + 1). 102 */ 103 if (n <= 120) 104 dom(*this, q, (n+1)/2, (n+1)/2 + 1); 105 106 branch(*this, b, INT_VAR_SIZE_MIN(), INT_VAL_MIN()); 107 // Try the easier solution first 108 branch(*this, q, INT_VAL_MAX()); 109 } 110 111 /// Return cost 112 virtual IntVar cost(void) const { 113 return q; 114 } 115 116 /// Constructor for cloning \a s 117 DominatingQueens(DominatingQueens& s) 118 : IntMinimizeScript(s), n(s.n) { 119 b.update(*this, s.b); 120 q.update(*this, s.q); 121 } 122 123 /// Perform copying during cloning 124 virtual Space* 125 copy(void) { 126 return new DominatingQueens(*this); 127 } 128 129 /// Print solution 130 virtual void 131 print(std::ostream& os) const { 132 os << "\tNumber of Queens: " << q << std::endl; 133 os << "\tBoard: " << b << std::endl; 134 if (b.assigned()) { 135 // Print a nice board 136 bool* placed = new bool[n*n]; 137 for (int i=0; i<n*n; i++) 138 placed[i] = false; 139 for (int i=0; i<n*n; i++) 140 placed[b[i].val()] = true; 141 for (int j=0; j<n; j++) { 142 std::cout << "\t\t"; 143 for (int i=0; i<n; i++) 144 std::cout << (placed[xy(i,j)] ? 'Q' : '.') << ' '; 145 std::cout << std::endl; 146 } 147 delete [] placed; 148 } 149 os << std::endl; 150 } 151}; 152 153/** \brief Main-function 154 * \relates DominatingQueens 155 */ 156int 157main(int argc, char* argv[]) { 158 SizeOptions opt("DominatingQueens"); 159 opt.size(7); 160 opt.solutions(0); 161 opt.parse(argc,argv); 162 IntMinimizeScript::run<DominatingQueens,BAB,SizeOptions>(opt); 163 return 0; 164} 165 166// STATISTICS: example-any 167