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/linear.hh"
00039
00040 namespace Gecode { namespace Int { namespace Linear {
00041
00042 void
00043 post_pos_unit(Space* home,
00044 Term<BoolView>* t_p, int n_p,
00045 IntRelType r, IntView y, int c,
00046 PropKind) {
00047 switch (r) {
00048 case IRT_EQ:
00049 {
00050 ViewArray<BoolView> x(home,n_p);
00051 for (int i=n_p; i--; )
00052 x[i]=t_p[i].x;
00053 GECODE_ES_FAIL(home,(EqBoolView<BoolView,IntView>
00054 ::post(home,x,y,c)));
00055 }
00056 break;
00057 case IRT_NQ:
00058 {
00059 ViewArray<BoolView> x(home,n_p);
00060 for (int i=n_p; i--; )
00061 x[i]=t_p[i].x;
00062 GECODE_ES_FAIL(home,(NqBoolView<BoolView,IntView>
00063 ::post(home,x,y,c)));
00064 }
00065 break;
00066 case IRT_GQ:
00067 {
00068 ViewArray<BoolView> x(home,n_p);
00069 for (int i=n_p; i--; )
00070 x[i]=t_p[i].x;
00071 GECODE_ES_FAIL(home,(GqBoolView<BoolView,IntView>
00072 ::post(home,x,y,c)));
00073 }
00074 break;
00075 case IRT_LQ:
00076 {
00077 ViewArray<NegBoolView> x(home,n_p);
00078 for (int i=n_p; i--; )
00079 x[i]=t_p[i].x;
00080 MinusView z(y);
00081 GECODE_ES_FAIL(home,(GqBoolView<NegBoolView,MinusView>
00082 ::post(home,x,z,n_p-c)));
00083 }
00084 break;
00085 default: GECODE_NEVER;
00086 }
00087 }
00088
00089 void
00090 post_pos_unit(Space* home,
00091 Term<BoolView>* t_p, int n_p,
00092 IntRelType r, ZeroIntView, int c,
00093 PropKind pk) {
00094 switch (r) {
00095 case IRT_EQ:
00096 {
00097 ViewArray<BoolView> x(home,n_p);
00098 for (int i=n_p; i--; )
00099 x[i]=t_p[i].x;
00100 GECODE_ES_FAIL(home,(EqBoolInt<BoolView>::post(home,x,c,pk)));
00101 }
00102 break;
00103 case IRT_NQ:
00104 {
00105 ViewArray<BoolView> x(home,n_p);
00106 for (int i=n_p; i--; )
00107 x[i]=t_p[i].x;
00108 GECODE_ES_FAIL(home,(NqBoolInt<BoolView>::post(home,x,c)));
00109 }
00110 break;
00111 case IRT_GQ:
00112 {
00113 ViewArray<BoolView> x(home,n_p);
00114 for (int i=n_p; i--; )
00115 x[i]=t_p[i].x;
00116 GECODE_ES_FAIL(home,(GqBoolInt<BoolView>::post(home,x,c,pk)));
00117 }
00118 break;
00119 case IRT_LQ:
00120 {
00121 ViewArray<NegBoolView> x(home,n_p);
00122 for (int i=n_p; i--; )
00123 x[i]=t_p[i].x;
00124 GECODE_ES_FAIL(home,(GqBoolInt<NegBoolView>::post(home,x,n_p-c,pk)));
00125 }
00126 break;
00127 default: GECODE_NEVER;
00128 }
00129 }
00130
00131 void
00132 post_neg_unit(Space* home,
00133 Term<BoolView>* t_n, int n_n,
00134 IntRelType r, IntView y, int c,
00135 PropKind) {
00136 switch (r) {
00137 case IRT_EQ:
00138 {
00139 ViewArray<BoolView> x(home,n_n);
00140 for (int i=n_n; i--; )
00141 x[i]=t_n[i].x;
00142 MinusView z(y);
00143 GECODE_ES_FAIL(home,(EqBoolView<BoolView,MinusView>
00144 ::post(home,x,z,-c)));
00145 }
00146 break;
00147 case IRT_NQ:
00148 {
00149 ViewArray<BoolView> x(home,n_n);
00150 for (int i=n_n; i--; )
00151 x[i]=t_n[i].x;
00152 MinusView z(y);
00153 GECODE_ES_FAIL(home,(NqBoolView<BoolView,MinusView>
00154 ::post(home,x,z,-c)));
00155 }
00156 break;
00157 case IRT_GQ:
00158 {
00159 ViewArray<NegBoolView> x(home,n_n);
00160 for (int i=n_n; i--; )
00161 x[i]=t_n[i].x;
00162 GECODE_ES_FAIL(home,(GqBoolView<NegBoolView,IntView>
00163 ::post(home,x,y,n_n+c)));
00164 }
00165 break;
00166 case IRT_LQ:
00167 {
00168 ViewArray<BoolView> x(home,n_n);
00169 for (int i=n_n; i--; )
00170 x[i]=t_n[i].x;
00171 MinusView z(y);
00172 GECODE_ES_FAIL(home,(GqBoolView<BoolView,MinusView>
00173 ::post(home,x,z,-c)));
00174 }
00175 break;
00176 default: GECODE_NEVER;
00177 }
00178 }
00179
00180 void
00181 post_neg_unit(Space* home,
00182 Term<BoolView>* t_n, int n_n,
00183 IntRelType r, ZeroIntView, int c,
00184 PropKind pk) {
00185 switch (r) {
00186 case IRT_EQ:
00187 {
00188 ViewArray<BoolView> x(home,n_n);
00189 for (int i=n_n; i--; )
00190 x[i]=t_n[i].x;
00191 GECODE_ES_FAIL(home,(EqBoolInt<BoolView>::post(home,x,-c,pk)));
00192 }
00193 break;
00194 case IRT_NQ:
00195 {
00196 ViewArray<BoolView> x(home,n_n);
00197 for (int i=n_n; i--; )
00198 x[i]=t_n[i].x;
00199 GECODE_ES_FAIL(home,(NqBoolInt<BoolView>::post(home,x,-c)));
00200 }
00201 break;
00202 case IRT_GQ:
00203 {
00204 ViewArray<NegBoolView> x(home,n_n);
00205 for (int i=n_n; i--; )
00206 x[i]=t_n[i].x;
00207 GECODE_ES_FAIL(home,(GqBoolInt<NegBoolView>::post(home,x,n_n+c,pk)));
00208 }
00209 break;
00210 case IRT_LQ:
00211 {
00212 ViewArray<BoolView> x(home,n_n);
00213 for (int i=n_n; i--; )
00214 x[i]=t_n[i].x;
00215 GECODE_ES_FAIL(home,(GqBoolInt<BoolView>::post(home,x,-c,pk)));
00216 }
00217 break;
00218 default: GECODE_NEVER;
00219 }
00220 }
00221
00222
00223 void
00224 post_mixed(Space* home,
00225 Term<BoolView>* t_p, int n_p,
00226 Term<BoolView>* t_n, int n_n,
00227 IntRelType r, IntView y, int c) {
00228 ScaleBoolArray b_p(home,n_p);
00229 {
00230 ScaleBool* f=b_p.fst();
00231 for (int i=n_p; i--; ) {
00232 f[i].x=t_p[i].x; f[i].a=t_p[i].a;
00233 }
00234 }
00235 ScaleBoolArray b_n(home,n_n);
00236 {
00237 ScaleBool* f=b_n.fst();
00238 for (int i=n_n; i--; ) {
00239 f[i].x=t_n[i].x; f[i].a=t_n[i].a;
00240 }
00241 }
00242 switch (r) {
00243 case IRT_EQ:
00244 GECODE_ES_FAIL(home,
00245 (EqBoolScale<ScaleBoolArray,ScaleBoolArray,IntView>
00246 ::post(home,b_p,b_n,y,c)));
00247 break;
00248 case IRT_NQ:
00249 GECODE_ES_FAIL(home,
00250 (NqBoolScale<ScaleBoolArray,ScaleBoolArray,IntView>
00251 ::post(home,b_p,b_n,y,c)));
00252 break;
00253 case IRT_LQ:
00254 GECODE_ES_FAIL(home,
00255 (LqBoolScale<ScaleBoolArray,ScaleBoolArray,IntView>
00256 ::post(home,b_p,b_n,y,c)));
00257 break;
00258 case IRT_GQ:
00259 {
00260 MinusView m(y);
00261 GECODE_ES_FAIL(home,
00262 (LqBoolScale<ScaleBoolArray,ScaleBoolArray,MinusView>
00263 ::post(home,b_n,b_p,m,-c)));
00264 }
00265 break;
00266 default:
00267 GECODE_NEVER;
00268 }
00269 }
00270
00271
00272 void
00273 post_mixed(Space* home,
00274 Term<BoolView>* t_p, int n_p,
00275 Term<BoolView>* t_n, int n_n,
00276 IntRelType r, ZeroIntView y, int c) {
00277 ScaleBoolArray b_p(home,n_p);
00278 {
00279 ScaleBool* f=b_p.fst();
00280 for (int i=n_p; i--; ) {
00281 f[i].x=t_p[i].x; f[i].a=t_p[i].a;
00282 }
00283 }
00284 ScaleBoolArray b_n(home,n_n);
00285 {
00286 ScaleBool* f=b_n.fst();
00287 for (int i=n_n; i--; ) {
00288 f[i].x=t_n[i].x; f[i].a=t_n[i].a;
00289 }
00290 }
00291 switch (r) {
00292 case IRT_EQ:
00293 GECODE_ES_FAIL(home,
00294 (EqBoolScale<ScaleBoolArray,ScaleBoolArray,ZeroIntView>
00295 ::post(home,b_p,b_n,y,c)));
00296 break;
00297 case IRT_NQ:
00298 GECODE_ES_FAIL(home,
00299 (NqBoolScale<ScaleBoolArray,ScaleBoolArray,ZeroIntView>
00300 ::post(home,b_p,b_n,y,c)));
00301 break;
00302 case IRT_LQ:
00303 GECODE_ES_FAIL(home,
00304 (LqBoolScale<ScaleBoolArray,ScaleBoolArray,ZeroIntView>
00305 ::post(home,b_p,b_n,y,c)));
00306 break;
00307 case IRT_GQ:
00308 GECODE_ES_FAIL(home,
00309 (LqBoolScale<ScaleBoolArray,ScaleBoolArray,ZeroIntView>
00310 ::post(home,b_n,b_p,y,-c)));
00311 break;
00312 default:
00313 GECODE_NEVER;
00314 }
00315 }
00316
00317 template <class View>
00318 forceinline void
00319 post_all(Space* home,
00320 Term<BoolView>* t, int n,
00321 IntRelType r, View x, int c, PropKind pk) {
00322
00323 Limits::check(c,"Int::linear");
00324
00325 {
00326 double d = c;
00327
00328
00329 switch (r) {
00330 case IRT_EQ: case IRT_NQ: case IRT_LQ: case IRT_GQ:
00331 break;
00332 case IRT_LE:
00333 d--; r = IRT_LQ; break;
00334 case IRT_GR:
00335 d++; r = IRT_GQ; break;
00336 default:
00337 throw UnknownRelation("Int::linear");
00338 }
00339
00340
00341 for (int i=n; i--; )
00342 if (t[i].x.one()) {
00343 d -= t[i].a; t[i]=t[--n];
00344 } else if (t[i].x.zero()) {
00345 t[i]=t[--n];
00346 }
00347
00348 Limits::check(d,"Int::linear");
00349
00350 c = static_cast<int>(d);
00351 }
00352
00353 Term<BoolView> *t_p, *t_n;
00354 int n_p, n_n;
00355 bool unit = normalize<BoolView>(t,n,t_p,n_p,t_n,n_n);
00356
00357 if (n == 0) {
00358 switch (r) {
00359 case IRT_EQ: GECODE_ME_FAIL(home,x.eq(home,-c)); break;
00360 case IRT_NQ: GECODE_ME_FAIL(home,x.nq(home,-c)); break;
00361 case IRT_GQ: GECODE_ME_FAIL(home,x.lq(home,-c)); break;
00362 case IRT_LQ: GECODE_ME_FAIL(home,x.gq(home,-c)); break;
00363 default: GECODE_NEVER;
00364 }
00365 return;
00366 }
00367
00368
00369 {
00370 double sl = x.max()+c;
00371 double su = x.min()+c;
00372 for (int i=n_p; i--; )
00373 su -= t_p[i].a;
00374 for (int i=n_n; i--; )
00375 sl += t_n[i].a;
00376 Limits::check(sl,"Int::linear");
00377 Limits::check(su,"Int::linear");
00378 }
00379
00380 if (unit && (n_n == 0)) {
00382 post_pos_unit(home,t_p,n_p,r,x,c,pk);
00383 } else if (unit && (n_p == 0)) {
00384
00385 post_neg_unit(home,t_n,n_n,r,x,c,pk);
00386 } else {
00387
00388 post_mixed(home,t_p,n_p,t_n,n_n,r,x,c);
00389 }
00390 }
00391
00392
00393 void
00394 post(Space* home,
00395 Term<BoolView>* t, int n, IntRelType r, IntView x, int c,
00396 IntConLevel, PropKind pk) {
00397 post_all(home,t,n,r,x,c,pk);
00398 }
00399
00400 void
00401 post(Space* home,
00402 Term<BoolView>* t, int n, IntRelType r, int c,
00403 IntConLevel, PropKind pk) {
00404 ZeroIntView x;
00405 post_all(home,t,n,r,x,c,pk);
00406 }
00407
00408 void
00409 post(Space* home,
00410 Term<BoolView>* t, int n, IntRelType r, IntView x, BoolView b,
00411 IntConLevel icl, PropKind pk) {
00412 int l, u;
00413 estimate(t,n,0,l,u);
00414 IntVar z(home,l,u); IntView zv(z);
00415 post_all(home,t,n,IRT_EQ,zv,0,pk);
00416 rel(home,z,r,x,b,icl,pk);
00417 }
00418
00419 void
00420 post(Space* home,
00421 Term<BoolView>* t, int n, IntRelType r, int c, BoolView b,
00422 IntConLevel icl, PropKind pk) {
00423 int l, u;
00424 estimate(t,n,0,l,u);
00425 IntVar z(home,l,u); IntView zv(z);
00426 post_all(home,t,n,IRT_EQ,zv,0,pk);
00427 rel(home,z,r,c,b,icl,pk);
00428 }
00429
00430 }}}
00431
00432
00433