sortsup.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 namespace Gecode { namespace Int { namespace Sorted {
00035
00039 class Rank {
00040 public:
00042 int min;
00044 int max;
00045 };
00046
00053 class SccComponent {
00054 public:
00056 int leftmost;
00058 int left;
00060 int right;
00062 int rightmost;
00063 };
00064
00076 template<class View, bool Perm>
00077 inline bool
00078 check_subsumption(ViewArray<View>& x, ViewArray<View>& y, ViewArray<View>& z,
00079 bool& subsumed, int& dropfst) {
00080
00081 dropfst = 0;
00082 subsumed = true;
00083 int xs = x.size();
00084 for (int i = 0; i < xs ; i++) {
00085 if (Perm) {
00086 subsumed &= (x[i].assigned() &&
00087 z[i].assigned() &&
00088 y[z[i].val()].assigned());
00089 if (subsumed) {
00090 if (x[i].val() != y[z[i].val()].val()) {
00091 return false;
00092 } else {
00093 if (z[i].val() == i) {
00094 dropfst++;
00095 }
00096 }
00097 }
00098 } else {
00099 subsumed &= (x[i].assigned() && y[i].assigned());
00100 if (subsumed) {
00101 if (x[i].val() != y[i].val()) {
00102 return false;
00103 } else {
00104 dropfst++;
00105 }
00106 }
00107 }
00108 }
00109 return true;
00110 }
00111
00117 class OfflineMinItem {
00118 public:
00120 int root;
00122 int parent;
00124 int rank;
00126 int name;
00134 int iset;
00136 int succ;
00138 int pred;
00139 };
00140
00146 class OfflineMin {
00147 private:
00148 OfflineMinItem* sequence;
00149 int* vertices;
00150 int n;
00151 public:
00152 OfflineMin(void);
00153 OfflineMin(OfflineMinItem[], int[], int);
00158 int find(int x);
00163 int find_pc(int x);
00165 void unite(int a, int b, int c);
00167 void makeset(void);
00169 int size(void);
00170 OfflineMinItem& operator [](int);
00171 };
00172
00173 OfflineMin::OfflineMin(void){
00174 n = 0;
00175 sequence = NULL;
00176 vertices = NULL;
00177 }
00178
00179 OfflineMin::OfflineMin(OfflineMinItem s[], int v[], int size){
00180 n = size;
00181 sequence = &s[0];
00182 vertices = &v[0];
00183 }
00184
00185 forceinline int
00186 OfflineMin::find(int x) {
00187 while (sequence[x].parent != x) {
00188 x = sequence[x].parent;
00189 }
00190
00191
00192 return sequence[x].name;
00193 }
00194
00195 forceinline int
00196 OfflineMin::find_pc(int x){
00197 int vsize = 0;
00198 while (sequence[x].parent != x) {
00199 vertices[x] = x;
00200 x = sequence[x].parent;
00201 }
00202
00203 for (int i=0; i<vsize; i++)
00204 sequence[vertices[i]].parent = x;
00205
00206 return sequence[x].name;
00207 }
00208
00209 forceinline void
00210 OfflineMin::unite(int a, int b, int c){
00211
00212 int ra = sequence[a].root;
00213 int rb = sequence[b].root;
00214 int large = rb;
00215 int small = ra;
00216 if (sequence[ra].rank > sequence[rb].rank) {
00217 large = ra;
00218 small = rb;
00219 }
00220 sequence[small].parent = large;
00221 sequence[large].rank += sequence[small].rank;
00222 sequence[large].name = c;
00223 sequence[c].root = large;
00224 }
00225
00226 forceinline void
00227 OfflineMin::makeset(void){
00228 for(int i = n; i--; ){
00229 OfflineMinItem& cur = sequence[i];
00230 cur.rank = 0;
00231 cur.name = i;
00232 cur.root = i;
00233 cur.parent = i;
00234 cur.pred = i - 1;
00235 cur.succ = i + 1;
00236 cur.iset = -5;
00237 }
00238 }
00239
00240 forceinline int
00241 OfflineMin::size(void){
00242 return n;
00243 }
00244
00245 forceinline OfflineMinItem&
00246 OfflineMin::operator [](int i){
00247 return sequence[i];
00248 }
00249
00259 template<class View>
00260 class TupleMaxInc {
00261 protected:
00262 ViewArray<View> x;
00263 public:
00264 TupleMaxInc(const ViewArray<View>& x0) : x(x0) {}
00265 bool operator ()(const int i, const int j) {
00266 if (x[i].max() == x[j].max()) {
00267 return x[i].min() < x[j].min();
00268 } else {
00269 return x[i].max() < x[j].max();
00270 }
00271 }
00272 };
00273
00274
00284 template<class View>
00285 class TupleMaxIncExt {
00286 protected:
00287 ViewArray<View> x;
00288 ViewArray<View> z;
00289 public:
00290 TupleMaxIncExt(const ViewArray<View>& x0,
00291 const ViewArray<View>& z0) : x(x0), z(z0) {}
00292 bool operator ()(const int i, const int j) {
00293 if (x[i].max() == x[j].max()) {
00294 if (x[i].min() == x[j].min()) {
00295 if (z[i].max() == z[j].max()) {
00296 return z[i].min() < z[j].min();
00297 } else {
00298 return z[i].max() < z[j].max();
00299 }
00300 } else {
00301 return x[i].min() < x[j].min();
00302 }
00303 } else {
00304 return x[i].max() < x[j].max();
00305 }
00306 }
00307 };
00308
00318 template<class View>
00319 class TupleMinInc {
00320 public:
00321 bool operator ()(const View& x, const View& y) {
00322 if (x.min() == y.min()) {
00323 return x.max() < y.max();
00324 } else {
00325 return x.min() < y.min();
00326 }
00327 }
00328 };
00329
00330
00332 template<class View>
00333 class ViewPair {
00334 public:
00335 View x;
00336 View z;
00337 };
00338
00349 template<class View>
00350 class TupleMinIncExt {
00351 public:
00352 bool operator ()(const ViewPair<View>& x, const ViewPair<View>& y) {
00353 if (x.x.min() == y.x.min()) {
00354 if (x.x.max() == y.x.max()) {
00355 if (x.z.min() == y.z.min()) {
00356 return x.z.max() < y.z.max();
00357 } else {
00358 return x.z.min() < y.z.min();
00359 }
00360 } else {
00361 return x.x.max() < y.x.max();
00362 }
00363 } else {
00364 return x.x.min() < y.x.min();
00365 }
00366 }
00367 };
00368
00376 template<class View, bool Perm>
00377 inline bool
00378 array_assigned(Space& home,
00379 ViewArray<View>& x,
00380 ViewArray<View>& y,
00381 ViewArray<View>& z,
00382 bool& subsumed,
00383 bool& match_fixed,
00384 bool&,
00385 bool& noperm_bc) {
00386
00387 bool x_complete = true;
00388 bool y_complete = true;
00389 bool z_complete = true;
00390
00391 for (int i=0; i<y.size(); i++) {
00392 x_complete &= x[i].assigned();
00393 y_complete &= y[i].assigned();
00394 if (Perm) {
00395 z_complete &= z[i].assigned();
00396 }
00397 }
00398
00399 if (x_complete) {
00400 for (int i=0; i<x.size(); i++) {
00401 ModEvent me = y[i].eq(home, x[i].val());
00402 if (me_failed(me)) {
00403 return false;
00404 }
00405 }
00406 if (Perm) {
00407 subsumed = false;
00408 } else {
00409 subsumed = true;
00410 }
00411 }
00412
00413 if (y_complete) {
00414 bool y_equality = true;
00415 for (int i=1; i<y.size(); i++) {
00416 y_equality &= (y[i-1].val() == y[i].val());
00417 }
00418 if (y_equality) {
00419 for (int i=0; i<x.size(); i++) {
00420 ModEvent me = x[i].eq(home, y[i].val());
00421 if (me_failed(me)) {
00422 return false;
00423 }
00424 }
00425 if (Perm) {
00426 subsumed = false;
00427 } else {
00428 subsumed = true;
00429 }
00430 noperm_bc = true;
00431 }
00432 }
00433
00434 if (Perm) {
00435 if (z_complete) {
00436 if (x_complete) {
00437 for (int i=0; i<x.size(); i++) {
00438 ModEvent me = y[z[i].val()].eq(home, x[i].val());
00439 if (me_failed(me)) {
00440 return false;
00441 }
00442 }
00443 subsumed = true;
00444 return subsumed;
00445 }
00446 if (y_complete) {
00447 for (int i=0; i<x.size(); i++) {
00448 ModEvent me = x[i].eq(home, y[z[i].val()].val());
00449 if (me_failed(me)) {
00450 return false;
00451 }
00452 }
00453 subsumed = true;
00454 return subsumed;
00455 }
00456
00457
00458 int sum = 0;
00459 for (int i=0; i<x.size(); i++) {
00460 int pi = z[i].val();
00461 if (x[i].max() < y[pi].min() ||
00462 x[i].min() > y[pi].max()) {
00463 return false;
00464 }
00465 sum += pi;
00466 }
00467 int n = x.size();
00468 int gauss = ( (n * (n + 1)) / 2);
00469
00470
00471 if (sum != gauss - n) {
00472 return false;
00473 }
00474 match_fixed = true;
00475 }
00476 }
00477 return true;
00478 }
00479
00487 template<class View>
00488 forceinline bool
00489 channel(Space& home, ViewArray<View>& x, ViewArray<View>& y,
00490 ViewArray<View>& z, bool& nofix) {
00491 int n = x.size();
00492 for (int i=0; i<n; i++) {
00493 if (z[i].assigned()) {
00494 int v = z[i].val();
00495 if (x[i].assigned()) {
00496
00497 ModEvent me = y[v].eq(home, x[i].val());
00498 if (me_failed(me))
00499 return false;
00500 nofix |= me_modified(me);
00501 } else {
00502 if (y[v].assigned()) {
00503
00504 ModEvent me = x[i].eq(home, y[v].val());
00505 if (me_failed(me))
00506 return false;
00507 nofix |= me_modified(me);
00508 } else {
00509
00510 ModEvent me = x[i].lq(home, y[v].max());
00511 if (me_failed(me))
00512 return false;
00513 nofix |= me_modified(me);
00514
00515
00516 me = x[i].gq(home, y[v].min());
00517 if (me_failed(me))
00518 return false;
00519 nofix |= me_modified(me);
00520
00521
00522
00523 me = y[v].lq(home, x[i].max());
00524 if (me_failed(me))
00525 return false;
00526 nofix |= me_modified(me);
00527
00528
00529 me = y[v].gq(home, x[i].min());
00530 if (me_failed(me))
00531 return false;
00532 nofix |= me_modified(me);
00533 }
00534 }
00535 } else {
00536
00537 int l = z[i].min();
00538 int r = z[i].max();
00539
00540 ModEvent me = x[i].lq(home, y[r].max());
00541 if (me_failed(me))
00542 return false;
00543 nofix |= me_modified(me);
00544
00545
00546 me = x[i].gq(home, y[l].min());
00547 if (me_failed(me))
00548 return false;
00549 nofix |= me_modified(me);
00550 }
00551 }
00552 return true;
00553 }
00554
00555
00556 }}}
00557
00558
00559