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 #include <gecode/int/cumulative.hh>
00037
00038 #include <algorithm>
00039
00040 namespace Gecode { namespace Int { namespace Cumulative {
00041
00042 template<class Cap>
00043 void
00044 cumulative(Home home, Cap c, const TaskTypeArgs& t,
00045 const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
00046 IntPropLevel ipl) {
00047 if ((s.size() != p.size()) || (s.size() != u.size()) ||
00048 (s.size() != t.size()))
00049 throw ArgumentSizeMismatch("Int::cumulative");
00050 long long int w = 0;
00051 for (int i=0; i<p.size(); i++) {
00052 Limits::nonnegative(p[i],"Int::cumulative");
00053 Limits::nonnegative(u[i],"Int::cumulative");
00054 Limits::check(static_cast<long long int>(s[i].max()) + p[i],
00055 "Int::cumulative");
00056 mul_check(p[i],u[i]);
00057 w += s[i].width();
00058 }
00059 mul_check(c.max(),w,s.size());
00060 GECODE_POST;
00061
00062 int minU = INT_MAX; int minU2 = INT_MAX; int maxU = INT_MIN;
00063 for (int i=0; i<u.size(); i++) {
00064 if (u[i] < minU) {
00065 minU2 = minU;
00066 minU = u[i];
00067 } else if (u[i] < minU2)
00068 minU2 = u[i];
00069 if (u[i] > maxU)
00070 maxU = u[i];
00071 }
00072 bool disjunctive =
00073 (minU > c.max()/2) || (minU2 > c.max()/2 && minU+minU2>c.max());
00074 if (disjunctive) {
00075 GECODE_ME_FAIL(c.gq(home,maxU));
00076 unary(home,t,s,p,ipl);
00077 } else {
00078 bool fixp = true;
00079 for (int i=0; i<t.size(); i++)
00080 if (t[i] != TT_FIXP) {
00081 fixp = false; break;
00082 }
00083 int nonOptionals = 0;
00084 for (int i=0; i<u.size(); i++)
00085 if (u[i]>0) nonOptionals++;
00086 if (fixp) {
00087 TaskArray<ManFixPTask> tasks(home,nonOptionals);
00088 int cur = 0;
00089 for (int i=0; i<s.size(); i++)
00090 if (u[i] > 0)
00091 tasks[cur++].init(s[i],p[i],u[i]);
00092 GECODE_ES_FAIL(manpost(home,c,tasks,ipl));
00093 } else {
00094 TaskArray<ManFixPSETask> tasks(home,nonOptionals);
00095 int cur = 0;
00096 for (int i=0; i<s.size(); i++)
00097 if (u[i] > 0)
00098 tasks[cur++].init(t[i],s[i],p[i],u[i]);
00099 GECODE_ES_FAIL(manpost(home,c,tasks,ipl));
00100 }
00101 }
00102 }
00103
00104 template<class Cap>
00105 void
00106 cumulative(Home home, Cap c, const TaskTypeArgs& t,
00107 const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
00108 const BoolVarArgs& m, IntPropLevel ipl) {
00109 using namespace Gecode::Int;
00110 using namespace Gecode::Int::Cumulative;
00111 if ((s.size() != p.size()) || (s.size() != u.size()) ||
00112 (s.size() != t.size()) || (s.size() != m.size()))
00113 throw Int::ArgumentSizeMismatch("Int::cumulative");
00114 long long int w = 0;
00115 for (int i=0; i<p.size(); i++) {
00116 Limits::nonnegative(p[i],"Int::cumulative");
00117 Limits::nonnegative(u[i],"Int::cumulative");
00118 Limits::check(static_cast<long long int>(s[i].max()) + p[i],
00119 "Int::cumulative");
00120 mul_check(p[i],u[i]);
00121 w += s[i].width();
00122 }
00123 mul_check(c.max(),w,s.size());
00124 GECODE_POST;
00125
00126 bool allMandatory = true;
00127 for (int i=0; i<m.size(); i++) {
00128 if (!m[i].one()) {
00129 allMandatory = false;
00130 break;
00131 }
00132 }
00133 if (allMandatory) {
00134 cumulative(home,c,t,s,p,u,ipl);
00135 } else {
00136 bool fixp = true;
00137 for (int i=0; i<t.size(); i++)
00138 if (t[i] != TT_FIXP) {
00139 fixp = false; break;
00140 }
00141 int nonOptionals = 0;
00142 for (int i=0; i<u.size(); i++)
00143 if (u[i]>0) nonOptionals++;
00144 if (fixp) {
00145 TaskArray<OptFixPTask> tasks(home,nonOptionals);
00146 int cur = 0;
00147 for (int i=0; i<s.size(); i++)
00148 if (u[i]>0)
00149 tasks[cur++].init(s[i],p[i],u[i],m[i]);
00150 GECODE_ES_FAIL(optpost(home,c,tasks,ipl));
00151 } else {
00152 TaskArray<OptFixPSETask> tasks(home,nonOptionals);
00153 int cur = 0;
00154 for (int i=0; i<s.size(); i++)
00155 if (u[i]>0)
00156 tasks[cur++].init(t[i],s[i],p[i],u[i],m[i]);
00157 GECODE_ES_FAIL(optpost(home,c,tasks,ipl));
00158 }
00159 }
00160 }
00161
00162 template<class Cap>
00163 void
00164 cumulative(Home home, Cap c, const IntVarArgs& s,
00165 const IntArgs& p, const IntArgs& u, IntPropLevel ipl) {
00166 using namespace Gecode::Int;
00167 using namespace Gecode::Int::Cumulative;
00168 if ((s.size() != p.size()) || (s.size() != u.size()))
00169 throw Int::ArgumentSizeMismatch("Int::cumulative");
00170 long long int w = 0;
00171 for (int i=0; i<p.size(); i++) {
00172 Limits::nonnegative(p[i],"Int::cumulative");
00173 Limits::nonnegative(u[i],"Int::cumulative");
00174 Limits::check(static_cast<long long int>(s[i].max()) + p[i],
00175 "Int::cumulative");
00176 mul_check(p[i],u[i]);
00177 w += s[i].width();
00178 }
00179 mul_check(c.max(),w,s.size());
00180 GECODE_POST;
00181
00182 int minU = INT_MAX; int minU2 = INT_MAX; int maxU = INT_MIN;
00183 for (int i=0; i<u.size(); i++) {
00184 if (u[i] < minU) {
00185 minU2 = minU;
00186 minU = u[i];
00187 } else if (u[i] < minU2)
00188 minU2 = u[i];
00189 if (u[i] > maxU)
00190 maxU = u[i];
00191 }
00192 bool disjunctive =
00193 (minU > c.max()/2) || (minU2 > c.max()/2 && minU+minU2>c.max());
00194 if (disjunctive) {
00195 GECODE_ME_FAIL(c.gq(home,maxU));
00196 unary(home,s,p,ipl);
00197 } else {
00198 int nonOptionals = 0;
00199 for (int i=0; i<u.size(); i++)
00200 if (u[i]>0) nonOptionals++;
00201 TaskArray<ManFixPTask> t(home,nonOptionals);
00202 int cur = 0;
00203 for (int i=0; i<s.size(); i++)
00204 if (u[i]>0)
00205 t[cur++].init(s[i],p[i],u[i]);
00206 GECODE_ES_FAIL(manpost(home,c,t,ipl));
00207 }
00208 }
00209
00210 template<class Cap>
00211 void
00212 cumulative(Home home, Cap c, const IntVarArgs& s, const IntArgs& p,
00213 const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl) {
00214 using namespace Gecode::Int;
00215 using namespace Gecode::Int::Cumulative;
00216 if ((s.size() != p.size()) || (s.size() != u.size()) ||
00217 (s.size() != m.size()))
00218 throw Int::ArgumentSizeMismatch("Int::cumulative");
00219 long long int w = 0;
00220 for (int i=0; i<p.size(); i++) {
00221 Limits::nonnegative(p[i],"Int::cumulative");
00222 Limits::nonnegative(u[i],"Int::cumulative");
00223 Limits::check(static_cast<long long int>(s[i].max()) + p[i],
00224 "Int::cumulative");
00225 mul_check(p[i],u[i]);
00226 w += s[i].width();
00227 }
00228 mul_check(c.max(),w,s.size());
00229 GECODE_POST;
00230
00231 bool allMandatory = true;
00232 for (int i=0; i<m.size(); i++) {
00233 if (!m[i].one()) {
00234 allMandatory = false;
00235 break;
00236 }
00237 }
00238 if (allMandatory) {
00239 cumulative(home,c,s,p,u,ipl);
00240 } else {
00241 int nonOptionals = 0;
00242 for (int i=0; i<u.size(); i++)
00243 if (u[i]>0) nonOptionals++;
00244 TaskArray<OptFixPTask> t(home,nonOptionals);
00245 int cur = 0;
00246 for (int i=0; i<s.size(); i++)
00247 if (u[i]>0)
00248 t[cur++].init(s[i],p[i],u[i],m[i]);
00249 GECODE_ES_FAIL(optpost(home,c,t,ipl));
00250 }
00251 }
00252
00253 template<class Cap>
00254 void
00255 cumulative(Home home, Cap c, const IntVarArgs& s,
00256 const IntVarArgs& p, const IntVarArgs& e,
00257 const IntArgs& u, IntPropLevel ipl) {
00258 using namespace Gecode::Int;
00259 using namespace Gecode::Int::Cumulative;
00260 if ((s.size() != p.size()) || (s.size() != e.size()) ||
00261 (s.size() != u.size()))
00262 throw Int::ArgumentSizeMismatch("Int::cumulative");
00263 long long int w = 0;
00264 for (int i=0; i<p.size(); i++) {
00265 Limits::nonnegative(u[i],"Int::cumulative");
00266 Limits::check(static_cast<long long int>(s[i].max()) + p[i].max(),
00267 "Int::cumulative");
00268 mul_check(p[i].max(),u[i]);
00269 w += s[i].width();
00270 }
00271 mul_check(c.max(),w,s.size());
00272
00273 GECODE_POST;
00274 for (int i=0; i<p.size(); i++)
00275 GECODE_ME_FAIL(IntView(p[i]).gq(home,0));
00276
00277 bool fixP = true;
00278 for (int i=0; i<p.size(); i++) {
00279 if (!p[i].assigned()) {
00280 fixP = false;
00281 break;
00282 }
00283 }
00284 if (fixP) {
00285 IntArgs pp(p.size());
00286 for (int i=0; i<p.size(); i++)
00287 pp[i] = p[i].val();
00288 cumulative(home,c,s,pp,u,ipl);
00289 } else {
00290 int nonOptionals = 0;
00291 for (int i=0; i<u.size(); i++)
00292 if (u[i]>0) nonOptionals++;
00293 TaskArray<ManFlexTask> t(home,nonOptionals);
00294 int cur = 0;
00295 for (int i=0; i<s.size(); i++)
00296 if (u[i]>0)
00297 t[cur++].init(s[i],p[i],e[i],u[i]);
00298 GECODE_ES_FAIL(manpost(home,c,t,ipl));
00299 }
00300 }
00301
00302 template<class Cap>
00303 void
00304 cumulative(Home home, Cap c, const IntVarArgs& s, const IntVarArgs& p,
00305 const IntVarArgs& e, const IntArgs& u, const BoolVarArgs& m,
00306 IntPropLevel ipl) {
00307 using namespace Gecode::Int;
00308 using namespace Gecode::Int::Cumulative;
00309 if ((s.size() != p.size()) || (s.size() != u.size()) ||
00310 (s.size() != e.size()) || (s.size() != m.size()))
00311 throw Int::ArgumentSizeMismatch("Int::cumulative");
00312
00313 long long int w = 0;
00314 for (int i=0; i<p.size(); i++) {
00315 Limits::nonnegative(u[i],"Int::cumulative");
00316 Limits::check(static_cast<long long int>(s[i].max()) + p[i].max(),
00317 "Int::cumulative");
00318 mul_check(p[i].max(),u[i]);
00319 w += s[i].width();
00320 }
00321 mul_check(c.max(),w,s.size());
00322
00323 GECODE_POST;
00324 for (int i=0; i<p.size(); i++)
00325 GECODE_ME_FAIL(IntView(p[i]).gq(home,0));
00326
00327 bool allMandatory = true;
00328 for (int i=0; i<m.size(); i++) {
00329 if (!m[i].one()) {
00330 allMandatory = false;
00331 break;
00332 }
00333 }
00334 if (allMandatory) {
00335 cumulative(home,c,s,p,e,u,ipl);
00336 } else {
00337 int nonOptionals = 0;
00338 for (int i=0; i<u.size(); i++)
00339 if (u[i]>0) nonOptionals++;
00340 TaskArray<OptFlexTask> t(home,nonOptionals);
00341 int cur = 0;
00342 for (int i=0; i<s.size(); i++)
00343 if (u[i]>0)
00344 t[cur++].init(s[i],p[i],e[i],u[i],m[i]);
00345 GECODE_ES_FAIL(optpost(home,c,t,ipl));
00346 }
00347 }
00348
00349 }}}
00350
00351 namespace Gecode {
00352
00353 void
00354 cumulative(Home home, int c, const TaskTypeArgs& t,
00355 const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
00356 IntPropLevel ipl) {
00357 Int::Limits::nonnegative(c,"Int::cumulative");
00358 Int::Cumulative::cumulative(home,Int::ConstIntView(c),t,s,p,u,ipl);
00359 }
00360
00361 void
00362 cumulative(Home home, IntVar c, const TaskTypeArgs& t,
00363 const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
00364 IntPropLevel ipl) {
00365 if (c.assigned())
00366 cumulative(home,c.val(),t,s,p,u,ipl);
00367 else
00368 Int::Cumulative::cumulative(home,Int::IntView(c),t,s,p,u,ipl);
00369 }
00370
00371
00372 void
00373 cumulative(Home home, int c, const TaskTypeArgs& t,
00374 const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
00375 const BoolVarArgs& m, IntPropLevel ipl) {
00376 Int::Limits::nonnegative(c,"Int::cumulative");
00377 Int::Cumulative::cumulative(home,Int::ConstIntView(c),t,s,p,u,m,ipl);
00378 }
00379
00380 void
00381 cumulative(Home home, IntVar c, const TaskTypeArgs& t,
00382 const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
00383 const BoolVarArgs& m, IntPropLevel ipl) {
00384 if (c.assigned())
00385 cumulative(home,c.val(),t,s,p,u,m,ipl);
00386 else
00387 Int::Cumulative::cumulative(home,Int::IntView(c),t,s,p,u,m,ipl);
00388 }
00389
00390
00391 void
00392 cumulative(Home home, int c, const IntVarArgs& s,
00393 const IntArgs& p, const IntArgs& u, IntPropLevel ipl) {
00394 Int::Limits::nonnegative(c,"Int::cumulative");
00395 Int::Cumulative::cumulative(home,Int::ConstIntView(c),s,p,u,ipl);
00396 }
00397
00398 void
00399 cumulative(Home home, IntVar c, const IntVarArgs& s,
00400 const IntArgs& p, const IntArgs& u, IntPropLevel ipl) {
00401 if (c.assigned())
00402 cumulative(home,c.val(),s,p,u,ipl);
00403 else
00404 Int::Cumulative::cumulative(home,Int::IntView(c),s,p,u,ipl);
00405 }
00406
00407
00408 void
00409 cumulative(Home home, int c, const IntVarArgs& s, const IntArgs& p,
00410 const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl) {
00411 Int::Limits::nonnegative(c,"Int::cumulative");
00412 Int::Cumulative::cumulative(home,Int::ConstIntView(c),s,p,u,m,ipl);
00413 }
00414
00415 void
00416 cumulative(Home home, IntVar c, const IntVarArgs& s, const IntArgs& p,
00417 const IntArgs& u, const BoolVarArgs& m, IntPropLevel ipl) {
00418 if (c.assigned())
00419 cumulative(home,c.val(),s,p,u,m,ipl);
00420 else
00421 Int::Cumulative::cumulative(home,Int::IntView(c),s,p,u,m,ipl);
00422 }
00423
00424
00425 void
00426 cumulative(Home home, int c, const IntVarArgs& s,
00427 const IntVarArgs& p, const IntVarArgs& e,
00428 const IntArgs& u, IntPropLevel ipl) {
00429 Int::Limits::nonnegative(c,"Int::cumulative");
00430 Int::Cumulative::cumulative(home,Int::ConstIntView(c),s,p,e,u,ipl);
00431 }
00432
00433 void
00434 cumulative(Home home, IntVar c, const IntVarArgs& s,
00435 const IntVarArgs& p, const IntVarArgs& e,
00436 const IntArgs& u, IntPropLevel ipl) {
00437 if (c.assigned())
00438 cumulative(home,c.val(),s,p,e,u,ipl);
00439 else
00440 Int::Cumulative::cumulative(home,Int::IntView(c),s,p,e,u,ipl);
00441 }
00442
00443
00444 void
00445 cumulative(Home home, int c, const IntVarArgs& s, const IntVarArgs& p,
00446 const IntVarArgs& e, const IntArgs& u, const BoolVarArgs& m,
00447 IntPropLevel ipl) {
00448 Int::Limits::nonnegative(c,"Int::cumulative");
00449 Int::Cumulative::cumulative(home,Int::ConstIntView(c),s,p,e,u,m,ipl);
00450 }
00451
00452 void
00453 cumulative(Home home, IntVar c, const IntVarArgs& s, const IntVarArgs& p,
00454 const IntVarArgs& e, const IntArgs& u, const BoolVarArgs& m,
00455 IntPropLevel ipl) {
00456 if (c.assigned())
00457 cumulative(home,c.val(),s,p,e,u,m,ipl);
00458 else
00459 Int::Cumulative::cumulative(home,Int::IntView(c),s,p,e,u,m,ipl);
00460 }
00461
00462 }
00463
00464