edge-finding.hpp
Go to the documentation of this file.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
00037
00038
00039
00040
00041
00042
00043
00044 #include <algorithm>
00045
00046 namespace Gecode { namespace Int { namespace Cumulative {
00047
00049 template<class TaskView, bool inc>
00050 class StoCap {
00051 public:
00053 bool operator ()(const TaskView& t1, const TaskView& t2) const {
00054 return inc ? (t1.c() < t2.c()) : (t2.c() < t1.c());
00055 }
00056 };
00057
00059 class PrecOrder {
00060 public:
00061 int* prec;
00063 PrecOrder(int* prec0) : prec(prec0) {}
00065 bool operator ()(int i, int j) const {
00066 return prec[i] > prec[j];
00067 }
00068 };
00069
00070 template<class TaskView>
00071 forceinline ExecStatus
00072 edgefinding(Space& home, int c, TaskViewArray<TaskView>& t) {
00073 sort<TaskView,STO_LCT,false>(t);
00074
00075 Region r(home);
00076
00078
00079
00080 int* prec = r.alloc<int>(t.size());
00081 for (int i=t.size(); i--; )
00082 prec[i] = t[i].ect();
00083
00084 OmegaLambdaTree<TaskView> ol(r,c,t);
00085
00086 for (int j=0; j<t.size(); j++) {
00087 while (!ol.lempty() &&
00088 (ol.lenv() > static_cast<double>(c)*t[j].lct())) {
00089 int i = ol.responsible();
00090 prec[i] = std::max(prec[i], t[j].lct());
00091 ol.lremove(i);
00092 }
00093 ol.shift(j);
00094 }
00095
00097
00098
00099
00100
00101
00102
00103 int* cap = r.alloc<int>(t.size());
00104 for (int i=t.size(); i--;)
00105 cap[i] = i;
00106 SortMap<TaskView,StoCap,true> o(t);
00107 Support::quicksort(cap, t.size(), o);
00108
00109 int* capacities = r.alloc<int>(t.size());
00110 int* capInv = r.alloc<int>(t.size());
00111 for (int i=t.size(); i--;) {
00112 capacities[cap[i]] = t[i].c();
00113 capInv[cap[i]] = i;
00114 }
00115
00116 int n_c = 0;
00117 for (int i=0, cur_c=INT_MIN; i<t.size(); i++) {
00118 if (capacities[i] != cur_c)
00119 capacities[n_c++] = cur_c = capacities[i];
00120 cap[capInv[i]] = n_c-1;
00121 }
00122 r.free<int>(capInv, t.size());
00123
00124
00125
00126 int* update = r.alloc<int>(t.size()*n_c);
00127 for (int i=t.size()*n_c; i--;)
00128 update[i] = -Int::Limits::infinity;
00129
00130 ExtOmegaTree<TaskView> eo(r,c,ol);
00131 for (int i=0; i<n_c; i++) {
00132 eo.init(capacities[i]);
00133 int u = -Int::Limits::infinity;
00134 for (int j=t.size(); j--;) {
00135 double lctj = static_cast<double>(c-capacities[i])*t[j].lct();
00136 double diff_d = ceil(div(plus(eo.env(j), -lctj),capacities[i]));
00137 int diff = (diff_d == -Int::Limits::double_infinity) ?
00138 -Int::Limits::infinity : static_cast<int>(diff_d);
00139 u = std::max(u,diff);
00140 update[i*t.size()+j] = u;
00141 }
00142 }
00143
00144
00145
00146
00147 int* precMap = r.alloc<int>(t.size());
00148 for (int i=t.size(); i--;)
00149 precMap[i] = i;
00150 PrecOrder po(prec);
00151 Support::quicksort(precMap, t.size(), po);
00152
00153 int curJ = 0;
00154 for (int i=0; i<t.size(); i++) {
00155
00156 while (curJ < t.size() && t[curJ].lct() > prec[precMap[i]])
00157 curJ++;
00158 if (curJ >= t.size())
00159 break;
00160
00161 int locJ = curJ;
00162 do {
00163 if (t[locJ].lct() != t[precMap[i]].lct()) {
00164 GECODE_ME_CHECK(t[precMap[i]].est(home,update[cap[precMap[i]]*t.size()+locJ]));
00165 break;
00166 }
00167 } while (t[locJ].lct() == prec[precMap[i]] && locJ++ < t.size() - 1);
00168 }
00169
00170 return ES_OK;
00171 }
00172
00173 template<class Task>
00174 ExecStatus
00175 edgefinding(Space& home, int c, TaskArray<Task>& t) {
00176 TaskViewArray<typename TaskTraits<Task>::TaskViewFwd> f(t);
00177 GECODE_ES_CHECK(edgefinding(home,c,f));
00178 TaskViewArray<typename TaskTraits<Task>::TaskViewBwd> b(t);
00179 GECODE_ES_CHECK(edgefinding(home,c,b));
00180 return ES_OK;
00181 }
00182
00183 }}}
00184
00185