forceinline void sort(int* map, const TaskViewArray<TaskView>& t) { for (int i=t.size(); i--; ) map[i]=i; switch (sto) { case STO_EST: { SortMap<TaskView,StoEst,inc> o(t); Support::quicksort(map, t.size(), o); } break; case STO_ECT: { SortMap<TaskView,StoEct,inc> o(t); Support::quicksort(map, t.size(), o); } break; case STO_LST: { SortMap<TaskView,StoLst,inc> o(t); Support::quicksort(map, t.size(), o); } break; case STO_LCT: { SortMap<TaskView,StoLct,inc> o(t); Support::quicksort(map, t.size(), o); } break; default: GECODE_NEVER; } }
forceinline void sort(TaskViewArray<TaskView>& t) { switch (sto) { case STO_EST: { StoEst<TaskView,inc> o; Support::quicksort(&t[0], t.size(), o); } break; case STO_ECT: { StoEct<TaskView,inc> o; Support::quicksort(&t[0], t.size(), o); } break; case STO_LST: { StoLst<TaskView,inc> o; Support::quicksort(&t[0], t.size(), o); } break; case STO_LCT: { StoLct<TaskView,inc> o; Support::quicksort(&t[0], t.size(), o); } break; default: GECODE_NEVER; } }
forceinline ExecStatus notlast(Space& home, TaskViewArray<ManTaskView>& t) { sort<ManTaskView,STO_LCT,true>(t); Region r(home); OmegaTree<ManTaskView> o(r,t); TaskViewIter<ManTaskView,STO_LST,true> q(r,t); int* lct = r.alloc<int>(t.size()); for (int i=t.size(); i--; ) lct[i] = t[i].lct(); for (int i=0; i<t.size(); i++) { int j = -1; while (q() && (t[i].lct() > t[q.task()].lst())) { if ((j >= 0) && (o.ect() > t[q.task()].lst())) lct[q.task()] = std::min(lct[q.task()],t[j].lst()); j = q.task(); o.insert(j); ++q; } if ((j >= 0) && (o.ect(i) > t[i].lst())) lct[i] = std::min(lct[i],t[j].lst()); } for (int i=t.size(); i--; ) GECODE_ME_CHECK(t[i].lct(home,lct[i])); return ES_OK; }
forceinline ManTaskViewIter<OptTaskView,sto,inc> ::ManTaskViewIter(Region& r, const TaskViewArray<OptTaskView>& t) { map = r.alloc<int>(t.size()); i=0; for (int j=t.size(); j--; ) if (t[j].mandatory()) map[i++]=j; sort<OptTaskView,sto,!inc>(map,i,t); i--; }
forceinline ExecStatus notlast(Space& home, Propagator& p, TaskViewArray<OptTaskView>& t) { sort<OptTaskView,STO_LCT,true>(t); Region r(home); OmegaTree<OptTaskView> o(r,t); ManTaskViewIter<OptTaskView,STO_LST,true> q(r,t); int* lct = r.alloc<int>(t.size()); for (int i=t.size(); i--; ) lct[i] = t[i].lct(); for (int i=0; i<t.size(); i++) { int j = -1; while (q() && (t[i].lct() > t[q.task()].lst())) { if ((j >= 0) && (o.ect() > t[q.task()].lst())) lct[q.task()] = std::min(lct[q.task()],t[j].lst()); j = q.task(); o.insert(j); ++q; } if ((j >= 0) && (o.ect(i) > t[i].lst())) lct[i] = std::min(lct[i],t[j].lst()); } int n = t.size(); for (int i=n; i--; ) if (t[i].mandatory()) { GECODE_ME_CHECK(t[i].lct(home,lct[i])); } else if (lct[i] < t[i].ect()) { // GECODE_ME_CHECK(t[i].excluded(home)); // t[i].cancel(home,p); t[i]=t[--n]; } t.size(n); return (t.size() < 2) ? home.ES_SUBSUMED(p) : ES_OK; }
forceinline TaskViewIter<TaskView,sto,inc> ::TaskViewIter(Region& r, const TaskViewArray<TaskView>& t) : map(r.alloc<int>(t.size())), i(t.size()-1) { sort<TaskView,sto,!inc>(map,t); }
forceinline ExecStatus edgefinding(Space& home, int c, TaskViewArray<TaskView>& t) { sort<TaskView,STO_LCT,false>(t); Region r(home); /////////////////////// // Detection int* prec = r.alloc<int>(t.size()); for (int i=t.size(); i--; ) prec[i] = t[i].ect(); OmegaLambdaTree<TaskView> ol(r,c,t); for (int j=0; j<t.size(); j++) { while (!ol.lempty() && (ol.lenv() > static_cast<long long int>(c)*t[j].lct())) { int i = ol.responsible(); prec[i] = std::max(prec[i], t[j].lct()); ol.lremove(i); } ol.shift(j); } /////////////////////// // Propagation // Compute array of unique capacities and a mapping // from the task array to the corresponding entry in // the capacity array int* cap = r.alloc<int>(t.size()); for (int i=t.size(); i--;) cap[i] = i; SortMap<TaskView,StoCap,true> o(t); Support::quicksort(cap, t.size(), o); int* capacities = r.alloc<int>(t.size()); int* capInv = r.alloc<int>(t.size()); for (int i=t.size(); i--;) { capacities[cap[i]] = t[i].c(); capInv[cap[i]] = i; } int n_c = 0; for (int i=0, cur_c=INT_MIN; i<t.size(); i++) { if (capacities[i] != cur_c) capacities[n_c++] = cur_c = capacities[i]; cap[capInv[i]] = n_c-1; } r.free<int>(capInv, t.size()); // Compute update values for each capacity and LCut int* update = r.alloc<int>(t.size()*n_c); for (int i=t.size()*n_c; i--;) update[i] = -Int::Limits::infinity; ExtOmegaTree<TaskView> eo(r,c,ol); for (int i=0; i<n_c; i++) { eo.init(capacities[i]); int u = -Int::Limits::infinity; for (int j=t.size(); j--;) { long long int lctj = static_cast<long long int>(c-capacities[i])*t[j].lct(); long long int eml = plus(eo.env(j), -lctj); long long int diff_l; if (eml == -Limits::llinfinity) diff_l = -Limits::llinfinity; else diff_l = ceil_div_xx(eml, static_cast<long long int>(capacities[i])); int diff = (diff_l <= -Limits::infinity) ? -Limits::infinity : static_cast<int>(diff_l); u = std::max(u,diff); update[i*t.size()+j] = u; } } // Update est by iterating in parallel over the prec array // and the task array, both sorted by lct int* precMap = r.alloc<int>(t.size()); for (int i=t.size(); i--;) precMap[i] = i; PrecOrder po(prec); Support::quicksort(precMap, t.size(), po); int curJ = 0; for (int i=0; i<t.size(); i++) { // discard any curJ with lct > prec[i]: while (curJ < t.size() && t[curJ].lct() > prec[precMap[i]]) curJ++; if (curJ >= t.size()) break; // if lct[curJ] == prec[i], then LCut(T,j) <= i, so update est[i] int locJ = curJ; do { if (t[locJ].lct() != t[precMap[i]].lct()) { GECODE_ME_CHECK(t[precMap[i]].est(home,update[cap[precMap[i]]*t.size()+locJ])); break; } } while (t[locJ].lct() == prec[precMap[i]] && locJ++ < t.size() - 1); } return ES_OK; }