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 * Copyright: 8 * Christian Schulte, 2009 9 * Guido Tack, 2010 10 * 11 * This file is part of Gecode, the generic constraint 12 * development environment: 13 * http://www.gecode.org 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining 16 * a copy of this software and associated documentation files (the 17 * "Software"), to deal in the Software without restriction, including 18 * without limitation the rights to use, copy, modify, merge, publish, 19 * distribute, sublicense, and/or sell copies of the Software, and to 20 * permit persons to whom the Software is furnished to do so, subject to 21 * the following conditions: 22 * 23 * The above copyright notice and this permission notice shall be 24 * included in all copies or substantial portions of the Software. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 30 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 31 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 32 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 * 34 */ 35 36#include <algorithm> 37 38namespace Gecode { namespace Int { namespace Cumulative { 39 40 template<class OptTask, class Cap, class PL> 41 forceinline 42 OptProp<OptTask,Cap,PL>::OptProp(Home home, Cap c0, TaskArray<OptTask>& t) 43 : TaskProp<OptTask,PL>(home,t), c(c0) { 44 c.subscribe(home,*this,PC_INT_BND); 45 } 46 47 template<class OptTask, class Cap, class PL> 48 forceinline 49 OptProp<OptTask,Cap,PL>::OptProp(Space& home, OptProp<OptTask,Cap,PL>& p) 50 : TaskProp<OptTask,PL>(home,p) { 51 c.update(home,p.c); 52 } 53 54 template<class OptTask, class Cap, class PL> 55 ExecStatus 56 OptProp<OptTask,Cap,PL>::post(Home home, Cap c, TaskArray<OptTask>& t) { 57 // Capacity must be nonnegative 58 GECODE_ME_CHECK(c.gq(home, 0)); 59 // Check for overload by single task and remove excluded tasks 60 int n=t.size(), m=0; 61 for (int i=n; i--; ) { 62 if (t[i].c() > c.max()) 63 GECODE_ME_CHECK(t[i].excluded(home)); 64 if (t[i].excluded()) 65 t[i]=t[--n]; 66 else if (t[i].mandatory()) 67 m++; 68 } 69 t.size(n); 70 if (t.size() < 2) { 71 if (t.size() == 1) { 72 if (t[0].mandatory()) { 73 GECODE_ME_CHECK(c.gq(home, t[0].c())); 74 return ES_OK; 75 } else if (c.min() >= t[0].c()) { 76 return ES_OK; 77 } 78 } else { 79 return ES_OK; 80 } 81 } 82 if (c.assigned() && (c.val() == 1)) { 83 TaskArray<typename TaskTraits<OptTask>::UnaryTask> mt(home,t.size()); 84 for (int i=0; i<t.size(); i++) 85 mt[i]=t[i]; 86 return Unary::OptProp<typename TaskTraits<OptTask>::UnaryTask,PL> 87 ::post(home,mt); 88 } 89 if (m == t.size()) { 90 TaskArray<typename TaskTraits<OptTask>::ManTask> mt(home,m); 91 for (int i=0; i<m; i++) 92 mt[i].init(t[i]); 93 return ManProp<typename TaskTraits<OptTask>::ManTask,Cap,PL> 94 ::post(home,c,mt); 95 } 96 (void) new (home) OptProp<OptTask,Cap,PL>(home,c,t); 97 return ES_OK; 98 } 99 100 template<class OptTask, class Cap, class PL> 101 Actor* 102 OptProp<OptTask,Cap,PL>::copy(Space& home) { 103 return new (home) OptProp<OptTask,Cap,PL>(home,*this); 104 } 105 106 template<class OptTask, class Cap, class PL> 107 forceinline size_t 108 OptProp<OptTask,Cap,PL>::dispose(Space& home) { 109 (void) TaskProp<OptTask,PL>::dispose(home); 110 c.cancel(home,*this,PC_INT_BND); 111 return sizeof(*this); 112 } 113 114 template<class OptTask, class Cap, class PL> 115 ExecStatus 116 OptProp<OptTask,Cap,PL>::propagate(Space& home, const ModEventDelta& med) { 117 // Did one of the Boolean views change? 118 if (BoolView::me(med) == ME_BOOL_VAL) 119 GECODE_ES_CHECK((purge<OptTask,PL>(home,*this,t,c))); 120 121 // Only bounds changes? 122 if (IntView::me(med) != ME_INT_DOM) 123 GECODE_ES_CHECK(overload(home,c.max(),t)); 124 125 if (PL::basic) 126 GECODE_ES_CHECK(timetabling(home,*this,c,t)); 127 128 if (PL::advanced) { 129 // Partition into mandatory and optional activities 130 int n = t.size(); 131 int i=0, j=n-1; 132 while (true) { 133 while ((i < n) && t[i].mandatory()) i++; 134 while ((j >= 0) && !t[j].mandatory()) j--; 135 if (i >= j) break; 136 std::swap(t[i],t[j]); 137 } 138 139 if (i > 1) { 140 // Truncate array to only contain mandatory tasks 141 t.size(i); 142 GECODE_ES_CHECK(edgefinding(home,c.max(),t)); 143 // Restore to also include optional tasks 144 t.size(n); 145 } 146 } 147 148 if (Cap::varderived() && c.assigned() && c.val()==1) { 149 // Check that tasks do not overload resource 150 for (int i=0; i<t.size(); i++) 151 if (t[i].c() > 1) 152 GECODE_ME_CHECK(t[i].excluded(home)); 153 // Rewrite to unary resource constraint 154 TaskArray<typename TaskTraits<OptTask>::UnaryTask> ut(home,t.size()); 155 for (int i=0; i<t.size(); i++) 156 ut[i]=t[i]; 157 GECODE_REWRITE(*this, 158 (Unary::OptProp<typename TaskTraits<OptTask>::UnaryTask,PL> 159 ::post(home(*this),ut))); 160 } 161 162 if (!PL::basic && c.assigned()) 163 GECODE_ES_CHECK(subsumed(home,*this,c.val(),t)); 164 165 return ES_NOFIX; 166 } 167 168}}} 169 170// STATISTICS: int-prop