opt.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 NoOverlap {
00035
00036 template<class Box>
00037 forceinline
00038 OptProp<Box>::OptProp(Home home, Box* b, int n, int m0)
00039 : Base<Box>(home,b,n), m(m0) {
00040 for (int i=0; i<m; i++)
00041 b[n+i].subscribe(home, *this);
00042 }
00043
00044 template<class Box>
00045 ExecStatus
00046 OptProp<Box>::post(Home home, Box* b, int n) {
00047
00048 if (n > 1) {
00049 int p = Base<Box>::partition(b, 0, n);
00050 (void) new (home) OptProp<Box>(home,b,p,n-p);
00051 }
00052 return ES_OK;
00053 }
00054
00055 template<class Box>
00056 forceinline size_t
00057 OptProp<Box>::dispose(Space& home) {
00058 for (int i=0; i<m; i++)
00059 b[n+i].cancel(home, *this);
00060 (void) Base<Box>::dispose(home);
00061 return sizeof(*this);
00062 }
00063
00064
00065 template<class Box>
00066 forceinline
00067 OptProp<Box>::OptProp(Space& home, OptProp<Box>& p)
00068 : Base<Box>(home, p, p.n + p.m), m(p.m) {}
00069
00070 template<class Box>
00071 Actor*
00072 OptProp<Box>::copy(Space& home) {
00073 return new (home) OptProp<Box>(home,*this);
00074 }
00075
00076 template<class Box>
00077 ExecStatus
00078 OptProp<Box>::propagate(Space& home, const ModEventDelta& med) {
00079 Region r;
00080
00081 if (BoolView::me(med) == ME_BOOL_VAL) {
00082
00083 for (int i=m; i--; )
00084 if (b[n+i].excluded()) {
00085 b[n+i].cancel(home,*this);
00086 b[n+i] = b[n+(--m)];
00087 }
00088
00089 if (m > 0) {
00090 int p = Base<Box>::partition(b+n, 0, m);
00091 n += p; m -= p;
00092 }
00093 }
00094
00095
00096 int* db = r.alloc<int>(n);
00097 for (int i=0; i<n; i++)
00098 db[i] = n-1;
00099
00100
00101 int e = 0;
00102 for (int i=0; i<n; i++) {
00103 assert(b[i].mandatory());
00104 for (int j=0; j<i; j++)
00105 if (b[i].nooverlap(b[j])) {
00106 assert(db[i] > 0); assert(db[j] > 0);
00107 if (--db[i] == 0) e++;
00108 if (--db[j] == 0) e++;
00109 continue;
00110 } else {
00111 GECODE_ES_CHECK(b[i].nooverlap(home,b[j]));
00112 }
00113 }
00114
00115 if (m == 0) {
00116 if (e == n)
00117 return home.ES_SUBSUMED(*this);
00118 int i = n-1;
00119 while (e > 0) {
00120
00121 while (db[i] > 0)
00122 i--;
00123 b[i].cancel(home, *this);
00124 b[i] = b[--n]; b[n] = b[n+m];
00125 e--; i--;
00126 }
00127 if (n < 2)
00128 return home.ES_SUBSUMED(*this);
00129 }
00130
00131
00132 for (int i=m; i--; ) {
00133 if (b[n+i].optional()) {
00134 for (int j=n; j--; )
00135 if (b[n+i].overlap(b[j])) {
00136 GECODE_ES_CHECK(b[n+i].exclude(home));
00137 b[n+i].cancel(home,*this);
00138 b[n+i] = b[n+(--m)];
00139 break;
00140 }
00141 } else {
00142
00143
00144 assert(b[n+i].excluded());
00145 b[n+i].cancel(home,*this);
00146 b[n+i] = b[n+(--m)];
00147 }
00148 }
00149
00150 return ES_NOFIX;
00151 }
00152
00153 }}}
00154
00155
00156