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 *
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#ifndef GECODE_INT_NVALUES_HH
35#define GECODE_INT_NVALUES_HH
36
37#include <gecode/int.hh>
38#include <gecode/int/val-set.hh>
39
40/**
41 * \namespace Gecode::Int::NValues
42 * \brief Number of values propagators
43 */
44
45namespace Gecode { namespace Int { namespace NValues {
46
47 /// Event type for range-based overlap analysis
48 enum RangeEventType {
49 /// A range starts
50 RET_FST = 0,
51 /// A range ends
52 RET_LST = 1,
53 /// No further events
54 RET_END = 2
55 };
56
57 /// Event for range-based overlap analysis
58 class RangeEvent {
59 public:
60 /// The event type
61 RangeEventType ret;
62 /// The value for the range (first or last value, depending on type)
63 int val;
64 /// Which view does this range belong to
65 int view;
66 /// Order events: first by val, then by event type
67 bool operator <(RangeEvent re) const;
68 };
69
70 /// Symmetric diagonal bit matrix
71 class SymBitMatrix : public Support::BitSet<Region> {
72 protected:
73 /// Size of matrix
74 int n;
75 /// Return position in matrix
76 int pos(int x, int y) const;
77 public:
78 /// Initialize matrix for dimension \a n by \a n
79 SymBitMatrix(Region& r, int n);
80 /// Is bit at position \a x, \a y set?
81 bool get(int x, int y) const;
82 /// Set bit at position \a x, \a y
83 void set(int x, int y);
84 };
85
86}}}
87
88#include <gecode/int/nvalues/range-event.hpp>
89#include <gecode/int/nvalues/sym-bit-matrix.hpp>
90
91#include <gecode/int/view-val-graph.hh>
92
93namespace Gecode { namespace Int { namespace NValues {
94
95 /// View-value graph for propagation of upper bound
96 class Graph : public ViewValGraph::Graph<IntView> {
97 protected:
98 /// Number of matched edges
99 int n_matched;
100 public:
101 /// Construct graph as not yet initialized
102 Graph(void);
103 /// Return size of maximal matching (excluding assigned views)
104 int size(void) const;
105 /// Initialize graph including values in \a vs
106 void init(Space& home, const ValSet& vs, const ViewArray<IntView>& x);
107 /// Synchronize graph with new view domains
108 void sync(void);
109 /*
110 * \brief Mark all edges used that can appear in some maximal matching
111 *
112 * Return true, if any edge can be in fact pruned.
113 */
114 bool mark(void);
115 /// Prune all values corresponding to unused edges
116 ExecStatus prune(Space& home);
117 };
118
119}}}
120
121#include <gecode/int/nvalues/graph.hpp>
122
123namespace Gecode { namespace Int { namespace NValues {
124
125 /**
126 * \brief Number of values propagator for integer views base class
127 *
128 * Requires \code #include <gecode/int/nvalues.hh> \endcode
129 * \ingroup FuncIntProp
130 */
131 template<class VY>
132 class IntBase
133 : public MixNaryOnePropagator<IntView,PC_INT_DOM,VY,PC_INT_BND> {
134 protected:
135 using MixNaryOnePropagator<IntView,PC_INT_DOM,VY,PC_INT_BND>::x;
136 using MixNaryOnePropagator<IntView,PC_INT_DOM,VY,PC_INT_BND>::y;
137 /// Value set storing the values of already assigned views
138 ValSet vs;
139 /// Constructor for posting
140 IntBase(Home home, ValSet& vs, ViewArray<IntView>& x, VY y);
141 /// Constructor for cloning \a p
142 IntBase(Space& home, IntBase<VY>& p);
143 /// Add values of assigned views to value set
144 void add(Space& home);
145 /**
146 * Compute position of disjoint views in \a dis (with length \a n_dis)
147 * and eliminate subsumed views (all values included in the value set
148 * \a vs).
149 */
150 void disjoint(Space& home, Region& r, int*& dis, int& n_dis);
151 /// Eliminate subsumed views (all values included in the value set \a vs)
152 void eliminate(Space& home);
153 /// Propagate that all views must take values from value set
154 ExecStatus all_in_valset(Space& home);
155 /**
156 * Perform pruning of the lower bound based on finding
157 * an independent set, where \a dis and \a n_dis define the
158 * set of disjoint views (not overlapping with the values in
159 * the value set).
160 *
161 * Changes \a dis.
162 */
163 ExecStatus prune_lower(Space& home, int* dis, int n_dis);
164 /**
165 * Perform pruning of the upper bound based on finding
166 * a maximal matching in the view value graph \a g.
167 *
168 * Requires that subsumed views have been eliminated.
169 */
170 ExecStatus prune_upper(Space& home, Graph& g);
171 public:
172 /// Cost function
173 virtual PropCost cost(const Space&, const ModEventDelta&) const;
174 /// Delete propagator and return its size
175 virtual size_t dispose(Space& home);
176 };
177
178 /**
179 * \brief Equal to number of values propagator for integer views
180 *
181 * Requires \code #include <gecode/int/nvalues.hh> \endcode
182 * \ingroup FuncIntProp
183 */
184 template<class VY>
185 class EqInt : public IntBase<VY> {
186 protected:
187 using IntBase<VY>::x;
188 using IntBase<VY>::y;
189 using IntBase<VY>::vs;
190 using IntBase<VY>::add;
191 using IntBase<VY>::all_in_valset;
192 using IntBase<VY>::disjoint;
193 using IntBase<VY>::prune_lower;
194 using IntBase<VY>::prune_upper;
195 /// View-value graph
196 Graph g;
197 /// Constructor for posting
198 EqInt(Home home, ValSet& vs, ViewArray<IntView>& x, VY y);
199 /// Constructor for cloning \a p
200 EqInt(Space& home, EqInt<VY>& p);
201 public:
202 /// Copy propagator during cloning
203 virtual Propagator* copy(Space& home);
204 /// Perform propagation
205 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
206 /// Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}=y\f$
207 static ExecStatus post(Home home, ViewArray<IntView>& x, VY y);
208 /// Delete propagator and return its size
209 virtual size_t dispose(Space& home);
210 };
211
212 /**
213 * \brief Less or equal to number of values propagator for integer views
214 *
215 * Requires \code #include <gecode/int/nvalues.hh> \endcode
216 * \ingroup FuncIntProp
217 */
218 template<class VY>
219 class LqInt : public IntBase<VY> {
220 protected:
221 using IntBase<VY>::x;
222 using IntBase<VY>::y;
223 using IntBase<VY>::vs;
224 using IntBase<VY>::add;
225 using IntBase<VY>::all_in_valset;
226 using IntBase<VY>::disjoint;
227 using IntBase<VY>::prune_lower;
228 using IntBase<VY>::prune_upper;
229 /// Constructor for posting
230 LqInt(Home home, ValSet& vs, ViewArray<IntView>& x, VY y);
231 /// Constructor for cloning \a p
232 LqInt(Space& home, LqInt<VY>& p);
233 public:
234 /// Copy propagator during cloning
235 virtual Propagator* copy(Space& home);
236 /// Perform propagation
237 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
238 /// Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\leq y\f$
239 static ExecStatus post(Home home, ViewArray<IntView>& x, VY y);
240 /// Delete propagator and return its size
241 virtual size_t dispose(Space& home);
242 };
243
244 /**
245 * \brief Greater or equal to number of values propagator for integer views
246 *
247 * Requires \code #include <gecode/int/nvalues.hh> \endcode
248 * \ingroup FuncIntProp
249 */
250 template<class VY>
251 class GqInt : public IntBase<VY> {
252 protected:
253 using IntBase<VY>::x;
254 using IntBase<VY>::y;
255 using IntBase<VY>::vs;
256 using IntBase<VY>::add;
257 using IntBase<VY>::all_in_valset;
258 using IntBase<VY>::disjoint;
259 using IntBase<VY>::prune_lower;
260 using IntBase<VY>::prune_upper;
261 using IntBase<VY>::eliminate;
262 /// View-value graph
263 Graph g;
264 /// Constructor for posting
265 GqInt(Home home, ValSet& vs, ViewArray<IntView>& x, VY y);
266 /// Constructor for cloning \a p
267 GqInt(Space& home, GqInt<VY>& p);
268 public:
269 /// Copy propagator during cloning
270 virtual Propagator* copy(Space& home);
271 /// Perform propagation
272 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
273 /// Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\geq y\f$
274 static ExecStatus post(Home home, ViewArray<IntView>& x, VY y);
275 };
276
277}}}
278
279#include <gecode/int/nvalues/int-base.hpp>
280#include <gecode/int/nvalues/int-eq.hpp>
281#include <gecode/int/nvalues/int-lq.hpp>
282#include <gecode/int/nvalues/int-gq.hpp>
283
284namespace Gecode { namespace Int { namespace NValues {
285
286 /**
287 * \brief Number of values propagator for Boolean views base class
288 *
289 * Requires \code #include <gecode/int/nvalues.hh> \endcode
290 * \ingroup FuncIntProp
291 */
292 template<class VY>
293 class BoolBase : public Propagator {
294 protected:
295 /// View status: a zero has already been encountered
296 static const int VS_ZERO = 1 << 0;
297 /// View status: a one has already been encountered
298 static const int VS_ONE = 1 << 1;
299 /// Status information about the views
300 int status;
301 /// The advisor council
302 Council<ViewAdvisor<BoolView> > c;
303 /// The view for counting the number of values
304 VY y;
305 /// Constructor for posting
306 BoolBase(Home home, int status, ViewArray<BoolView>& x, VY y);
307 /// Constructor for cloning \a p
308 BoolBase(Space& home, BoolBase<VY>& p);
309 public:
310 /// Give advice to propagator
311 virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
312 /// Cost function (defined as low unary)
313 virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
314 /// Schedule function
315 virtual void reschedule(Space& home);
316 /// Delete propagator and return its size
317 virtual size_t dispose(Space& home);
318 };
319
320 /**
321 * \brief Equal to number of values propagator for Boolean views
322 *
323 * Requires \code #include <gecode/int/nvalues.hh> \endcode
324 * \ingroup FuncIntProp
325 */
326 template<class VY>
327 class EqBool : public BoolBase<VY> {
328 protected:
329 using BoolBase<VY>::VS_ZERO;
330 using BoolBase<VY>::VS_ONE;
331 using BoolBase<VY>::status;
332 using BoolBase<VY>::c;
333 using BoolBase<VY>::y;
334 /// Constructor for posting
335 EqBool(Home home, int status, ViewArray<BoolView>& x, VY y);
336 /// Constructor for cloning \a p
337 EqBool(Space& home, EqBool<VY>& p);
338 public:
339 /// Copy propagator during cloning
340 virtual Actor* copy(Space& home);
341 /// Perform propagation
342 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
343 /**
344 * \brief Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}=y\f$
345 *
346 * The view array \a x is used only temporarily and hence can
347 * be region allocated.
348 */
349 static ExecStatus post(Home home, ViewArray<BoolView>& x, VY y);
350 };
351
352 /**
353 * \brief Less or equal to number of values propagator for Boolean views
354 *
355 * Requires \code #include <gecode/int/nvalues.hh> \endcode
356 * \ingroup FuncIntProp
357 */
358 template<class VY>
359 class LqBool : public BoolBase<VY> {
360 protected:
361 using BoolBase<VY>::VS_ZERO;
362 using BoolBase<VY>::VS_ONE;
363 using BoolBase<VY>::status;
364 using BoolBase<VY>::c;
365 using BoolBase<VY>::y;
366 /// Constructor for posting
367 LqBool(Home home, int status, ViewArray<BoolView>& x, VY y);
368 /// Constructor for cloning \a p
369 LqBool(Space& home, LqBool<VY>& p);
370 public:
371 /// Copy propagator during cloning
372 virtual Actor* copy(Space& home);
373 /// Perform propagation
374 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
375 /**
376 * \brief Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\leq y\f$
377 *
378 * The view array \a x is used only temporarily and hence can
379 * be region allocated.
380 */
381 static ExecStatus post(Home home, ViewArray<BoolView>& x, VY y);
382 };
383
384 /**
385 * \brief Greater or equal to number of values propagator for Boolean views
386 *
387 * Requires \code #include <gecode/int/nvalues.hh> \endcode
388 * \ingroup FuncIntProp
389 */
390 template<class VY>
391 class GqBool : public BoolBase<VY> {
392 protected:
393 using BoolBase<VY>::VS_ZERO;
394 using BoolBase<VY>::VS_ONE;
395 using BoolBase<VY>::status;
396 using BoolBase<VY>::c;
397 using BoolBase<VY>::y;
398 /// Constructor for posting
399 GqBool(Home home, int status, ViewArray<BoolView>& x, VY y);
400 /// Constructor for cloning \a p
401 GqBool(Space& home, GqBool<VY>& p);
402 public:
403 /// Copy propagator during cloning
404 virtual Actor* copy(Space& home);
405 /// Perform propagation
406 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
407 /**
408 * \brief Post propagator for \f$\#\{x_0,\ldots,x_{|x|-1}\}\geq y\f$
409 *
410 * The view array \a x is used only temporarily and hence can
411 * be region allocated.
412 */
413 static ExecStatus post(Home home, ViewArray<BoolView>& x, VY y);
414 };
415
416}}}
417
418#include <gecode/int/nvalues/bool-base.hpp>
419#include <gecode/int/nvalues/bool-eq.hpp>
420#include <gecode/int/nvalues/bool-lq.hpp>
421#include <gecode/int/nvalues/bool-gq.hpp>
422
423#endif
424
425// STATISTICS: int-prop