1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker 1d9faf38de Squashed 'software/gecode/' content from commit 313e8764
git-subtree-dir: software/gecode
git-subtree-split: 313e87646da4fc2752a70e83df16d993121a8e40
2021-06-16 14:02:33 +10:00

189 lines
5.6 KiB
C++
Executable File

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Christian Schulte <schulte@gecode.org>
* Guido Tack <tack@gecode.org>
*
* Contributing authors:
* Joseph Scott <joseph.scott@it.uu.se>
*
* Copyright:
* Christian Schulte, 2009
* Guido Tack, 2010
* Joseph Scott, 2011
*
* 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 <algorithm>
namespace Gecode { namespace Int { namespace Cumulative {
/// Sort by capacity
template<class TaskView, bool inc>
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<class TaskView>
forceinline ExecStatus
edgefinding(Space& home, int c, TaskViewArray<TaskView>& t) {
sort<TaskView,STO_LCT,false>(t);
Region r;
///////////////////////
// Detection
int* prec = r.alloc<int>(t.size());
for (int i=0; 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=0; 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=0; i<t.size()*n_c; i++)
update[i] = -Limits::infinity;
ExtOmegaTree<TaskView> eo(r,c,ol);
for (int i=0; i<n_c; i++) {
eo.init(capacities[i]);
int u = -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=0; 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;
}
template<class Task>
ExecStatus
edgefinding(Space& home, int c, TaskArray<Task>& t) {
TaskViewArray<typename TaskTraits<Task>::TaskViewFwd> f(t);
GECODE_ES_CHECK(edgefinding(home,c,f));
TaskViewArray<typename TaskTraits<Task>::TaskViewBwd> b(t);
GECODE_ES_CHECK(edgefinding(home,c,b));
return ES_OK;
}
}}}
// STATISTICS: int-prop