this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Guido Tack <tack@gecode.org> 5 * 6 * Copyright: 7 * Guido Tack, 2004 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/set.hh> 37 38using namespace Gecode; 39 40/** 41 * \brief %Example: %Steiner triples 42 * 43 * See also problem 044 at http://www.csplib.org/. 44 * 45 * \ingroup Example 46 * 47 */ 48class Steiner : public Script { 49public: 50 /// Model variants 51 enum { 52 MODEL_NONE, ///< Use simple relation constraint 53 MODEL_MATCHING, ///< Use matching constraints 54 MODEL_SEQ ///< Use sequence constraints 55 }; 56 /// Order of the Steiner problem 57 int n; 58 /// Number of Steiner triples 59 int noOfTriples; 60 61 /// The steiner triples 62 SetVarArray triples; 63 64 /// Actual model 65 Steiner(const SizeOptions& opt) 66 : Script(opt), n(opt.size()), noOfTriples((n*(n-1))/6), 67 triples(*this, noOfTriples, IntSet::empty, 1, n, 3U, 3U) { 68 69 for (int i=0; i<noOfTriples; i++) { 70 for (int j=i+1; j<noOfTriples; j++) { 71 SetVar x = triples[i]; 72 SetVar y = triples[j]; 73 74 SetVar atmostOne(*this,IntSet::empty,1,n,0U,1U); 75 rel(*this, (x & y) == atmostOne); 76 77 IntVar x1(*this,1,n); 78 IntVar x2(*this,1,n); 79 IntVar x3(*this,1,n); 80 IntVar y1(*this,1,n); 81 IntVar y2(*this,1,n); 82 IntVar y3(*this,1,n); 83 84 if (opt.model() == MODEL_NONE) { 85 /* Naive alternative: 86 * just including the ints in the set 87 */ 88 rel(*this, singleton(x1) <= x); 89 rel(*this, singleton(x2) <= x); 90 rel(*this, singleton(x3) <= x); 91 rel(*this, singleton(y1) <= y); 92 rel(*this, singleton(y2) <= y); 93 rel(*this, singleton(y3) <= y); 94 95 } else if (opt.model() == MODEL_MATCHING) { 96 /* Smart alternative: 97 * Using matching constraints 98 */ 99 100 channelSorted(*this, {x1,x2,x3}, x); 101 channelSorted(*this, {y1,y2,y3}, y); 102 } else if (opt.model() == MODEL_SEQ) { 103 SetVar sx1 = expr(*this, singleton(x1)); 104 SetVar sx2 = expr(*this, singleton(x2)); 105 SetVar sx3 = expr(*this, singleton(x3)); 106 SetVar sy1 = expr(*this, singleton(y1)); 107 SetVar sy2 = expr(*this, singleton(y2)); 108 SetVar sy3 = expr(*this, singleton(y3)); 109 sequence(*this,{sx1,sx2,sx3},x); 110 sequence(*this,{sy1,sy2,sy3},y); 111 } 112 113 /* Breaking symmetries */ 114 rel(*this, x1 < x2); 115 rel(*this, x2 < x3); 116 rel(*this, x1 < x3); 117 118 rel(*this, y1 < y2); 119 rel(*this, y2 < y3); 120 rel(*this, y1 < y3); 121 122 linear(*this, 123 {(n+1)*(n+1), n+1, 1, -(n+1)*(n+1), -(n+1), -1}, 124 {x1, x2, x3, y1, y2, y3}, 125 IRT_LE, 0); 126 } 127 } 128 129 branch(*this, triples, SET_VAR_NONE(), SET_VAL_MIN_INC()); 130 } 131 /// Print solution 132 virtual void 133 print(std::ostream& os) const { 134 for (int i=0; i<noOfTriples; i++) { 135 os << "\t[" << i << "] = " << triples[i] << std::endl; 136 } 137 } 138 /// Constructor for copying \a s 139 Steiner(Steiner& s) : Script(s), n(s.n), noOfTriples(s.noOfTriples) { 140 triples.update(*this, s.triples); 141 } 142 /// Copy during cloning 143 virtual Space* 144 copy(void) { 145 return new Steiner(*this); 146 } 147}; 148 149/** \brief Main-function 150 * \relates Steiner 151 */ 152int 153main(int argc, char* argv[]) { 154 SizeOptions opt("Steiner"); 155 opt.model(Steiner::MODEL_NONE); 156 opt.model(Steiner::MODEL_NONE, "rel", "Use simple relation constraints"); 157 opt.model(Steiner::MODEL_MATCHING, "matching", "Use matching constraints"); 158 opt.model(Steiner::MODEL_SEQ, "sequence", "Use sequence constraints"); 159 opt.size(9); 160 opt.iterations(20); 161 opt.parse(argc,argv); 162 Script::run<Steiner,DFS,SizeOptions>(opt); 163 return 0; 164} 165 166 167// STATISTICS: example-any 168