this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * Guido Tack <tack@gecode.org> 6 * 7 * Contributing authors: 8 * Gabor Szokoli <szokoli@gecode.org> 9 * 10 * Copyright: 11 * Christian Schulte, 2002 12 * Guido Tack, 2004 13 * Gabor Szokoli, 2003 14 * 15 * This file is part of Gecode, the generic constraint 16 * development environment: 17 * http://www.gecode.org 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining 20 * a copy of this software and associated documentation files (the 21 * "Software"), to deal in the Software without restriction, including 22 * without limitation the rights to use, copy, modify, merge, publish, 23 * distribute, sublicense, and/or sell copies of the Software, and to 24 * permit persons to whom the Software is furnished to do so, subject to 25 * the following conditions: 26 * 27 * The above copyright notice and this permission notice shall be 28 * included in all copies or substantial portions of the Software. 29 * 30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 * 38 */ 39 40#ifndef GECODE_INT_DISTINCT_HH 41#define GECODE_INT_DISTINCT_HH 42 43#include <gecode/int.hh> 44 45#include <gecode/int/view-val-graph.hh> 46#include <gecode/int/rel.hh> 47 48/** 49 * \namespace Gecode::Int::Distinct 50 * \brief %Distinct propagators 51 */ 52 53namespace Gecode { namespace Int { namespace Distinct { 54 55 /** 56 * \brief Naive value distinct propagator 57 * 58 * Eliminates values of assigned views of type \a View. 59 * 60 * Requires \code #include <gecode/int/distinct.hh> \endcode 61 * \ingroup FuncIntProp 62 */ 63 template<class View> 64 class Val : public NaryPropagator<View,PC_INT_VAL> { 65 protected: 66 using NaryPropagator<View,PC_INT_VAL>::x; 67 68 /// Constructor for posting 69 Val(Home home, ViewArray<View>& x); 70 /// Constructor for cloning \a p 71 Val(Space& home, Val<View>& p); 72 public: 73#ifdef GECODE_HAS_CBS 74 /// Solution distribution computation for branching 75 virtual void solndistrib(Space& home, Propagator::SendMarginal send) const; 76 /// Sum of variables cardinalities 77 virtual void domainsizesum(Propagator::InDecision in, 78 unsigned int& size, unsigned int& size_b) const; 79#endif 80 /// Copy propagator during cloning 81 virtual Actor* copy(Space& home); 82 /// Perform propagation 83 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 84 /// Post propagator for view array \a x 85 static ExecStatus post(Home home, ViewArray<View>& x); 86 }; 87 88#ifdef GECODE_HAS_CBS 89 /** 90 * \brief Solution distribution computation for the AllDifferent constraint 91 * 92 * The algorithm is taken from: 93 * Gagnon, Samuel & Pesant, Gilles. (2018). 94 * Accelerating Counting-Based Search. 95 * In book: Integration of Constraint Programming, 96 * Artificial Intelligence, and Operations Research, pp.245-253 97 * Available at http://www.polymtl.ca/labo-quosseca/en/publications 98 */ 99 template<class View> 100 void cbsdistinct(Space& home, unsigned int prop_id, const ViewArray<View>& x, 101 Propagator::SendMarginal send); 102 103 template<class View> 104 void cbssize(const ViewArray<View>& x, Propagator::InDecision in, 105 unsigned int& size, unsigned int& size_b); 106#endif 107 108 /** 109 * \brief Eliminate singletons by naive value propagation 110 * 111 * This is actually the propagation algorithm for Distinct::Val. 112 * It is available as separate function as it is reused for 113 * both bounds consistent and domain consistent distinct 114 * propagators. 115 * 116 * If \a complete is true, computes fixpoint, otherwise might not 117 * compute fixpoint. This can be helpful when used together with 118 * bounds or domain propagation to protect from pathological cases 119 * which can be handled more efficiently with bounds propagation. 120 */ 121 template<class View, bool complete> 122 ExecStatus prop_val(Space& home, ViewArray<View>&); 123 124 125 126 /** 127 * \brief Bounds consistent distinct propagator 128 * 129 * The propagator uses staging: first it uses naive value-based 130 * propagation and only then uses bounds consistent propagation. 131 * Due to using naive value-based propagation, the propagator 132 * might actually achieve stronger consistency than just 133 * bounds consistency. 134 * 135 * The algorithm is taken from: 136 * A. Lopez-Ortiz, C.-G. Quimper, J. Tromp, and P. van Beek. 137 * A fast and simple algorithm for bounds consistency of the 138 * alldifferent constraint. IJCAI-2003. 139 * 140 * This implementation uses the code that is provided by 141 * Peter Van Beek: 142 * http://ai.uwaterloo.ca/~vanbeek/software/software.html 143 * The code (originally by John Tromp) here has only been slightly modified 144 * to fit %Gecode (taking idempotent/non-idempotent propagation into account) 145 * and uses a more efficient layout of datastructures (keeping the number 146 * of different arrays small). 147 * 148 * Requires \code #include <gecode/int/distinct.hh> \endcode 149 * \ingroup FuncIntProp 150 */ 151 template<class View> 152 class Bnd : public Propagator { 153 protected: 154 /// Views on which to perform bounds-propagation 155 ViewArray<View> x; 156 /// Views on which to perform value-propagation (subset of \c x) 157 ViewArray<View> y; 158 /// Minimum (approximation) of view in \a x 159 int min_x; 160 /// Maximum (approximation) of view in \a x 161 int max_x; 162 /// Constructor for posting 163 Bnd(Home home, ViewArray<View>& x); 164 /// Constructor for cloning \a p 165 Bnd(Space& home, Bnd<View>& p); 166 public: 167#ifdef GECODE_HAS_CBS 168 /// Solution distribution computation for branching 169 virtual void solndistrib(Space& home, Propagator::SendMarginal send) const; 170 /// Sum of variables cardinalities 171 virtual void domainsizesum(Propagator::InDecision in, 172 unsigned int& size, unsigned int& size_b) const; 173#endif 174 /// Post propagator for view array \a x 175 static ExecStatus post(Home home, ViewArray<View>& x); 176 /// Perform propagation 177 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 178 /** 179 * \brief Cost function 180 * 181 * If in stage for naive value propagation, the cost is 182 * low linear. Otherwise it is low quadratic. 183 */ 184 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 185 /// Schedule function 186 virtual void reschedule(Space& home); 187 /// Copy propagator during cloning 188 virtual Actor* copy(Space& home); 189 /// Destructor 190 virtual size_t dispose(Space& home); 191 }; 192 193 /** 194 * \brief Perform bounds consistent distinct propagation 195 * 196 * This is actually the propagation algorithm for Distinct::Bnd. 197 * It is available as separate function as it is reused for 198 * both bounds consistent and domain consistent distinct 199 * propagators. 200 */ 201 template<class View> 202 ExecStatus prop_bnd(Space& home, ViewArray<View>& x, int& min_x, int& max_x); 203 204 /** 205 * \brief Perform bounds consistent distinct propagation 206 * 207 * This is actually the propagation algorithm for Distinct::Bnd. 208 * It is available as separate function as it is reused for 209 * both bounds consistent and domain consistent distinct 210 * propagators. 211 */ 212 template<class View> 213 ExecStatus prop_bnd(Space& home, ViewArray<View>& x); 214 215 216 /// View-value graph for propagation 217 template<class View> 218 class Graph : public ViewValGraph::Graph<View> { 219 public: 220 using ViewValGraph::Graph<View>::view; 221 using ViewValGraph::Graph<View>::n_view; 222 using ViewValGraph::Graph<View>::val; 223 using ViewValGraph::Graph<View>::n_val; 224 using ViewValGraph::Graph<View>::count; 225 using ViewValGraph::Graph<View>::scc; 226 using ViewValGraph::Graph<View>::match; 227 /// Construct graph as not yet initialized 228 Graph(void); 229 /// Initialize graph 230 ExecStatus init(Space& home, ViewArray<View>& x); 231 /// Mark edges in graph, return true if pruning is at all possible 232 bool mark(void); 233 /// Prune unmarked edges, \a assigned is true if a view got assigned 234 ExecStatus prune(Space& home, bool& assigned); 235 /// Synchronize graph with new view domains 236 bool sync(void); 237 }; 238 239 /** 240 * \brief Propagation controller for domain consistent distinct 241 * 242 * The propagation controller provides convenient access to 243 * performing incremental domain consistent distinct propagation 244 * so that the routines can be reused easily. 245 * 246 * Requires \code #include <gecode/int/distinct.hh> \endcode 247 * \ingroup FuncIntProp 248 */ 249 template<class View> 250 class DomCtrl { 251 protected: 252 /// Propagation is performed on a view-value graph 253 Graph<View> g; 254 public: 255 /// Initialize with non-initialized view-value graph 256 DomCtrl(void); 257 /// Check whether a view-value graph is available 258 bool available(void); 259 /// Initialize view-value graph for views \a x 260 ExecStatus init(Space& home, ViewArray<View>& x); 261 /// Synchronize available view-value graph 262 ExecStatus sync(void); 263 /// Perform propagation, \a assigned is true if a view gets assigned 264 ExecStatus propagate(Space& home, bool& assigned); 265 }; 266 267 /** 268 * \brief Domain consistent distinct propagator 269 * 270 * The propagator uses staging: first it uses naive value-based 271 * propagation and only then uses domain consistent propagation. 272 * 273 * The algorithm is taken from: 274 * Jean-Charles Régin, A filtering algorithm for constraints 275 * of difference in CSPs, Proceedings of the Twelfth National 276 * Conference on Artificial Intelligence, pages 362--367. 277 * Seattle, WA, USA, 1994. 278 * 279 * Requires \code #include <gecode/int/distinct.hh> \endcode 280 * \ingroup FuncIntProp 281 */ 282 template<class View> 283 class Dom : public NaryPropagator<View,PC_INT_DOM> { 284 protected: 285 using NaryPropagator<View,PC_INT_DOM>::x; 286 /// Propagation controller 287 DomCtrl<View> dc; 288 /// Constructor for cloning \a p 289 Dom(Space& home, Dom<View>& p); 290 /// Constructor for posting 291 Dom(Home home, ViewArray<View>& x); 292 public: 293#ifdef GECODE_HAS_CBS 294 /// Solution distribution computation for branching 295 virtual void solndistrib(Space& home, Propagator::SendMarginal send) const; 296 /// Sum of variables cardinalities 297 virtual void domainsizesum(Propagator::InDecision in, 298 unsigned int& size, unsigned int& size_b) const; 299#endif 300 /// Perform propagation 301 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 302 /** 303 * \brief Cost function 304 * 305 * If in stage for naive value propagation, the cost is 306 * low linear. Otherwise it is high quadratic. 307 */ 308 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 309 /// Copy propagator during cloning 310 virtual Actor* copy(Space& home); 311 /// Post propagator for views \a x 312 static ExecStatus post(Home home, ViewArray<View>& x); 313 }; 314 315 /** 316 * \brief Ternary domain consistent distinct propagator 317 * 318 * Requires \code #include <gecode/int/distinct.hh> \endcode 319 * \ingroup FuncIntProp 320 */ 321 template<class View> 322 class TerDom : public TernaryPropagator<View,PC_INT_DOM> { 323 protected: 324 using TernaryPropagator<View,PC_INT_DOM>::x0; 325 using TernaryPropagator<View,PC_INT_DOM>::x1; 326 using TernaryPropagator<View,PC_INT_DOM>::x2; 327 328 /// Constructor for cloning \a p 329 TerDom(Space& home, TerDom<View>& p); 330 /// Constructor for posting 331 TerDom(Home home, View x0, View x1, View x2); 332 public: 333 /// Perform propagation 334 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 335 /// Copy propagator during cloning 336 virtual Actor* copy(Space& home); 337 /// Post propagator for views \a x 338 static ExecStatus post(Home home, View x0, View x1, View x2); 339 }; 340 341 /** 342 * \brief Equal-if-then-else domain-consistent propagator 343 * 344 * Implements the propagator \f$x_1=(x_0 = c_0) ? c_1 : x_0\f$. 345 * 346 * Requires \code #include <gecode/int/distinct.hh> \endcode 347 * \ingroup FuncIntProp 348 */ 349 class EqIte : public BinaryPropagator<IntView,PC_INT_DOM> { 350 protected: 351 using BinaryPropagator<IntView,PC_INT_DOM>::x0; 352 using BinaryPropagator<IntView,PC_INT_DOM>::x1; 353 /// The integer constant 354 int c0, c1; 355 /// Constructor for cloning \a p 356 EqIte(Space& home, EqIte& p); 357 /// Constructor for creation 358 EqIte(Home home, IntView x0, IntView x1, int c0, int c1); 359 public: 360 /// Copy propagator during cloning 361 GECODE_INT_EXPORT 362 virtual Actor* copy(Space& home); 363 /// Cost function (defined as high ternary) 364 GECODE_INT_EXPORT 365 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 366 /// Perform propagation 367 GECODE_INT_EXPORT 368 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 369 /// Post if-then-else propagator 370 static ExecStatus post(Home home, IntView x0, IntView x1, int c0, int c1); 371 }; 372 373}}} 374 375#include <gecode/int/distinct/cbs.hpp> 376#include <gecode/int/distinct/val.hpp> 377#include <gecode/int/distinct/bnd.hpp> 378#include <gecode/int/distinct/ter-dom.hpp> 379#include <gecode/int/distinct/graph.hpp> 380#include <gecode/int/distinct/dom-ctrl.hpp> 381#include <gecode/int/distinct/dom.hpp> 382#include <gecode/int/distinct/eqite.hpp> 383 384#endif 385 386// STATISTICS: int-prop 387