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, 2015 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 <climits> 35 36namespace Gecode { namespace Search { namespace Seq { 37 38 39 forceinline 40 PortfolioStop::PortfolioStop(Stop* so0) 41 : so(so0) {} 42 forceinline void 43 PortfolioStop::share(SharedStopInfo* ssi0) { 44 ssi = ssi0; 45 } 46 47 48 forceinline 49 Slave::Slave(void) 50 : slave(nullptr), stop(nullptr) {} 51 forceinline void 52 Slave::init(Engine* e, Stop* s) { 53 slave = e; stop = s; 54 } 55 forceinline Space* 56 Slave::next(void) { 57 return slave->next(); 58 } 59 forceinline Statistics 60 Slave::statistics(void) const { 61 return slave->statistics(); 62 } 63 forceinline bool 64 Slave::stopped(void) const { 65 return slave->stopped(); 66 } 67 forceinline void 68 Slave::constrain(const Space& b) { 69 slave->constrain(b); 70 } 71 forceinline 72 Slave::~Slave(void) { 73 delete slave; 74 delete stop; 75 } 76 77 78 template<bool best> 79 forceinline 80 PBS<best>::PBS(Engine** e, Stop** s, unsigned int n, 81 const Statistics& stat0, 82 const Search::Options& opt) 83 : stat(stat0), slice(opt.slice), 84 slaves(heap.alloc<Slave>(n)), n_slaves(n), cur(0), 85 slave_stop(false) { 86 ssi.done = false; 87 ssi.l = opt.slice; 88 89 for (unsigned int i=0U; i<n; i++) { 90 slaves[i].init(e[i],static_cast<PortfolioStop*>(s[i])); 91 static_cast<PortfolioStop*>(s[i])->share(&ssi); 92 } 93 } 94 95 template<bool best> 96 Space* 97 PBS<best>::next(void) { 98 slave_stop = false; 99 unsigned int n_exhausted = 0; 100 while (n_slaves > 0) { 101 if (Space* s = slaves[cur].next()) { 102 // Constrain other slaves 103 if (best) { 104 for (unsigned int i=0U; i<cur; i++) 105 slaves[i].constrain(*s); 106 for (unsigned int i=cur+1; i<n_slaves; i++) 107 slaves[i].constrain(*s); 108 } 109 return s; 110 } 111 if (slaves[cur].stopped()) { 112 if (ssi.done) { 113 cur++; n_exhausted++; 114 } else { 115 slave_stop = true; 116 return nullptr; 117 } 118 } else { 119 // This slave is done, kill it after saving the statistics 120 stat += slaves[cur].statistics(); 121 slaves[cur].~Slave(); 122 slaves[cur] = slaves[--n_slaves]; 123 if (n_slaves == 1) 124 // Disable stoping by seeting a high limit 125 ssi.l = ULONG_MAX; 126 } 127 if (n_exhausted == n_slaves) { 128 n_exhausted = 0; 129 // Increment by one slice 130 ssi.l += slice; 131 } 132 if (cur == n_slaves) 133 cur = 0; 134 } 135 return nullptr; 136 } 137 138 template<bool best> 139 bool 140 PBS<best>::stopped(void) const { 141 return slave_stop; 142 } 143 144 template<bool best> 145 Statistics 146 PBS<best>::statistics(void) const { 147 Statistics s(stat); 148 for (unsigned int i=0U; i<n_slaves; i++) 149 s += slaves[i].statistics(); 150 return s; 151 } 152 153 template<bool best> 154 void 155 PBS<best>::constrain(const Space& b) { 156 if (!best) 157 throw NoBest("PBS::constrain"); 158 for (unsigned int i=0U; i<n_slaves; i++) 159 slaves[i].constrain(b); 160 } 161 162 template<bool best> 163 PBS<best>::~PBS(void) { 164 for (unsigned int i=0U; i<n_slaves; i++) 165 slaves[i].~Slave(); 166 // Note that n_slaves might be different now! 167 heap.rfree(slaves); 168 } 169 170}}} 171 172// STATISTICS: search-seq