bab.hh
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 #ifndef __GECODE_SEARCH_PARALLEL_BAB_HH__
00039 #define __GECODE_SEARCH_PARALLEL_BAB_HH__
00040
00041 #include <gecode/search/parallel/engine.hh>
00042
00043 namespace Gecode { namespace Search { namespace Parallel {
00044
00046 class BAB : public Engine {
00047 protected:
00049 class Worker : public Engine::Worker {
00050 protected:
00052 int mark;
00054 Space* best;
00055 public:
00057 Worker(Space* s, size_t sz, BAB& e);
00059 BAB& engine(void) const;
00061 virtual void run(void);
00063 void better(Space* b);
00065 void find(void);
00067 void reset(Space* s);
00069 virtual ~Worker(void);
00070 };
00072 Worker** _worker;
00074 Space* best;
00075 public:
00077 Worker* worker(unsigned int i) const;
00078
00080
00081
00082 void solution(Space* s);
00084
00086
00087
00088 BAB(Space* s, size_t sz, const Options& o);
00090 virtual Statistics statistics(void) const;
00092 virtual void reset(Space* s);
00094 virtual ~BAB(void);
00096 };
00097
00098
00099
00100
00101
00102
00103 forceinline BAB&
00104 BAB::Worker::engine(void) const {
00105 return static_cast<BAB&>(_engine);
00106 }
00107 forceinline BAB::Worker*
00108 BAB::worker(unsigned int i) const {
00109 return _worker[i];
00110 }
00111
00112 forceinline void
00113 BAB::Worker::reset(Space* s) {
00114 delete cur;
00115 delete best;
00116 best = NULL;
00117 path.reset();
00118 d = mark = 0;
00119 idle = false;
00120 if ((s == NULL) || (s->status(*this) == SS_FAILED)) {
00121 delete s;
00122 cur = NULL;
00123 Search::Worker::reset();
00124 } else {
00125 cur = s;
00126 Search::Worker::reset(cur);
00127 }
00128 }
00129
00130
00131
00132
00133
00134 forceinline
00135 BAB::Worker::Worker(Space* s, size_t sz, BAB& e)
00136 : Engine::Worker(s,sz,e), mark(0), best(NULL) {}
00137
00138 forceinline
00139 BAB::BAB(Space* s, size_t sz, const Options& o)
00140 : Engine(o), best(NULL) {
00141
00142 _worker = static_cast<Worker**>
00143 (heap.ralloc(workers() * sizeof(Worker*)));
00144
00145 _worker[0] = new Worker(s,sz,*this);
00146
00147 for (unsigned int i=1; i<workers(); i++)
00148 _worker[i] = new Worker(NULL,sz,*this);
00149
00150 block();
00151
00152 for (unsigned int i=0; i<workers(); i++)
00153 Support::Thread::run(_worker[i]);
00154 }
00155
00156
00157
00158
00159
00160 forceinline void
00161 BAB::Worker::better(Space* b) {
00162 m.acquire();
00163 delete best;
00164 best = b->clone(false);
00165 mark = path.entries();
00166 if (cur != NULL)
00167 cur->constrain(*best);
00168 m.release();
00169 }
00170 forceinline void
00171 BAB::solution(Space* s) {
00172 m_search.acquire();
00173 if (best != NULL) {
00174 s->constrain(*best);
00175 if (s->status() == SS_FAILED) {
00176 delete s;
00177 m_search.release();
00178 return;
00179 } else {
00180 delete best;
00181 best = s->clone();
00182 }
00183 } else {
00184 best = s->clone();
00185 }
00186
00187 for (unsigned int i=0; i<workers(); i++)
00188 worker(i)->better(best);
00189 bool bs = signal();
00190 solutions.push(s);
00191 if (bs)
00192 e_search.signal();
00193 m_search.release();
00194 }
00195
00196
00197
00198
00199
00200 forceinline void
00201 BAB::Worker::find(void) {
00202
00203 for (unsigned int i=0; i<engine().workers(); i++) {
00204 unsigned long int r_d = 0ul;
00205 if (Space* s = engine().worker(i)->steal(r_d)) {
00206
00207 m.acquire();
00208 idle = false;
00209 d = 0;
00210 cur = s;
00211 mark = 0;
00212 if (best != NULL)
00213 cur->constrain(*best);
00214 Search::Worker::reset(cur,r_d);
00215 m.release();
00216 return;
00217 }
00218 }
00219 }
00220
00221 }}}
00222
00223 #endif
00224
00225