00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 namespace Gecode { namespace Int { namespace Sortedness {
00023
00025 template<class View>
00026 void pview(View& v){
00027 if (v.min() == v.max()) {
00028 std::cout << v.min() <<" ";
00029 } else {
00030 if (v.range()){
00031 std::cout << "["<<v.min() <<".."<<v.max()<<"] ";
00032 } else {
00033 std::cout << "{";
00034 ViewValues<View> iter(v);
00035 while(iter()){
00036 std::cout << iter.val() <<",";
00037 ++iter;
00038 }
00039 std::cout << "} ";
00040 }
00041 }
00042 }
00043
00045 template <class T, unsigned int n>
00046 inline std::ostream&
00047 operator<<(std::ostream& os, ViewTuple<T,n>& xs) {
00048 if (n > 1) { os << "<";}
00049 if (xs[0].min() == xs[0].max()) {
00050 os << xs[0].min();
00051 if (n > 1) {
00052 std::cout << ",";
00053 if (xs[1].min() == xs[1].max()) {
00054 os << xs[1].min() <<" ";
00055 } else {
00056 os << "["<<xs[1].min() <<".."<<xs[1].max()<<"]("<<xs[1].range()<<") ";
00057 }
00058 }
00059 } else {
00060 os << "["<<xs[0].min() <<".."<<xs[0].max()<<"]("<<xs[0].range()<<")";
00061 if (n > 1) {
00062 std::cout << ", ";
00063 if (xs[1].min() == xs[1].max()) {
00064 os << xs[1].min() <<" ";
00065 } else {
00066 os << "["<<xs[1].min() <<".."<<xs[1].max()<<"]("<<xs[1].range()<<") ";
00067 }
00068 }
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 if (n > 1) { os << ">";}
00080 return os;
00081 }
00082
00086 class Rank {
00087 public:
00088
00089 int min;
00090
00091 int max;
00092 };
00093
00100 class SccComponent {
00101 public:
00103 int leftmost;
00105 int left;
00107 int right;
00109 int rightmost;
00110 };
00111
00125 template<class View, class Tuple, bool Perm>
00126 forceinline bool
00127 check_subsumption(Space* home,
00128 ViewArray<Tuple>& xz,
00129 ViewArray<View>& y,
00130 bool& subsumed,
00131 int& dropfst) {
00132
00133 dropfst = 0;
00134 subsumed = true;
00135 int xs = xz.size();
00136 for (int i = 0; i < xs ; i++) {
00137 if (Perm) {
00138 subsumed &= (xz[i][0].assigned() &&
00139 xz[i][1].assigned() &&
00140 y[xz[i][1].val()].assigned());
00141 if (subsumed) {
00142 if (xz[i][0].val() != y[xz[i][1].val()].val()) {
00143 return false;
00144 } else {
00145 if (xz[i][1].val() == i) {
00146 dropfst++;
00147 }
00148 }
00149 }
00150 } else {
00151 subsumed &= (xz[i][0].assigned() && y[i].assigned());
00152 if (subsumed) {
00153 if (xz[i][0].val() != y[i].val()) {
00154 return false;
00155 } else {
00156 dropfst++;
00157 }
00158 }
00159 }
00160 }
00161 return true;
00162 }
00163
00169 class OfflineMinItem{
00170 public:
00172 int root;
00174 int parent;
00176 int rank;
00178 int name;
00186 int iset;
00188 int succ;
00190 int pred;
00191 };
00192
00198 class OfflineMin {
00199 private:
00200 OfflineMinItem* sequence;
00201 int* vertices;
00202 int n;
00203 public:
00204 OfflineMin(void);
00205 OfflineMin(OfflineMinItem[], int[], int);
00210 int find(int x);
00215 int find_pc(int x);
00217 void unite(int a, int b, int c);
00219 void makeset(void);
00221 int size(void);
00222 OfflineMinItem& operator[](int);
00223 };
00224
00225 OfflineMin::OfflineMin(void){
00226 n = 0;
00227 sequence = NULL;
00228 vertices = NULL;
00229 }
00230
00231 OfflineMin::OfflineMin(OfflineMinItem s[], int v[], int size){
00232 n = size;
00233 sequence = &s[0];
00234 vertices = &v[0];
00235 }
00236
00237 forceinline int
00238 OfflineMin::find(int x) {
00239 while (sequence[x].parent != x) {
00240 x = sequence[x].parent;
00241 }
00242
00243
00244 return sequence[x].name;
00245 }
00246
00247 forceinline int
00248 OfflineMin::find_pc(int x){
00249 int vsize = 0;
00250 while (sequence[x].parent != x) {
00251 vertices[x] = x;
00252 x = sequence[x].parent;
00253 }
00254
00255 for (int i = vsize; i--; ) {
00256 sequence[vertices[i]].parent = x;
00257 }
00258
00259 return sequence[x].name;
00260 }
00261
00262 forceinline void
00263 OfflineMin::unite(int a, int b, int c){
00264
00265 int ra = sequence[a].root;
00266 int rb = sequence[b].root;
00267 int large = rb;
00268 int small = ra;
00269 if (sequence[ra].rank > sequence[rb].rank) {
00270 large = ra;
00271 small = rb;
00272 }
00273 sequence[small].parent = large;
00274 sequence[large].rank += sequence[small].rank;
00275 sequence[large].name = c;
00276 sequence[c].root = large;
00277 }
00278
00279 forceinline void
00280 OfflineMin::makeset(void){
00281 for(int i = n; i--; ){
00282 OfflineMinItem& cur = sequence[i];
00283 cur.rank = 0;
00284 cur.name = i;
00285 cur.root = i;
00286 cur.parent = i;
00287 cur.pred = i - 1;
00288 cur.succ = i + 1;
00289 cur.iset = -5;
00290 }
00291 }
00292
00293 forceinline int
00294 OfflineMin::size(void){
00295 return n;
00296 }
00297
00298 forceinline OfflineMinItem&
00299 OfflineMin::operator [](int i){
00300 return sequence[i];
00301 }
00302
00304 forceinline std::ostream&
00305 operator<<(std::ostream& os, OfflineMin seq){
00306 for (int i = 0; i < seq.size();i++) {
00307 os << "Succ(" <<seq[i].succ << ") "
00308 << "Pred(" <<seq[i].pred << ") "
00309 << "Root(" <<seq[i].root << ") "
00310 << "Par (" <<seq[i].parent << ") "
00311 << "Rank(" <<seq[i].rank << ") "
00312 << "Name(" <<seq[i].name << ") "
00313 << "Set (" <<seq[i].iset << ") \n";
00314 }
00315 return os;
00316 }
00317
00327 template <class Tuple>
00328 class TupleMaxInc {
00329 protected:
00330 ViewArray<Tuple> x;
00331 public:
00332 TupleMaxInc(const ViewArray<Tuple>& x0) : x(x0) {}
00333 bool operator()(const int i, const int j) {
00334 if (x[i][0].max() == x[j][0].max()) {
00335 return x[i][0].min() < x[j][0].min();
00336 } else {
00337 return x[i][0].max() < x[j][0].max();
00338 }
00339 }
00340 };
00341
00342
00352 template <class Tuple>
00353 class TupleMaxIncExt {
00354 protected:
00355 ViewArray<Tuple> x;
00356 public:
00357 TupleMaxIncExt(const ViewArray<Tuple>& x0) : x(x0) {}
00358 bool operator()(const int i, const int j) {
00359 if (x[i][0].max() == x[j][0].max()) {
00360 if (x[i][0].min() == x[j][0].min()) {
00361 if (x[i][1].max() == x[j][1].max()) {
00362 return x[i][1].min() < x[j][1].min();
00363 } else {
00364 return x[i][1].max() < x[j][1].max();
00365 }
00366 } else {
00367 return x[i][0].min() < x[j][0].min();
00368 }
00369 } else {
00370 return x[i][0].max() < x[j][0].max();
00371 }
00372 }
00373 };
00374
00384 template <class View>
00385 class TupleMinInc {
00386 public:
00387 bool operator()(const View& x, const View& y) {
00388 if (x[0].min() == y[0].min()) {
00389 return x[0].max() < y[0].max();
00390 } else {
00391 return x[0].min() < y[0].min();
00392 }
00393 }
00394 };
00395
00407 template <class View>
00408 class TupleMinIncExt {
00409 public:
00410 bool operator()(const View& x, const View& y) {
00411 if (x[0].min() == y[0].min()) {
00412 if (x[0].max() == y[0].max()) {
00413 if (x[1].min() == y[1].min()) {
00414 return x[1].max() < y[1].max();
00415 } else {
00416 return x[1].min() < y[1].min();
00417 }
00418 } else {
00419 return x[0].max() < y[0].max();
00420 }
00421 } else {
00422 return x[0].min() < y[0].min();
00423 }
00424 }
00425 };
00426
00435 template <class View>
00436 class TupleMinIncPerm {
00437 public:
00438 bool operator()(const View& x, const View& y) {
00439 if (x[1].min() == y[1].min()) {
00440 return x[1].max() < y[1].max();
00441 } else {
00442 return x[1].min() < y[1].min();
00443 }
00444 }
00445 };
00446
00455 template <class View>
00456 class TupleMaxIncPerm {
00457 public:
00458 bool operator()(const View& x, const View& y) {
00459 if (x[1].max() == y[1].max()) {
00460 return x[1].min() < y[1].min();
00461 } else {
00462 return x[1].max() < y[1].max();
00463 }
00464 }
00465 };
00466
00474 template<class View, class Tuple, bool Perm>
00475 forceinline bool
00476 array_assigned(Space* home,
00477 ViewArray<Tuple>& xz,
00478 ViewArray<View>& y,
00479 bool& subsumed,
00480 bool& match_fixed,
00481 bool& nofix,
00482 bool& noperm_bc) {
00483
00484 bool x_complete = true;
00485 bool y_complete = true;
00486 bool z_complete = true;
00487
00488 for (int i = y.size(); i--; ) {
00489 x_complete &= xz[i][0].assigned();
00490 y_complete &= y[i].assigned();
00491 if (Perm) {
00492 z_complete &= xz[i][1].assigned();
00493 }
00494 }
00495
00496 if (x_complete) {
00497 for (int i = xz.size(); i--; ) {
00498 ModEvent me = y[i].eq(home, xz[i][0].val());
00499 if (me_failed(me)) {
00500 return false;
00501 }
00502 }
00503 if (Perm) {
00504 subsumed = false;
00505 } else {
00506 subsumed = true;
00507 }
00508 }
00509
00510 if (y_complete) {
00511 bool y_equality = true;
00512 for (int i = y.size() - 1; i--; ) {
00513 y_equality &= (y[i].val() == y[i + 1].val());
00514 }
00515 if (y_equality) {
00516 for (int i = xz.size(); i--; ) {
00517 ModEvent me = xz[i][0].eq(home, y[i].val());
00518 if (me_failed(me)) {
00519 return false;
00520 }
00521 }
00522 if (Perm) {
00523 subsumed = false;
00524 } else {
00525 subsumed = true;
00526 }
00527 noperm_bc = true;
00528 }
00529 }
00530
00531 if (Perm) {
00532 if (z_complete) {
00533 if (x_complete) {
00534 for (int i = xz.size(); i--; ) {
00535 ModEvent me = y[xz[i][1].val()].eq(home, xz[i][0].val());
00536 if (me_failed(me)) {
00537 return false;
00538 }
00539 }
00540 subsumed = true;
00541 return subsumed;
00542 }
00543 if (y_complete) {
00544 for (int i = xz.size(); i--; ) {
00545 ModEvent me = xz[i][0].eq(home, y[xz[i][1].val()].val());
00546 if (me_failed(me)) {
00547 return false;
00548 }
00549 }
00550 subsumed = true;
00551 return subsumed;
00552 }
00553
00554
00555 int sum = 0;
00556 for (int i = xz.size(); i--; ) {
00557 int pi = xz[i][1].val();
00558 if (xz[i][0].max() < y[pi].min() ||
00559 xz[i][0].min() > y[pi].max()) {
00560 return false;
00561 }
00562 sum += pi;
00563 }
00564 int n = xz.size();
00565 int gauss = ( (n * (n + 1)) / 2);
00566
00567
00568 if (sum != gauss - n) {
00569 return false;
00570 }
00571 match_fixed = true;
00572 }
00573 }
00574 return true;
00575 }
00576
00584 template<class View, class Tuple, bool Perm>
00585 forceinline bool
00586 channel(Space* home, ViewArray<Tuple>& xz, ViewArray<View>& y, bool& nofix) {
00587 int n = xz.size();
00588 for (int i = n; i--; ) {
00589 if (xz[i][1].assigned()) {
00590
00591
00592
00593 int v = xz[i][1].val();
00594 if (xz[i][0].assigned()) {
00595
00596 ModEvent me = y[v].eq(home, xz[i][0].val());
00597 if (me_failed(me)) {
00598 return false;
00599 }
00600 } else {
00601 if (y[v].assigned()) {
00602
00603 ModEvent me = xz[i][0].eq(home, y[v].val());
00604 if (me_failed(me)) {
00605 return false;
00606 }
00607 } else {
00608
00609 ModEvent me = xz[i][0].lq(home, y[v].max());
00610 if (me_failed(me)) {
00611 return false;
00612 }
00613 nofix |= (me_modified(me) && xz[i][0].max() != y[v].max());
00614
00615
00616 me = xz[i][0].gq(home, y[v].min());
00617 if (me_failed(me)) {
00618 return false;
00619 }
00620 nofix |= (me_modified(me) && xz[i][0].min() != y[v].min());
00621
00622
00623
00624 me = y[v].lq(home, xz[i][0].max());
00625 if (me_failed(me)) {
00626 return false;
00627 }
00628 nofix |= (me_modified(me) && y[v].max() != xz[i][0].max());
00629
00630
00631 me = y[v].gq(home, xz[i][0].min());
00632 if (me_failed(me)) {
00633 return false;
00634 }
00635 nofix |= (me_modified(me) && y[v].min() != xz[i][0].min());
00636 }
00637 }
00638 } else {
00639
00640
00641 int l = xz[i][1].min();
00642 int r = xz[i][1].max();
00643
00644
00645 ModEvent me = xz[i][0].lq(home, y[r].max());
00646 if (me_failed(me)) {
00647 return false;
00648 }
00649 nofix |= (me_modified(me) && xz[i][0].max() != y[r].max());
00650
00651
00652 me = xz[i][0].gq(home, y[l].min());
00653 if (me_failed(me)) {
00654 return false;
00655 }
00656 nofix |= (me_modified(me) && xz[i][0].min() != y[l].min());
00657 }
00658 }
00659 return true;
00660 }
00661
00662
00663 }}}
00664
00665
00666