dfs.cpp
Go to the documentation of this file.00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 00002 /* 00003 * Main authors: 00004 * Christian Schulte <schulte@gecode.org> 00005 * 00006 * Copyright: 00007 * Christian Schulte, 2009 00008 * 00009 * Last modified: 00010 * $Date: 2009-05-12 14:35:52 +0200 (Tue, 12 May 2009) $ by $Author: schulte $ 00011 * $Revision: 9065 $ 00012 * 00013 * This file is part of Gecode, the generic constraint 00014 * development environment: 00015 * http://www.gecode.org 00016 * 00017 * Permission is hereby granted, free of charge, to any person obtaining 00018 * a copy of this software and associated documentation files (the 00019 * "Software"), to deal in the Software without restriction, including 00020 * without limitation the rights to use, copy, modify, merge, publish, 00021 * distribute, sublicense, and/or sell copies of the Software, and to 00022 * permit persons to whom the Software is furnished to do so, subject to 00023 * the following conditions: 00024 * 00025 * The above copyright notice and this permission notice shall be 00026 * included in all copies or substantial portions of the Software. 00027 * 00028 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00029 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00030 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00031 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00032 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00033 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00034 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00035 * 00036 */ 00037 00038 #include <gecode/search/parallel/dfs.hh> 00039 00040 namespace Gecode { namespace Search { namespace Parallel { 00041 00042 /* 00043 * Statistics 00044 */ 00045 Statistics 00046 DFS::statistics(void) const { 00047 Statistics s; 00048 for (unsigned int i=0; i<workers(); i++) 00049 s += worker(i)->statistics(); 00050 return s; 00051 } 00052 00053 00054 /* 00055 * Engine: search control 00056 */ 00057 void 00058 DFS::Worker::run(void) { 00059 // Peform initial delay, if not first worker 00060 if (this != engine().worker(0)) 00061 Support::Thread::sleep(Config::initial_delay); 00062 // Okay, we are in business, start working 00063 while (true) { 00064 switch (engine().cmd()) { 00065 case C_WAIT: 00066 // Wait 00067 engine().wait(); 00068 break; 00069 case C_TERMINATE: 00070 // Acknowledge termination request 00071 engine().ack_terminate(); 00072 // Wait until termination can proceed 00073 engine().wait_terminate(); 00074 // Terminate thread 00075 engine().terminated(); 00076 return; 00077 case C_RESET: 00078 // Acknowledge reset request 00079 engine().ack_reset_start(); 00080 // Wait until reset has been performed 00081 engine().wait_reset(); 00082 // Acknowledge that reset cycle is over 00083 engine().ack_reset_stop(); 00084 break; 00085 case C_WORK: 00086 // Perform exploration work 00087 { 00088 m.acquire(); 00089 if (idle) { 00090 m.release(); 00091 // Try to find new work 00092 find(); 00093 } else if (cur != NULL) { 00094 start(); 00095 if (stop(engine().opt(),path.size())) { 00096 // Report stop 00097 m.release(); 00098 engine().stop(); 00099 } else { 00100 node++; 00101 switch (cur->status(*this)) { 00102 case SS_FAILED: 00103 fail++; 00104 delete cur; 00105 cur = NULL; 00106 Worker::current(NULL); 00107 m.release(); 00108 break; 00109 case SS_SOLVED: 00110 { 00111 // Deletes all pending branchings 00112 (void) cur->description(); 00113 Space* s = cur->clone(false); 00114 delete cur; 00115 cur = NULL; 00116 Worker::current(NULL); 00117 m.release(); 00118 engine().solution(s); 00119 } 00120 break; 00121 case SS_BRANCH: 00122 { 00123 Space* c; 00124 if ((d == 0) || (d >= engine().opt().c_d)) { 00125 c = cur->clone(); 00126 d = 1; 00127 } else { 00128 c = NULL; 00129 d++; 00130 } 00131 const BranchingDesc* desc = path.push(*this,cur,c); 00132 Worker::push(c,desc); 00133 cur->commit(*desc,0); 00134 m.release(); 00135 } 00136 break; 00137 default: 00138 GECODE_NEVER; 00139 } 00140 } 00141 } else if (path.next(*this)) { 00142 cur = path.recompute(d,engine().opt().a_d,*this); 00143 Worker::current(cur); 00144 m.release(); 00145 } else { 00146 idle = true; 00147 m.release(); 00148 // Report that worker is idle 00149 engine().idle(); 00150 } 00151 } 00152 break; 00153 default: 00154 GECODE_NEVER; 00155 } 00156 } 00157 } 00158 00159 00160 /* 00161 * Termination and deletion 00162 */ 00163 DFS::~DFS(void) { 00164 terminate(); 00165 heap.rfree(_worker); 00166 } 00167 00168 }}} 00169 00170 // STATISTICS: search-parallel
