00001 //----------------------------------------------------------------------------- 00002 /** @file searchutils.cpp 00003 @see searchutils.h 00004 00005 $Id: searchutils_8cpp-source.html,v 1.1.1.1 2003/08/07 19:41:39 emarkus Exp $ 00006 $Source: /usr/cvsroot/www_pathfind/libpathfind/0.1.0/doc/searchutils_8cpp-source.html,v $ 00007 */ 00008 //----------------------------------------------------------------------------- 00009 00010 #include <assert.h> 00011 #include "searchutils.h" 00012 00013 #include "search.h" 00014 00015 using namespace std; 00016 using namespace PathFind; 00017 00018 //----------------------------------------------------------------------------- 00019 00020 bool SearchUtils::checkPathExists(const Environment& env, 00021 int start, int target) 00022 { 00023 m_env = &env; 00024 m_target = target; 00025 m_mark.clear(); 00026 m_mark.resize(env.getNumberNodes(), false); 00027 return searchPathExists(start, 0); 00028 } 00029 00030 void SearchUtils::findRandomStartTarget(const Environment& env, int& start, 00031 int &target) 00032 { 00033 int numberNodes = env.getNumberNodes(); 00034 do 00035 { 00036 start = rand() / (RAND_MAX / numberNodes + 1); 00037 target = rand() / (RAND_MAX / numberNodes + 1); 00038 } 00039 while (! env.isValidNodeId(start) 00040 || ! env.isValidNodeId(target) 00041 || start == target 00042 || ! checkPathExists(env, start, target)); 00043 } 00044 00045 bool SearchUtils::searchPathExists(int node, int depth) 00046 { 00047 assert(m_env->isValidNodeId(node)); 00048 if (m_mark[node]) 00049 return false; 00050 if (node == m_target) 00051 return true; 00052 m_mark[node] = true; 00053 assert(depth >= 0); 00054 if (m_successorStack.size() < static_cast<unsigned int>(depth + 1)) 00055 m_successorStack.resize(depth + 1); 00056 assert(static_cast<unsigned int>(depth) < m_successorStack.size()); 00057 vector<Environment::Successor>& successors = m_successorStack[depth]; 00058 m_env->getSuccessors(node, NO_NODE, successors); 00059 int numberSuccessors = successors.size(); 00060 for (int i = 0; i < numberSuccessors; ++i) 00061 { 00062 // Get reference on successor again, because resize could have 00063 // changed it. 00064 const Environment::Successor& successor = m_successorStack[depth][i]; 00065 int targetNodeId = successor.m_target; 00066 assert(m_env->isValidNodeId(targetNodeId)); 00067 if (searchPathExists(targetNodeId, depth + 1)) 00068 return true; 00069 } 00070 return false; 00071 } 00072 00073 //-----------------------------------------------------------------------------