Generated on for Gecode by doxygen 1.17.0
sortsup.hpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Patrick Pekczynski <pekczynski@ps.uni-sb.de>
5 *
6 * Copyright:
7 * Patrick Pekczynski, 2004
8 *
9 * This file is part of Gecode, the generic constraint
10 * development environment:
11 * http://www.gecode.dev
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
34namespace Gecode { namespace Int { namespace Sorted {
35
39 class Rank {
40 public:
42 int min;
44 int max;
45 };
46
54 public:
58 int left;
60 int right;
63 };
64
75
76 template<class View, bool Perm>
77 inline bool
79 bool& subsumed, int& dropfst) {
80
81 dropfst = 0;
82 subsumed = true;
83 int xs = x.size();
84 for (int i = 0; i < xs ; i++) {
85 if (Perm) {
86 subsumed &= (x[i].assigned() &&
87 z[i].assigned() &&
88 y[z[i].val()].assigned());
89 if (subsumed) {
90 if (x[i].val() != y[z[i].val()].val()) {
91 return false;
92 } else {
93 if (z[i].val() == i) {
94 dropfst++;
95 }
96 }
97 }
98 } else {
99 subsumed &= (x[i].assigned() && y[i].assigned());
100 if (subsumed) {
101 if (x[i].val() != y[i].val()) {
102 return false;
103 } else {
104 dropfst++;
105 }
106 }
107 }
108 }
109 return true;
110 }
111
116
118 public:
120 int root;
124 int rank;
126 int name;
134 int iset;
136 int succ;
138 int pred;
139 };
140
147 private:
149 OfflineMinItem* sequence;
151 int* vertices;
153 int n;
154 public:
155 OfflineMin(void);
156 OfflineMin(OfflineMinItem[], int[], int);
161 int find(int x);
166 int find_pc(int x);
168 void unite(int a, int b, int c);
170 void makeset(void);
172 int size(void);
174 };
175
177 n = 0;
178 sequence = nullptr;
179 vertices = nullptr;
180 }
181
183 n = size;
184 sequence = &s[0];
185 vertices = &v[0];
186 }
187
188 forceinline int
190 while (sequence[x].parent != x) {
191 x = sequence[x].parent;
192 }
193 // x is now the root of the tree
194 // return the set, x belongs to
195 return sequence[x].name;
196 }
197
198 forceinline int
200 int path_length = 0;
201 while (sequence[x].parent != x) {
202 vertices[path_length++] = x;
203 x = sequence[x].parent;
204 }
205 // x is now the root of the tree
206 // Compress path up to the root
207 for (int i=0; i < path_length-1; i++) {
208 sequence[vertices[i]].parent = x;
209 }
210 // return the set x belongs to
211 return sequence[x].name;
212 }
213
214 forceinline void
215 OfflineMin::unite(int a, int b, int c){
216 // c is the union of a and b
217 int ra = sequence[a].root;
218 int rb = sequence[b].root;
219 int large = rb;
220 int small = ra;
221 if (sequence[ra].rank > sequence[rb].rank) {
222 large = ra;
223 small = rb;
224 }
225 sequence[small].parent = large;
226 sequence[large].rank += sequence[small].rank;
227 sequence[large].name = c;
228 sequence[c].root = large;
229 }
230
231 forceinline void
233 for(int i = n; i--; ){
234 OfflineMinItem& cur = sequence[i];
235 cur.rank = 0; // initially each set is empty
236 cur.name = i; // it has its own name
237 cur.root = i; // it is the root node
238 cur.parent = i; // it is its own parent
239 cur.pred = i - 1;
240 cur.succ = i + 1;
241 cur.iset = -5;
242 }
243 // no need to zero vertices, as it is only used as scratch area
244 }
245
246 forceinline int
248 return n;
249 }
250
251 forceinline OfflineMinItem&
253 return sequence[i];
254 }
255
265 template<class View>
267 protected:
269 public:
270 TupleMaxInc(const ViewArray<View>& x0) : x(x0) {}
271 bool operator ()(const int i, const int j) {
272 if (x[i].max() == x[j].max()) {
273 return x[i].min() < x[j].min();
274 } else {
275 return x[i].max() < x[j].max();
276 }
277 }
278 };
279
280
290 template<class View>
292 protected:
295 public:
297 const ViewArray<View>& z0) : x(x0), z(z0) {}
298 bool operator ()(const int i, const int j) {
299 if (x[i].max() == x[j].max()) {
300 if (x[i].min() == x[j].min()) {
301 if (z[i].max() == z[j].max()) {
302 return z[i].min() < z[j].min();
303 } else {
304 return z[i].max() < z[j].max();
305 }
306 } else {
307 return x[i].min() < x[j].min();
308 }
309 } else {
310 return x[i].max() < x[j].max();
311 }
312 }
313 };
314
323
324 template<class View>
326 public:
327 bool operator ()(const View& x, const View& y) {
328 if (x.min() == y.min()) {
329 return x.max() < y.max();
330 } else {
331 return x.min() < y.min();
332 }
333 }
334 };
335
336
338 template<class View>
339 class ViewPair {
340 public:
343 };
344
355 template<class View>
357 public:
358 bool operator ()(const ViewPair<View>& x, const ViewPair<View>& y) {
359 if (x.x.min() == y.x.min()) {
360 if (x.x.max() == y.x.max()) {
361 if (x.z.min() == y.z.min()) {
362 return x.z.max() < y.z.max();
363 } else {
364 return x.z.min() < y.z.min();
365 }
366 } else {
367 return x.x.max() < y.x.max();
368 }
369 } else {
370 return x.x.min() < y.x.min();
371 }
372 }
373 };
374
381
382 template<class View, bool Perm>
383 inline bool
388 bool& subsumed,
389 bool& match_fixed,
390 bool&,
391 bool& noperm_bc) {
392
393 bool x_complete = true;
394 bool y_complete = true;
395 bool z_complete = true;
396
397 for (int i=0; i<y.size(); i++) {
398 x_complete &= x[i].assigned();
399 y_complete &= y[i].assigned();
400 if (Perm) {
401 z_complete &= z[i].assigned();
402 }
403 }
404
405 if (x_complete) {
406 for (int i=0; i<x.size(); i++) {
407 ModEvent me = y[i].eq(home, x[i].val());
408 if (me_failed(me)) {
409 return false;
410 }
411 }
412 if (Perm) {
413 subsumed = false;
414 } else {
415 subsumed = true;
416 }
417 }
418
419 if (y_complete) {
420 bool y_equality = true;
421 for (int i=1; i<y.size(); i++) {
422 y_equality &= (y[i-1].val() == y[i].val());
423 }
424 if (y_equality) {
425 for (int i=0; i<x.size(); i++) {
426 ModEvent me = x[i].eq(home, y[i].val());
427 if (me_failed(me)) {
428 return false;
429 }
430 }
431 if (Perm) {
432 subsumed = false;
433 } else {
434 subsumed = true;
435 }
436 noperm_bc = true;
437 }
438 }
439
440 if (Perm) {
441 if (z_complete) {
442 if (x_complete) {
443 for (int i=0; i<x.size(); i++) {
444 ModEvent me = y[z[i].val()].eq(home, x[i].val());
445 if (me_failed(me)) {
446 return false;
447 }
448 }
449 subsumed = true;
450 return subsumed;
451 }
452 if (y_complete) {
453 for (int i=0; i<x.size(); i++) {
454 ModEvent me = x[i].eq(home, y[z[i].val()].val());
455 if (me_failed(me)) {
456 return false;
457 }
458 }
459 subsumed = true;
460 return subsumed;
461 }
462
463 // validate the permutation
464 int sum = 0;
465 for (int i=0; i<x.size(); i++) {
466 int pi = z[i].val();
467 if (x[i].max() < y[pi].min() ||
468 x[i].min() > y[pi].max()) {
469 return false;
470 }
471 sum += pi;
472 }
473 int n = x.size();
474 int gauss = ( (n * (n + 1)) / 2);
475 // if the sum over all assigned permutation variables is not
476 // equal to the gaussian sum - n they are not distinct, hence invalid
477 if (sum != gauss - n) {
478 return false;
479 }
480 match_fixed = true;
481 }
482 }
483 return true;
484 }
485
492
493 template<class View>
494 forceinline bool
496 ViewArray<View>& z, bool& nofix) {
497 int n = x.size();
498 for (int i=0; i<n; i++) {
499 if (z[i].assigned()) {
500 int v = z[i].val();
501 if (x[i].assigned()) {
502 // channel equality from x to y
503 ModEvent me = y[v].eq(home, x[i].val());
504 if (me_failed(me))
505 return false;
506 nofix |= me_modified(me);
507 } else {
508 if (y[v].assigned()) {
509 // channel equality from y to x
510 ModEvent me = x[i].eq(home, y[v].val());
511 if (me_failed(me))
512 return false;
513 nofix |= me_modified(me);
514 } else {
515 // constrain upper bound
516 ModEvent me = x[i].lq(home, y[v].max());
517 if (me_failed(me))
518 return false;
519 nofix |= me_modified(me);
520
521 // constrain lower bound
522 me = x[i].gq(home, y[v].min());
523 if (me_failed(me))
524 return false;
525 nofix |= me_modified(me);
526
527 // constrain the sorted variable
528 // constrain upper bound
529 me = y[v].lq(home, x[i].max());
530 if (me_failed(me))
531 return false;
532 nofix |= me_modified(me);
533
534 // constrain lower bound
535 me = y[v].gq(home, x[i].min());
536 if (me_failed(me))
537 return false;
538 nofix |= me_modified(me);
539 }
540 }
541 } else {
542 // if the permutation variable is undetermined
543 int l = z[i].min();
544 int r = z[i].max();
545 // upper bound
546 ModEvent me = x[i].lq(home, y[r].max());
547 if (me_failed(me))
548 return false;
549 nofix |= me_modified(me);
550
551 // lower bound
552 me = x[i].gq(home, y[l].min());
553 if (me_failed(me))
554 return false;
555 nofix |= me_modified(me);
556 }
557 }
558 return true;
559 }
560
561
562}}}
563
564
565// STATISTICS: int-prop
Item used to construct the OfflineMin sequence.
Definition sortsup.hpp:117
int pred
Predecessor in the Offline-Min sequence.
Definition sortsup.hpp:138
int root
Root node representing the set the vertex belongs to.
Definition sortsup.hpp:120
int succ
Successor in the Offline-Min sequence.
Definition sortsup.hpp:136
int rank
Ranking of the set given by its cardinality.
Definition sortsup.hpp:124
int name
Name or label of a set.
Definition sortsup.hpp:126
int parent
Predecessor in the tree representation of the set.
Definition sortsup.hpp:122
void unite(int a, int b, int c)
Unite two sets a and b and label the union with c.
Definition sortsup.hpp:215
OfflineMinItem & operator[](int)
Definition sortsup.hpp:252
void makeset(void)
Initialization of the datastructure.
Definition sortsup.hpp:232
int size(void)
Return the size of the Offline-Min item.
Definition sortsup.hpp:247
Storage class for mininmum and maximum of a variable.
Definition sortsup.hpp:39
int max
stores the mininmum of a variable
Definition sortsup.hpp:44
int min
stores the mininmum of a variable
Definition sortsup.hpp:42
Representation of a strongly connected component.
Definition sortsup.hpp:53
int leftmost
Leftmost y-node in a scc.
Definition sortsup.hpp:56
int left
Direct left neighbour of an y-node in a scc.
Definition sortsup.hpp:58
int right
Direct right neighbour of an y-node in a scc.
Definition sortsup.hpp:60
int rightmost
Rightmost reachable y-node in a scc.
Definition sortsup.hpp:62
bool operator()(const int i, const int j)
Definition sortsup.hpp:298
TupleMaxIncExt(const ViewArray< View > &x0, const ViewArray< View > &z0)
Definition sortsup.hpp:296
bool operator()(const int i, const int j)
Definition sortsup.hpp:271
TupleMaxInc(const ViewArray< View > &x0)
Definition sortsup.hpp:270
Extended view comparison on pairs of views.
Definition sortsup.hpp:356
bool operator()(const ViewPair< View > &x, const ViewPair< View > &y)
Definition sortsup.hpp:358
View comparison on ViewTuples.
Definition sortsup.hpp:325
bool operator()(const View &x, const View &y)
Definition sortsup.hpp:327
Computation spaces.
Definition core.hpp:1775
View arrays.
Definition array.hpp:255
bool assigned(void) const
Test if all variables are assigned.
Definition array.hpp:1377
int size(void) const
Return size of array (number of elements).
Definition array.hpp:1156
bool me_failed(ModEvent me)
Check whether modification event me is failed.
Definition modevent.hpp:54
bool me_modified(ModEvent me)
Check whether modification event me describes variable modification.
Definition modevent.hpp:59
Sorted propagators
bool channel(Space &home, ViewArray< View > &x, ViewArray< View > &y, ViewArray< View > &z, bool &nofix)
Channel between x, y and z.
Definition sortsup.hpp:495
bool array_assigned(Space &home, ViewArray< View > &x, ViewArray< View > &y, ViewArray< View > &z, bool &subsumed, bool &match_fixed, bool &, bool &noperm_bc)
Check for assignment of a variable array.
Definition sortsup.hpp:384
bool check_subsumption(ViewArray< View > &x, ViewArray< View > &y, ViewArray< View > &z, bool &subsumed, int &dropfst)
Subsumption test.
Definition sortsup.hpp:78
Finite domain integers.
Definition lastval.hh:52
Gecode toplevel namespace
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
LinIntExpr sum(const IntVarArgs &x)
Construct linear expression as sum of integer variables.
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
int ModEvent
Type for modification events.
Definition core.hpp:67
const int small[]
Small Photo example.
Definition photo.cpp:192
const int large[]
Large Photo example.
Definition photo.cpp:202
const int * pi[]
Definition photo.cpp:14262