/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte * Guido Tack * * Contributing authors: * Joseph Scott * * Copyright: * Christian Schulte, 2009 * Guido Tack, 2010 * Joseph Scott, 2011 * * Last modified: * $Date: 2012-02-22 16:04:20 +1100 (Wed, 22 Feb 2012) $ by $Author: tack $ * $Revision: 12537 $ * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include namespace Gecode { namespace Int { namespace Cumulative { /// Sort by capacity template class StoCap { public: /// Sort order bool operator ()(const TaskView& t1, const TaskView& t2) const { return inc ? (t1.c() < t2.c()) : (t2.c() < t1.c()); } }; /// Sort by prec array class PrecOrder { public: int* prec; /// Constructor PrecOrder(int* prec0) : prec(prec0) {} /// Sort order bool operator ()(int i, int j) const { return prec[i] > prec[j]; } }; template forceinline ExecStatus edgefinding(Space& home, int c, TaskViewArray& t) { sort(t); Region r(home); /////////////////////// // Detection int* prec = r.alloc(t.size()); for (int i=t.size(); i--; ) prec[i] = t[i].ect(); OmegaLambdaTree ol(r,c,t); for (int j=0; j static_cast(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(t.size()); for (int i=t.size(); i--;) cap[i] = i; SortMap o(t); Support::quicksort(cap, t.size(), o); int* capacities = r.alloc(t.size()); int* capInv = r.alloc(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(capInv, t.size()); // Compute update values for each capacity and LCut int* update = r.alloc(t.size()*n_c); for (int i=t.size()*n_c; i--;) update[i] = -Int::Limits::infinity; ExtOmegaTree eo(r,c,ol); for (int i=0; i(c-capacities[i])*t[j].lct(); double diff_d = ceil(div(plus(eo.env(j), -lctj),capacities[i])); int diff = (diff_d == -Int::Limits::double_infinity) ? -Int::Limits::infinity : static_cast(diff_d); 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(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 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; } template ExecStatus edgefinding(Space& home, int c, TaskArray& t) { TaskViewArray::TaskViewFwd> f(t); GECODE_ES_CHECK(edgefinding(home,c,f)); TaskViewArray::TaskViewBwd> b(t); GECODE_ES_CHECK(edgefinding(home,c,b)); return ES_OK; } }}} // STATISTICS: int-prop