this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * Guido Tack <tack@gecode.org> 6 * 7 * Contributing authors: 8 * Joseph Scott <joseph.scott@it.uu.se> 9 * 10 * Copyright: 11 * Christian Schulte, 2009 12 * Guido Tack, 2010 13 * Joseph Scott, 2011 14 * 15 * This file is part of Gecode, the generic constraint 16 * development environment: 17 * http://www.gecode.org 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining 20 * a copy of this software and associated documentation files (the 21 * "Software"), to deal in the Software without restriction, including 22 * without limitation the rights to use, copy, modify, merge, publish, 23 * distribute, sublicense, and/or sell copies of the Software, and to 24 * permit persons to whom the Software is furnished to do so, subject to 25 * the following conditions: 26 * 27 * The above copyright notice and this permission notice shall be 28 * included in all copies or substantial portions of the Software. 29 * 30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 * 38 */ 39 40#include <algorithm> 41 42namespace Gecode { namespace Int { namespace Cumulative { 43 44 /// Sort by capacity 45 template<class TaskView, bool inc> 46 class StoCap { 47 public: 48 /// Sort order 49 bool operator ()(const TaskView& t1, const TaskView& t2) const { 50 return inc ? (t1.c() < t2.c()) : (t2.c() < t1.c()); 51 } 52 }; 53 54 /// Sort by prec array 55 class PrecOrder { 56 public: 57 int* prec; 58 /// Constructor 59 PrecOrder(int* prec0) : prec(prec0) {} 60 /// Sort order 61 bool operator ()(int i, int j) const { 62 return prec[i] > prec[j]; 63 } 64 }; 65 66 template<class TaskView> 67 forceinline ExecStatus 68 edgefinding(Space& home, int c, TaskViewArray<TaskView>& t) { 69 sort<TaskView,STO_LCT,false>(t); 70 71 Region r; 72 73 /////////////////////// 74 // Detection 75 76 int* prec = r.alloc<int>(t.size()); 77 for (int i=0; i<t.size(); i++) 78 prec[i] = t[i].ect(); 79 80 OmegaLambdaTree<TaskView> ol(r,c,t); 81 82 for (int j=0; j<t.size(); j++) { 83 while (!ol.lempty() && 84 (ol.lenv() > static_cast<long long int>(c)*t[j].lct())) { 85 int i = ol.responsible(); 86 prec[i] = std::max(prec[i], t[j].lct()); 87 ol.lremove(i); 88 } 89 ol.shift(j); 90 } 91 92 /////////////////////// 93 // Propagation 94 95 // Compute array of unique capacities and a mapping 96 // from the task array to the corresponding entry in 97 // the capacity array 98 99 int* cap = r.alloc<int>(t.size()); 100 for (int i=0; i<t.size(); i++) 101 cap[i] = i; 102 SortMap<TaskView,StoCap,true> o(t); 103 Support::quicksort(cap, t.size(), o); 104 105 int* capacities = r.alloc<int>(t.size()); 106 int* capInv = r.alloc<int>(t.size()); 107 for (int i=t.size(); i--;) { 108 capacities[cap[i]] = t[i].c(); 109 capInv[cap[i]] = i; 110 } 111 112 int n_c = 0; 113 for (int i=0, cur_c=INT_MIN; i<t.size(); i++) { 114 if (capacities[i] != cur_c) 115 capacities[n_c++] = cur_c = capacities[i]; 116 cap[capInv[i]] = n_c-1; 117 } 118 r.free<int>(capInv, t.size()); 119 120 // Compute update values for each capacity and LCut 121 122 int* update = r.alloc<int>(t.size()*n_c); 123 for (int i=0; i<t.size()*n_c; i++) 124 update[i] = -Limits::infinity; 125 126 ExtOmegaTree<TaskView> eo(r,c,ol); 127 for (int i=0; i<n_c; i++) { 128 eo.init(capacities[i]); 129 int u = -Limits::infinity; 130 for (int j=t.size(); j--;) { 131 long long int lctj = 132 static_cast<long long int>(c-capacities[i])*t[j].lct(); 133 long long int eml = plus(eo.env(j), -lctj); 134 long long int diff_l; 135 if (eml == -Limits::llinfinity) 136 diff_l = -Limits::llinfinity; 137 else 138 diff_l = ceil_div_xx(eml, 139 static_cast<long long int>(capacities[i])); 140 int diff = (diff_l <= -Limits::infinity) ? 141 -Limits::infinity : static_cast<int>(diff_l); 142 u = std::max(u,diff); 143 update[i*t.size()+j] = u; 144 } 145 } 146 147 // Update est by iterating in parallel over the prec array 148 // and the task array, both sorted by lct 149 150 int* precMap = r.alloc<int>(t.size()); 151 for (int i=0; i<t.size(); i++) 152 precMap[i] = i; 153 PrecOrder po(prec); 154 Support::quicksort(precMap, t.size(), po); 155 156 int curJ = 0; 157 for (int i=0; i<t.size(); i++) { 158 // discard any curJ with lct > prec[i]: 159 while (curJ < t.size() && t[curJ].lct() > prec[precMap[i]]) 160 curJ++; 161 if (curJ >= t.size()) 162 break; 163 // if lct[curJ] == prec[i], then LCut(T,j) <= i, so update est[i] 164 int locJ = curJ; 165 do { 166 if (t[locJ].lct() != t[precMap[i]].lct()) { 167 GECODE_ME_CHECK(t[precMap[i]].est(home,update[cap[precMap[i]]*t.size()+locJ])); 168 break; 169 } 170 } while (t[locJ].lct() == prec[precMap[i]] && locJ++ < t.size() - 1); 171 } 172 173 return ES_OK; 174 } 175 176 template<class Task> 177 ExecStatus 178 edgefinding(Space& home, int c, TaskArray<Task>& t) { 179 TaskViewArray<typename TaskTraits<Task>::TaskViewFwd> f(t); 180 GECODE_ES_CHECK(edgefinding(home,c,f)); 181 TaskViewArray<typename TaskTraits<Task>::TaskViewBwd> b(t); 182 GECODE_ES_CHECK(edgefinding(home,c,b)); 183 return ES_OK; 184 } 185 186}}} 187 188// STATISTICS: int-prop