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
00035
00036
00037
00038 #include <gecode/int/rel.hh>
00039
00040 namespace Gecode { namespace Int { namespace Arithmetic {
00041
00042 template<class VA, class VB, bool tiebreak>
00043 forceinline
00044 ArgMax<VA,VB,tiebreak>::ArgMax(Home home, IdxViewArray<VA>& x0, VB y0)
00045 : Propagator(home), x(x0), y(y0) {
00046 x.subscribe(home,*this,PC_INT_BND);
00047 y.subscribe(home,*this,PC_INT_DOM);
00048 }
00049
00050 template<class VA, class VB, bool tiebreak>
00051 ExecStatus
00052 ArgMax<VA,VB,tiebreak>::post(Home home, IdxViewArray<VA>& x, VB y) {
00053 assert(x.size() > 0);
00054 if (x.size() == 1) {
00055 GECODE_ME_CHECK(y.eq(home,x[0].idx));
00056 } else if (y.assigned()) {
00057 int max=0;
00058 while (x[max].idx < y.val())
00059 max++;
00060 assert(x[max].idx == y.val());
00061 if (tiebreak)
00062 for (int i=0; i<max; i++)
00063 GECODE_ES_CHECK(Rel::Le<VA>::post(home,
00064 x[i].view,x[max].view));
00065 else
00066 for (int i=0; i<max; i++)
00067 GECODE_ES_CHECK(Rel::Lq<VA>::post(home,
00068 x[i].view,x[max].view));
00069 for (int i=max+1; i<x.size(); i++)
00070 GECODE_ES_CHECK(Rel::Lq<VA>::post(home,
00071 x[i].view,x[max].view));
00072 } else {
00073 (void) new (home) ArgMax<VA,VB,tiebreak>(home,x,y);
00074 }
00075 return ES_OK;
00076 }
00077
00078 template<class VA, class VB, bool tiebreak>
00079 forceinline
00080 ArgMax<VA,VB,tiebreak>::ArgMax(Space& home, bool share,
00081 ArgMax<VA,VB,tiebreak>& p)
00082 : Propagator(home,share,p) {
00083 x.update(home,share,p.x);
00084 y.update(home,share,p.y);
00085 }
00086
00087 template<class VA, class VB, bool tiebreak>
00088 Actor*
00089 ArgMax<VA,VB,tiebreak>::copy(Space& home, bool share) {
00090 return new (home) ArgMax<VA,VB,tiebreak>(home,share,*this);
00091 }
00092
00093 template<class VA, class VB, bool tiebreak>
00094 PropCost
00095 ArgMax<VA,VB,tiebreak>::cost(const Space&,
00096 const ModEventDelta&) const {
00097 return PropCost::linear(PropCost::LO,x.size()+1);
00098 }
00099
00100 template<class VA, class VB, bool tiebreak>
00101 ExecStatus
00102 ArgMax<VA,VB,tiebreak>::propagate(Space& home, const ModEventDelta&) {
00103
00104
00105
00106
00107
00108
00109 int p = x[0].idx;
00110 int l = x[0].view.min();
00111 int u = x[0].view.max();
00112 for (int i=1; i<x.size(); i++) {
00113 if (l < x[i].view.min()) {
00114 p = x[i].idx; l = x[i].view.min();
00115 }
00116 if (u < x[i].view.max())
00117 u = x[i].view.max();
00118 }
00119
00120
00121 {
00122 Region r(home);
00123
00124
00125 int* d=r.alloc<int>(y.size());
00126
00127 int n = 0;
00128
00129 int i=0, j=0;
00130 ViewValues<VB> iy(y);
00131
00132 while ((i < x.size()) && iy()) {
00133 if (x[i].idx == iy.val()) {
00134 if (x[i].view.max() < l) {
00135 x[i].view.cancel(home,*this,PC_INT_BND);
00136 d[n++]=x[i].idx;
00137 } else {
00138 x[j++]=x[i];
00139 }
00140 ++iy;
00141 } else {
00142 assert(x[i].idx < iy.val());
00143 if (x[i].view.max() < l) {
00144 x[i].view.cancel(home,*this,PC_INT_BND);
00145 } else {
00146 x[j++]=x[i];
00147 }
00148 }
00149 i++;
00150 }
00151 while (i < x.size())
00152 if (x[i].view.max() < l) {
00153 x[i].view.cancel(home,*this,PC_INT_BND); i++;
00154 } else {
00155 x[j++]=x[i++];
00156 }
00157 x.size(j);
00158
00159 if (static_cast<unsigned int>(n) == y.size())
00160 return ES_FAILED;
00161 Iter::Values::Array id(d,n);
00162 GECODE_ME_CHECK(y.minus_v(home,id,false));
00163 }
00164
00165
00166
00167
00168
00169
00170
00171 if (tiebreak && (l == u))
00172 GECODE_ME_CHECK(y.lq(home,p));
00173
00174 if (y.assigned()) {
00175 int max=0;
00176 while (x[max].idx < y.val())
00177 max++;
00178 assert(x[max].idx == y.val());
00179 if (tiebreak)
00180 for (int i=0; i<max; i++)
00181 GECODE_ES_CHECK(Rel::Le<VA>::post(home(*this),
00182 x[i].view,x[max].view));
00183 else
00184 for (int i=0; i<max; i++)
00185 GECODE_ES_CHECK(Rel::Lq<VA>::post(home(*this),
00186 x[i].view,x[max].view));
00187 for (int i=max+1; i<x.size(); i++)
00188 GECODE_ES_CHECK(Rel::Lq<VA>::post(home(*this),
00189 x[i].view,x[max].view));
00190 return home.ES_SUBSUMED(*this);
00191 }
00192
00193
00194 {
00195 ViewValues<VB> iy(y);
00196 int i=0;
00197
00198 while (x[i].idx < y.min())
00199 i++;
00200 u=x[i].view.max();
00201
00202 i++; ++iy;
00203 while (iy()) {
00204 if (x[i].idx == iy.val()) {
00205 u = std::max(u,x[i].view.max());
00206 ++iy;
00207 } else {
00208 assert(x[i].idx < iy.val());
00209 }
00210 i++;
00211 }
00212 }
00213
00214
00215 {
00216 int i = 0;
00217
00218 if (tiebreak)
00219 while ((i < x.size()) && (x[i].idx < y.min())) {
00220 GECODE_ME_CHECK(x[i].view.le(home,u));
00221 i++;
00222 }
00223 else
00224 while ((i < x.size()) && (x[i].idx < y.min())) {
00225 GECODE_ME_CHECK(x[i].view.lq(home,u));
00226 i++;
00227 }
00228 assert(x[i].idx == y.min());
00229
00230
00231 ViewValues<VB> iy(y);
00232
00233 i++; ++iy;
00234 while ((i < x.size()) && iy()) {
00235 if (x[i].idx == iy.val()) {
00236 ++iy;
00237 } else {
00238 assert(x[i].idx < iy.val());
00239 GECODE_ME_CHECK(x[i].view.lq(home,u));
00240 }
00241 i++;
00242 }
00243 while (i < x.size()) {
00244 assert(x[i].idx > y.max());
00245 GECODE_ME_CHECK(x[i].view.lq(home,u));
00246 i++;
00247 }
00248 }
00249 return tiebreak ? ES_NOFIX : ES_FIX;
00250 }
00251
00252 template<class VA, class VB, bool tiebreak>
00253 forceinline size_t
00254 ArgMax<VA,VB,tiebreak>::dispose(Space& home) {
00255 x.cancel(home,*this,PC_INT_BND);
00256 y.cancel(home,*this,PC_INT_DOM);
00257 (void) Propagator::dispose(home);
00258 return sizeof(*this);
00259 }
00260
00261 }}}
00262
00263
00264