ExecStatus purge(Space& home, Propagator& p, TaskArray<OptTask>& t) { int n=t.size(); for (int i=n; i--; ) if (t[i].excluded()) { t[i].cancel(home,p,PL::pc); t[i]=t[--n]; } t.size(n); return (t.size() < 2) ? home.ES_SUBSUMED(p) : ES_OK; }
ExecStatus purge(Space& home, Propagator& p, TaskArray<OptTask>& t, Cap c) { int n=t.size(); for (int i=n; i--; ) if (t[i].excluded()) { t[i].cancel(home,p,PL::pc); t[i]=t[--n]; } t.size(n); if (t.size() == 1) { if (t[0].mandatory()) GECODE_ME_CHECK(c.gq(home, t[0].c())); else if (c.min() < t[0].c()) return ES_OK; } return (t.size() < 2) ? home.ES_SUBSUMED(p) : ES_OK; }
forceinline ExecStatus ManProp<ManTask,Cap>::post(Home home, Cap c, TaskArray<ManTask>& t) { // Capacity must be nonnegative GECODE_ME_CHECK(c.gq(home, 0)); // Check that tasks do not overload resource for (int i=t.size(); i--; ) if (t[i].c() > c.max()) return ES_FAILED; if (t.size() == 1) GECODE_ME_CHECK(c.gq(home, t[0].c())); if (t.size() > 1) { if (c.assigned() && c.val()==1) { TaskArray<typename TaskTraits<ManTask>::UnaryTask> mt(home,t.size()); for (int i=t.size(); i--; ) mt[i]=t[i]; return Unary::ManProp<typename TaskTraits<ManTask>::UnaryTask> ::post(home,mt); } else { (void) new (home) ManProp<ManTask,Cap>(home,c,t); } } return ES_OK; }
ExecStatus basic(Space& home, Propagator& p, int c, TaskArray<Task>& t) { // Sort tasks by decreasing capacity TaskByDecCap<Task> tbdc; Support::quicksort(&t[0], t.size(), tbdc); Region r(home); Event* e = r.alloc<Event>(4*t.size()+1); // Initialize events bool assigned=true; { bool required=false; int n=0; for (int i=t.size(); i--; ) if (t[i].assigned()) { // Only add required part if (t[i].pmin() > 0) { required = true; e[n++].init(Event::ERT,t[i].lst(),i); e[n++].init(Event::LRT,t[i].ect(),i); } else if (t[i].pmax() == 0) { required = true; e[n++].init(Event::ZRO,t[i].lst(),i); } } else { assigned = false; e[n++].init(Event::EST,t[i].est(),i); e[n++].init(Event::LCT,t[i].lct(),i); // Check whether task has required part if (t[i].lst() < t[i].ect()) { required = true; e[n++].init(Event::ERT,t[i].lst(),i); e[n++].init(Event::LRT,t[i].ect(),i); } } // Check whether no task has a required part if (!required) return assigned ? home.ES_SUBSUMED(p) : ES_FIX; // Write end marker e[n++].init(Event::END,Int::Limits::infinity,-1); // Sort events Support::quicksort(e, n); } // Set of current but not required tasks Support::BitSet<Region> tasks(r,static_cast<unsigned int>(t.size())); // Process events, use c as the capacity that is still free while (e->e != Event::END) { // Current time int time = e->t; // Process events for completion of required part for ( ; (e->t == time) && (e->e == Event::LRT); e++) if (t[e->i].mandatory()) { tasks.set(static_cast<unsigned int>(e->i)); c += t[e->i].c(); } // Process events for completion of task for ( ; (e->t == time) && (e->e == Event::LCT); e++) tasks.clear(static_cast<unsigned int>(e->i)); // Process events for start of task for ( ; (e->t == time) && (e->e == Event::EST); e++) tasks.set(static_cast<unsigned int>(e->i)); // Process events for zero-length task for ( ; (e->t == time) && (e->e == Event::ZRO); e++) if (c < t[e->i].c()) return ES_FAILED; // norun start time for 0-length tasks int zltime = time; // Process events for start of required part for ( ; (e->t == time) && (e->e == Event::ERT); e++) if (t[e->i].mandatory()) { tasks.clear(static_cast<unsigned int>(e->i)); c -= t[e->i].c(); zltime = time+1; if (c < 0) return ES_FAILED; } else if (t[e->i].optional() && (t[e->i].c() > c)) { GECODE_ME_CHECK(t[e->i].excluded(home)); } // Exploit that tasks are sorted according to capacity for (Iter::Values::BitSet<Support::BitSet<Region> > j(tasks); j() && (t[j.val()].c() > c); ++j) // Task j cannot run from time to next time - 1 if (t[j.val()].mandatory()) { if (t[j.val()].pmin() > 0) { GECODE_ME_CHECK(t[j.val()].norun(home, time, e->t - 1)); } else { GECODE_ME_CHECK(t[j.val()].norun(home, zltime, e->t - 1)); } } } return assigned ? home.ES_SUBSUMED(p) : ES_NOFIX; }
forceinline ExecStatus timetabling(Space& home, Propagator& p, Cap c, TaskArray<Task>& t) { int ccur = c.max(); int cmax = ccur; int cmin = ccur; // Sort tasks by decreasing capacity TaskByDecCap<Task> tbdc; Support::quicksort(&t[0], t.size(), tbdc); Region r(home); bool assigned; if (Event* e = Event::events(r,t,assigned)) { // Set of current but not required tasks Support::BitSet<Region> tasks(r,static_cast<unsigned int>(t.size())); // Process events, use ccur as the capacity that is still free do { // Current time int time = e->time(); // Process events for completion of required part for ( ; (e->type() == Event::LRT) && (e->time() == time); e++) if (t[e->idx()].mandatory()) { tasks.set(static_cast<unsigned int>(e->idx())); ccur += t[e->idx()].c(); } // Process events for completion of task for ( ; (e->type() == Event::LCT) && (e->time() == time); e++) tasks.clear(static_cast<unsigned int>(e->idx())); // Process events for start of task for ( ; (e->type() == Event::EST) && (e->time() == time); e++) tasks.set(static_cast<unsigned int>(e->idx())); // Process events for zero-length task for ( ; (e->type() == Event::ZRO) && (e->time() == time); e++) { ccur -= t[e->idx()].c(); if (ccur < cmin) cmin=ccur; if (ccur < 0) return ES_FAILED; ccur += t[e->idx()].c(); } // norun start time int nrstime = time; // Process events for start of required part for ( ; (e->type() == Event::ERT) && (e->time() == time); e++) if (t[e->idx()].mandatory()) { tasks.clear(static_cast<unsigned int>(e->idx())); ccur -= t[e->idx()].c(); if (ccur < cmin) cmin=ccur; nrstime = time+1; if (ccur < 0) return ES_FAILED; } else if (t[e->idx()].optional() && (t[e->idx()].c() > ccur)) { GECODE_ME_CHECK(t[e->idx()].excluded(home)); } // Exploit that tasks are sorted according to capacity for (Iter::Values::BitSet<Support::BitSet<Region> > j(tasks); j() && (t[j.val()].c() > ccur); ++j) // Task j cannot run from zltime to next time - 1 if (t[j.val()].mandatory()) GECODE_ME_CHECK(t[j.val()].norun(home, nrstime, e->time() - 1)); } while (e->type() != Event::END); GECODE_ME_CHECK(c.gq(home,cmax-cmin)); } if (assigned) return home.ES_SUBSUMED(p); return ES_NOFIX; }
forceinline ExecStatus ManProp<ManTask>::post(Home home, TaskArray<ManTask>& t) { if (t.size() > 1) (void) new (home) ManProp<ManTask>(home,t); return ES_OK; }
ExecStatus timetabling(Space& home, Propagator& p, TaskArray<Task>& t) { Region r(home); bool assigned; if (Event* e = Event::events(r,t,assigned)) { // Whether resource is free bool free = true; // Set of current but not required tasks Support::BitSet<Region> tasks(r,static_cast<unsigned int>(t.size())); // Process events do { // Current time int time = e->time(); // Process events for completion of required part for ( ; (e->type() == Event::LRT) && (e->time() == time); e++) if (t[e->idx()].mandatory()) { tasks.set(static_cast<unsigned int>(e->idx())); free = true; } // Process events for completion of task for ( ; (e->type() == Event::LCT) && (e->time() == time); e++) tasks.clear(static_cast<unsigned int>(e->idx())); // Process events for start of task for ( ; (e->type() == Event::EST) && (e->time() == time); e++) tasks.set(static_cast<unsigned int>(e->idx())); // Process events for zero-length task for ( ; (e->type() == Event::ZRO) && (e->time() == time); e++) if (!free) return ES_FAILED; // Norun start time int nrstime = time; // Process events for start of required part for ( ; (e->type() == Event::ERT) && (e->time() == time); e++) if (t[e->idx()].mandatory()) { tasks.clear(static_cast<unsigned int>(e->idx())); if (!free) return ES_FAILED; free = false; nrstime = time+1; } else if (t[e->idx()].optional() && !free) { GECODE_ME_CHECK(t[e->idx()].excluded(home)); } if (!free) for (Iter::Values::BitSet<Support::BitSet<Region> > j(tasks); j(); ++j) // Task j cannot run from time to next time - 1 if (t[j.val()].mandatory()) GECODE_ME_CHECK(t[j.val()].norun(home, nrstime, e->time() - 1)); } while (e->type() != Event::END); } if (assigned) return home.ES_SUBSUMED(p); return ES_NOFIX; }