this repo has no description
at develop 4.1 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, 2001 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: Magic squares 42 * 43 * Compute magic squares of arbitrary size 44 * 45 * See problem 19 at http://www.csplib.org/. 46 * 47 * \ingroup Example 48 * 49 */ 50class MagicSquare : public Script { 51private: 52 /// Size of magic square 53 const int n; 54 /// Fields of square 55 IntVarArray x; 56 57public: 58 /// Branching to use for model 59 enum { 60 BRANCH_SIZE, ///< Branch by size 61 BRANCH_AFC_SIZE ///< Branch by size over AFC 62 }; 63 /// Post constraints 64 MagicSquare(const SizeOptions& opt) 65 : Script(opt), n(opt.size()), x(*this,n*n,1,n*n) { 66 // Number of fields on square 67 const int nn = n*n; 68 69 // Sum of all a row, column, or diagonal 70 const int s = nn*(nn+1) / (2*n); 71 72 // Matrix-wrapper for the square 73 Matrix<IntVarArray> m(x, n, n); 74 75 for (int i = n; i--; ) { 76 linear(*this, m.row(i), IRT_EQ, s, opt.ipl()); 77 linear(*this, m.col(i), IRT_EQ, s, opt.ipl()); 78 } 79 // Both diagonals must have sum s 80 { 81 IntVarArgs d1y(n); 82 IntVarArgs d2y(n); 83 for (int i = n; i--; ) { 84 d1y[i] = m(i,i); 85 d2y[i] = m(n-i-1,i); 86 } 87 linear(*this, d1y, IRT_EQ, s, opt.ipl()); 88 linear(*this, d2y, IRT_EQ, s, opt.ipl()); 89 } 90 91 // All fields must be distinct 92 distinct(*this, x, opt.ipl()); 93 94 // Break some (few) symmetries 95 rel(*this, m(0,0), IRT_GR, m(0,n-1)); 96 rel(*this, m(0,0), IRT_GR, m(n-1,0)); 97 98 switch (opt.branching()) { 99 case BRANCH_SIZE: 100 branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_SPLIT_MIN()); 101 break; 102 case BRANCH_AFC_SIZE: 103 branch(*this, x, INT_VAR_AFC_SIZE_MAX(opt.decay()), INT_VAL_SPLIT_MIN()); 104 break; 105 } 106 } 107 108 /// Constructor for cloning \a s 109 MagicSquare(MagicSquare& s) : Script(s), n(s.n) { 110 x.update(*this, s.x); 111 } 112 113 /// Copy during cloning 114 virtual Space* 115 copy(void) { 116 return new MagicSquare(*this); 117 } 118 /// Print solution 119 virtual void 120 print(std::ostream& os) const { 121 // Matrix-wrapper for the square 122 Matrix<IntVarArray> m(x, n, n); 123 for (int i = 0; i<n; i++) { 124 os << "\t"; 125 for (int j = 0; j<n; j++) { 126 os.width(2); 127 os << m(i,j) << " "; 128 } 129 os << std::endl; 130 } 131 } 132 133}; 134 135/** \brief Main-function 136 * \relates MagicSquare 137 */ 138int 139main(int argc, char* argv[]) { 140 SizeOptions opt("MagicSquare"); 141 opt.iterations(1); 142 opt.size(7); 143 opt.branching(MagicSquare::BRANCH_SIZE); 144 opt.branching(MagicSquare::BRANCH_SIZE, "size"); 145 opt.branching(MagicSquare::BRANCH_AFC_SIZE, "afc-size"); 146 opt.parse(argc,argv); 147 Script::run<MagicSquare,DFS,SizeOptions>(opt); 148 return 0; 149} 150 151// STATISTICS: example-any 152