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 * 6 * Copyright: 7 * Christian Schulte, 2009 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#include <algorithm> 35 36namespace Gecode { namespace Int { namespace Unary { 37 38 /* 39 * Omega tree 40 */ 41 42 forceinline void 43 OmegaNode::init(const OmegaNode&, const OmegaNode&) { 44 p = 0; ect = -Limits::infinity; 45 } 46 47 forceinline void 48 OmegaNode::update(const OmegaNode& l, const OmegaNode& r) { 49 p = l.p + r.p; 50 ect = std::max(plus(l.ect,r.p), r.ect); 51 } 52 53 template<class TaskView> 54 forceinline 55 OmegaTree<TaskView>::OmegaTree(Region& r, const TaskViewArray<TaskView>& t) 56 : TaskTree<TaskView,OmegaNode>(r,t) { 57 for (int i=0; i<tasks.size(); i++) { 58 leaf(i).p = 0; leaf(i).ect = -Limits::infinity; 59 } 60 init(); 61 } 62 63 template<class TaskView> 64 forceinline void 65 OmegaTree<TaskView>::insert(int i) { 66 leaf(i).p = tasks[i].pmin(); 67 leaf(i).ect = tasks[i].est()+tasks[i].pmin(); 68 update(i); 69 } 70 71 template<class TaskView> 72 forceinline void 73 OmegaTree<TaskView>::remove(int i) { 74 leaf(i).p = 0; leaf(i).ect = -Limits::infinity; 75 update(i); 76 } 77 78 template<class TaskView> 79 forceinline int 80 OmegaTree<TaskView>::ect(void) const { 81 return root().ect; 82 } 83 84 template<class TaskView> 85 forceinline int 86 OmegaTree<TaskView>::ect(int i) const { 87 // Check whether task i is in? 88 OmegaTree<TaskView>& o = const_cast<OmegaTree<TaskView>&>(*this); 89 if (o.leaf(i).ect != -Limits::infinity) { 90 o.remove(i); 91 int ect = o.root().ect; 92 o.insert(i); 93 return ect; 94 } else { 95 return root().ect; 96 } 97 } 98 99 100 101 /* 102 * Omega lambda tree 103 */ 104 105 forceinline void 106 OmegaLambdaNode::init(const OmegaLambdaNode& l, const OmegaLambdaNode& r) { 107 OmegaNode::init(l,r); 108 lp = p; lect = ect; resEct = undef; resLp = undef; 109 } 110 111 forceinline void 112 OmegaLambdaNode::update(const OmegaLambdaNode& l, const OmegaLambdaNode& r) { 113 OmegaNode::update(l,r); 114 if (l.lp + r.p > l.p + r.lp) { 115 resLp = l.resLp; 116 lp = l.lp + r.p; 117 } else { 118 resLp = r.resLp; 119 lp = l.p + r.lp; 120 } 121 if ((r.lect >= plus(l.ect,r.lp)) && (r.lect >= plus(l.lect,r.p))) { 122 lect = r.lect; resEct = r.resEct; 123 } else if (plus(l.ect,r.lp) >= plus(l.lect,r.p)) { 124 assert(plus(l.ect,r.lp) > r.lect); 125 lect = plus(l.ect,r.lp); resEct = r.resLp; 126 } else { 127 assert((plus(l.lect,r.p) > r.lect) && 128 (plus(l.lect,r.p) > plus(l.ect,r.lp))); 129 lect = plus(l.lect,r.p); resEct = l.resEct; 130 } 131 } 132 133 134 template<class TaskView> 135 forceinline 136 OmegaLambdaTree<TaskView>::OmegaLambdaTree(Region& r, 137 const TaskViewArray<TaskView>& t, 138 bool inc) 139 : TaskTree<TaskView,OmegaLambdaNode>(r,t) { 140 if (inc) { 141 // Enter all tasks into tree (omega = all tasks, lambda = empty) 142 for (int i=0; i<tasks.size(); i++) { 143 leaf(i).p = leaf(i).lp = tasks[i].pmin(); 144 leaf(i).ect = leaf(i).lect = tasks[i].est()+tasks[i].pmin(); 145 leaf(i).resEct = OmegaLambdaNode::undef; 146 leaf(i).resLp = OmegaLambdaNode::undef; 147 } 148 update(); 149 } else { 150 // Enter no tasks into tree (omega = empty, lambda = empty) 151 for (int i=0; i<tasks.size(); i++) { 152 leaf(i).p = leaf(i).lp = 0; 153 leaf(i).ect = leaf(i).lect = -Limits::infinity; 154 leaf(i).resEct = OmegaLambdaNode::undef; 155 leaf(i).resLp = OmegaLambdaNode::undef; 156 } 157 init(); 158 } 159 } 160 161 template<class TaskView> 162 forceinline void 163 OmegaLambdaTree<TaskView>::shift(int i) { 164 // That means that i is in omega 165 assert(leaf(i).ect > -Limits::infinity); 166 leaf(i).p = 0; 167 leaf(i).ect = -Limits::infinity; 168 leaf(i).resEct = i; 169 leaf(i).resLp = i; 170 update(i); 171 } 172 173 template<class TaskView> 174 forceinline void 175 OmegaLambdaTree<TaskView>::oinsert(int i) { 176 leaf(i).p = tasks[i].pmin(); 177 leaf(i).ect = tasks[i].est()+tasks[i].pmin(); 178 update(i); 179 } 180 181 template<class TaskView> 182 forceinline void 183 OmegaLambdaTree<TaskView>::linsert(int i) { 184 leaf(i).lp = tasks[i].pmin(); 185 leaf(i).lect = tasks[i].est()+tasks[i].pmin(); 186 leaf(i).resEct = i; 187 leaf(i).resLp = i; 188 update(i); 189 } 190 191 template<class TaskView> 192 forceinline void 193 OmegaLambdaTree<TaskView>::lremove(int i) { 194 leaf(i).lp = 0; 195 leaf(i).lect = -Limits::infinity; 196 leaf(i).resEct = OmegaLambdaNode::undef; 197 leaf(i).resLp = OmegaLambdaNode::undef; 198 update(i); 199 } 200 201 template<class TaskView> 202 forceinline bool 203 OmegaLambdaTree<TaskView>::lempty(void) const { 204 return root().resEct < 0; 205 } 206 207 template<class TaskView> 208 forceinline int 209 OmegaLambdaTree<TaskView>::responsible(void) const { 210 return root().resEct; 211 } 212 213 template<class TaskView> 214 forceinline int 215 OmegaLambdaTree<TaskView>::ect(void) const { 216 return root().ect; 217 } 218 219 template<class TaskView> 220 forceinline int 221 OmegaLambdaTree<TaskView>::lect(void) const { 222 return root().lect; 223 } 224 225}}} 226 227// STATISTICS: int-prop