this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christopher Mears <chris.mears@monash.edu>
5 *
6 * Copyright:
7 * Christopher Mears, 2012
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_LDSB_HH
35#define GECODE_INT_LDSB_HH
36
37#include <gecode/int.hh>
38
39/**
40 * \namespace Gecode::Int::LDSB
41 * \brief Symmetry breaking for integer variables
42 */
43namespace Gecode { namespace Int { namespace LDSB {
44
45 /// A Literal is a pair of variable index and value.
46 class Literal {
47 public:
48 /// Constructor for an empty literal
49 Literal(void);
50 /// Constructor
51 Literal(int _var, int _val);
52
53 /// Variable index. The ViewArray that the index is meant
54 /// for is assumed to be known by context.
55 int _variable;
56 /// The value of the literal. For int and bool variables,
57 /// this is the value itself; for set variables, this is
58 /// one of the possible elements of the set.
59 int _value;
60
61 /// Less than. The ordering is the lexicographical order
62 /// on the (variable,value) pair.
63 bool operator <(const Literal &rhs) const;
64 };
65
66 /**
67 * \brief Find the location of an integer in a collection of
68 * sequences.
69 *
70 *
71 * Given an array \a indices of integers (of length \a n_values),
72 * which represents a collection of sequences each of size \a
73 * seq_size, find the location of the first occurrence of the value
74 * \a index. Returns a pair of sequence number and position within
75 * that sequence (both zero-based).
76 */
77 GECODE_INT_EXPORT
78 std::pair<int,int>
79 findVar(int *indices, unsigned int n_values, unsigned int seq_size, int index);
80}}}
81
82namespace Gecode {
83 /// Traits of %ArgArray<VarImpBase*>
84 template<>
85 class ArrayTraits<ArgArray<VarImpBase*> > {
86 public:
87 typedef ArgArray<VarImpBase*> StorageType;
88 typedef VarImpBase* ValueType;
89 typedef ArgArray<VarImpBase*> ArgsType;
90 };
91
92 /// An array of literals
93 typedef ArgArray<Int::LDSB::Literal> LiteralArgs;
94 /// Traits of %LiteralArgs
95 template<>
96 class ArrayTraits<LiteralArgs> {
97 public:
98 typedef LiteralArgs StorageType;
99 typedef Int::LDSB::Literal ValueType;
100 typedef LiteralArgs ArgsType;
101 };
102}
103
104namespace Gecode { namespace Int { namespace LDSB {
105 /// Implementation of a symmetry at the modelling level
106 class GECODE_INT_EXPORT SymmetryObject {
107 public:
108 /// Number of references that point to this symmetry object.
109 int nrefs;
110 /// Default constructor
111 SymmetryObject(void);
112 /// Destructor
113 virtual ~SymmetryObject(void);
114 };
115 /// Implementation of a variable symmetry at the modelling level
116 class GECODE_INT_EXPORT VariableSymmetryObject : public SymmetryObject {
117 public:
118 /// Array of variables in symmetry
119 VarImpBase** xs;
120 /// Number of variables in symmetry
121 int nxs;
122 /// Constructor for creation
123 VariableSymmetryObject(ArgArray<VarImpBase*> vars);
124 /// Destructor
125 ~VariableSymmetryObject(void);
126 };
127 /// Implementation of a value symmetry at the modelling level
128 class GECODE_INT_EXPORT ValueSymmetryObject : public SymmetryObject {
129 public:
130 /// Set of symmetric values
131 IntSet values;
132 /// Constructor for creation
133 ValueSymmetryObject(IntSet vs);
134 };
135 /// Implementation of a variable sequence symmetry at the modelling level
136 class GECODE_INT_EXPORT VariableSequenceSymmetryObject : public SymmetryObject {
137 public:
138 /// Array of variables in symmetry
139 VarImpBase** xs;
140 /// Number of variables in symmetry
141 int nxs;
142 /// Size of each sequence in symmetry
143 int seq_size;
144 /// Constructor for creation
145 VariableSequenceSymmetryObject(ArgArray<VarImpBase*> vars, int ss);
146 /// Destructor
147 ~VariableSequenceSymmetryObject();
148 };
149 /// Implementation of a value sequence symmetry at the modelling level
150 class GECODE_INT_EXPORT ValueSequenceSymmetryObject : public SymmetryObject {
151 public:
152 /// Array of values in symmetry
153 IntArgs values;
154 /// Size of each sequence in symmetry
155 int seq_size;
156 /// Constructor for creation
157 ValueSequenceSymmetryObject(IntArgs vs, int ss);
158 };
159
160 /// Implementation of a single symmetry.
161 template<class View>
162 class SymmetryImp {
163 public:
164 /// Compute symmetric literals
165 virtual ArgArray<Literal> symmetric(Literal, const ViewArray<View>&) const = 0;
166 /// Left-branch update
167 virtual void update(Literal) = 0;
168 /// Copy function
169 virtual SymmetryImp<View>* copy(Space& home) const = 0;
170 /// Disposal
171 virtual size_t dispose(Space& home) = 0;
172 /// Unused destructor
173 virtual ~SymmetryImp(void);
174 /// Placement new operator
175 static void* operator new(size_t s, Space& home);
176 /// Return memory to space
177 static void operator delete(void*,Space&);
178 /// Needed for exceptions
179 static void operator delete(void*);
180 };
181 /// Implementation of a variable symmetry.
182 template <class View>
183 class VariableSymmetryImp : public SymmetryImp<View> {
184 protected:
185 /// Symmetric variable indices
186 Support::BitSetOffset<Space> indices;
187 public:
188 /// Constructor for creation
189 VariableSymmetryImp<View>(Space& home, int* vs, unsigned int n);
190 /// Copy constructor
191 VariableSymmetryImp<View>(Space& home, const VariableSymmetryImp<View>& other);
192 /// Disposal
193 virtual size_t dispose(Space& home);
194 /// Left-branch update
195 void update(Literal);
196 /// Compute symmetric literals
197 virtual ArgArray<Literal> symmetric(Literal, const ViewArray<View>&) const;
198 /// Copy function
199 SymmetryImp<View>* copy(Space& home) const;
200 };
201 /// Implementation of a value symmetry.
202 template <class View>
203 class ValueSymmetryImp : public SymmetryImp<View>
204 {
205 public:
206 /// Symmetric values
207 Support::BitSetOffset<Space> values;
208 /// Constructor for creation
209 ValueSymmetryImp<View>(Space& home, int* vs, unsigned int n);
210 /// Copy constructor
211 ValueSymmetryImp<View>(Space& home, const ValueSymmetryImp<View>& other);
212 /// Disposal
213 virtual size_t dispose(Space& home);
214 /// Left-branch update
215 void update(Literal);
216 /// Compute symmetric literals
217 virtual ArgArray<Literal> symmetric(Literal, const ViewArray<View>&) const;
218 /// Copy function
219 SymmetryImp<View>* copy(Space& home) const;
220 };
221 /// Implementation of a variable sequence symmetry.
222 template <class View>
223 class VariableSequenceSymmetryImp : public SymmetryImp<View>
224 {
225 protected:
226 /// Array of variable indices
227 unsigned int *indices;
228 /// Total number of indices (n_seqs * seq_size)
229 unsigned int n_indices;
230 /// Size of each sequence in symmetry
231 unsigned int seq_size;
232 /// Number of sequences in symmetry
233 unsigned int n_seqs;
234
235 /// Map from variable's index to its sequence and position.
236 // e.g. lookup[2] == 10 indicates that the variable with index 2
237 // occurs at position 10 in the "indices" array.
238 // If a variable occurs more than once, only the first occurrence
239 // is recorded.
240 // A value of -1 indicates that the variable does not occur in
241 // "indices".
242 int *lookup;
243 /// Size of lookup
244 unsigned int lookup_size;
245
246 /// Get the value in the specified sequence at the specified
247 /// position. (Both are zero-based.)
248 int getVal(unsigned int sequence, unsigned int position) const;
249 public:
250 /// Constructor for creation
251 VariableSequenceSymmetryImp<View>(Space& home, int *_indices, unsigned int n, unsigned int seqsize);
252 /// Copy constructor
253 VariableSequenceSymmetryImp<View>(Space& home, const VariableSequenceSymmetryImp<View>& s);
254 /// Disposal
255 virtual size_t dispose(Space& home);
256 /// Search left-branch update
257 void update(Literal);
258 /// Compute symmetric literals
259 virtual ArgArray<Literal> symmetric(Literal, const ViewArray<View>&) const;
260 /// Copy function
261 SymmetryImp<View>* copy(Space& home) const;
262 };
263 /// Implementation of a value sequence symmetry.
264 template <class View>
265 class ValueSequenceSymmetryImp : public SymmetryImp<View>
266 {
267 protected:
268 /// Set of sequences
269 int *values;
270 /// Total number of values (n_seqs * seq_size)
271 unsigned int n_values;
272 /// Size of each sequence in symmetry
273 unsigned int seq_size;
274 /// Number of sequences in symmetry
275 unsigned int n_seqs;
276 /// Which sequences are dead
277 Support::BitSet<Space> dead_sequences;
278 /// Get the value in the specified sequence at the specified
279 /// position. (Both are zero-based.)
280 int getVal(unsigned int sequence, unsigned int position) const;
281 private:
282 ValueSequenceSymmetryImp<View>(const ValueSequenceSymmetryImp<View>&);
283 public:
284 /// Constructor for creation
285 ValueSequenceSymmetryImp<View>(Space& home, int* _values, unsigned int n, unsigned int seqsize);
286 /// Copy constructor
287 ValueSequenceSymmetryImp<View>(Space& home, const ValueSequenceSymmetryImp<View>& vss);
288 /// Disposal
289 virtual size_t dispose(Space& home);
290 /// Left-branch update
291 void update(Literal);
292 /// Compute symmetric literals
293 virtual ArgArray<Literal> symmetric(Literal, const ViewArray<View>&) const;
294 /// Copy function
295 SymmetryImp<View>* copy(Space& home) const;
296 };
297
298 /// %Choice storing position and value, and symmetric literals to be
299 /// excluded on the right branch.
300 template<class Val>
301 class GECODE_VTABLE_EXPORT LDSBChoice : public PosValChoice<Val> {
302 private:
303 /// Set of literals to be excluded
304 const Literal * const _literals;
305 /// Number of literals
306 const int _nliterals;
307 public:
308 /// Initialize choice for brancher \a b, position \a p, value \a
309 /// n, and set of literals \a literals (of size \a nliterals)
310 LDSBChoice(const Brancher& b, unsigned int a, const Pos& p, const Val& n,
311 const Literal* literals, int nliterals);
312 /// Destructor
313 ~LDSBChoice(void);
314 /// Return literals
315 const Literal* literals(void) const;
316 /// Return number of literals
317 int nliterals(void) const;
318 /// Archive into \a e
319 virtual void archive(Archive& e) const;
320 };
321
322 /**
323 * \brief Symmetry-breaking brancher with generic view and value
324 * selection
325 *
326 * Implements view-based branching for an array of views (of type
327 * \a View) and value (of type \a Val).
328 *
329 */
330 template<class View, int n, class Val, unsigned int a,
331 class Filter, class Print>
332 class LDSBBrancher : public ViewValBrancher<View,n,Val,a,Filter,Print> {
333 public:
334 using typename ViewValBrancher<View,n,Val,a,Filter,Print>::Var;
335 /// Array of symmetry implementations
336 SymmetryImp<View>** _syms;
337 /// Number of symmetry implementations
338 int _nsyms;
339 // Position of variable that last choice was created for
340 int _prevPos;
341 protected:
342 /// Constructor for cloning \a b
343 LDSBBrancher(Space& home, LDSBBrancher& b);
344 /// Constructor for creation
345 LDSBBrancher(Home home,
346 ViewArray<View>& x,
347 ViewSel<View>* vs[n],
348 ValSelCommitBase<View,Val>* vsc,
349 SymmetryImp<View>** syms, int nsyms,
350 BranchFilter<Var> bf,
351 VarValPrint<Var,Val> vvp);
352 public:
353 /// Return choice
354 virtual const Choice* choice(Space& home);
355 /// Return choice
356 virtual const Choice* choice(const Space& home, Archive& e);
357 /// Perform commit for choice \a c and alternative \a b
358 virtual ExecStatus commit(Space& home, const Choice& c, unsigned int b);
359 /// Perform cloning
360 virtual Actor* copy(Space& home);
361 /// Delete brancher and return its size
362 virtual size_t dispose(Space& home);
363 /// Brancher post function
364 static void post(Home home,
365 ViewArray<View>& x,
366 ViewSel<View>* vs[n],
367 ValSelCommitBase<View,Val>* vsc,
368 SymmetryImp<View>** syms,
369 int nsyms,
370 BranchFilter<Var> bf,
371 VarValPrint<Var,Val> vvp);
372 };
373
374 /// Post LDSB brancher
375 template<class View, int n, class Val, unsigned int a>
376 void postldsbbrancher(Home home,
377 ViewArray<View>& x,
378 ViewSel<View>* vs[n],
379 ValSelCommitBase<View,Val>* vsc,
380 SymmetryImp<View>** syms, int nsyms,
381 BranchFilter<typename View::VarType> bf,
382 VarValPrint<typename View::VarType,Val> vvp);
383
384 /// Exclude value \v from variable view \x
385 template<class View>
386 ModEvent prune(Space& home, View x, int v);
387
388}}}
389
390#include <gecode/int/ldsb/brancher.hpp>
391#include <gecode/int/ldsb/sym-imp.hpp>
392
393#endif
394
395// STATISTICS: int-branch
396