|
Boost Users : |
From: Detlef Mages (mages_at_[hidden])
Date: 2006-02-08 05:13:25
Hi all
I am using astar_search from the BGL and have sometimes hangs due to an
infinite loop (no, I do not use negative costs or negative heuristic values).
Now here is the strange problem: when compiling the attached (see below) test
program with compiler optimization enabled it runs into an infinite loop.
Without optimization a solution is found.
I need help, because I do not know what I should do next. Is this a compiler
bug? Is there something boost can do (workaround)? Is there a known issue
(could not find anything) with the relax function?
-- Detlef Here are the facts: I condensed one of the malicious (undirected) graphs to <SNIP> V ar[181]; for( unsigned int i = 0; i < 181; ++i ) { ar[i] = add_vertex( VProp(i, 1.0), g ); } add_edge( ar[1], ar[18 ], EProp( 2.20 ), g ); add_edge( ar[0], ar[30 ], EProp( 1.58 ), g ); add_edge( ar[0], ar[66 ], EProp( 0.93 ), g ); add_edge( ar[66], ar[100 ], EProp( 2.72 ), g ); add_edge( ar[66], ar[101 ], EProp( 2.87 ), g ); add_edge( ar[30], ar[142 ], EProp( 4.88 ), g ); add_edge( ar[18], ar[142 ], EProp( 3.29 ), g ); </SNAP>. There are no other edges. A complete listing of the program is attached. My compiler version: # g++ -v Using built-in specs. Target: i586-suse-linux Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,f95,java,ada --disable-checking --with-gxx-include-dir=/usr/include/c++/4.0.2 --enable-java-awt=gtk --disable-libjava-multilib --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit --without-system-libunwind --host=i586-suse-linux Thread model: posix gcc version 4.0.2 20050901 (prerelease) (SUSE Linux) # g++ -O2 searchtest4.cpp && a.out 2>/dev/null discover: 0 examine: 0 edge_relaxed: 0 -- 30 discover: 30 edge_relaxed: 0 -- 66 discover: 66 examine: 66 edge_not_relaxed: 66 -- 0 edge_relaxed: 66 -- 100 discover: 100 edge_relaxed: 66 -- 101 discover: 101 examine: 30 edge_not_relaxed: 30 -- 0 edge_relaxed: 30 -- 142 discover: 142 CYCLE: examine: 100 CYCLE: edge_relaxed: 100 -- 66 CYCLE: black_target: 100 -- 66 CYCLE: examine: 66 CYCLE: edge_not_relaxed: 66 -- 0 CYCLE: edge_relaxed: 66 -- 100 CYCLE: black_target: 66 -- 100 CYCLE: edge_relaxed: 66 -- 101 >From now on the lines marked CYCLE are repeated. --> infinite loop # g++ -O0 searchtest4.cpp && a.out 2>/dev/null discover: 0 examine: 0 edge_relaxed: 0 -- 30 discover: 30 edge_relaxed: 0 -- 66 discover: 66 examine: 66 edge_not_relaxed: 66 -- 0 edge_relaxed: 66 -- 100 discover: 100 edge_relaxed: 66 -- 101 discover: 101 examine: 30 edge_not_relaxed: 30 -- 0 edge_relaxed: 30 -- 142 discover: 142 examine: 100 edge_not_relaxed: 100 -- 66 // from here on the two outputs differ examine: 101 edge_not_relaxed: 101 -- 66 examine: 142 edge_not_relaxed: 142 -- 30 edge_relaxed: 142 -- 18 discover: 18 examine: 18 edge_relaxed: 18 -- 1 discover: 1 edge_not_relaxed: 18 -- 142 examine: 1 found 1->18->142->30->0 --> success Here is the listing "searchtest4.cpp": ---------------------------------- #include <boost/graph/astar_search.hpp> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphviz.hpp> #include <iostream> using namespace std; using namespace boost; struct VProp { VProp() : m_distance(1.0) {} VProp( size_t invar_id, double heuristic ) : m_vertex_invariable_id( invar_id ), m_heuristic( heuristic ), m_distance( .0 ) {} size_t m_vertex_invariable_id; // my id that is not changed by rebuilding the index map double m_heuristic; // a really simple heuristic double m_distance; // altered by the algo: this id is the distance boost::default_color_type m_color; }; struct EProp { EProp() : m_weight( .0 ) {} EProp( double weight ) : m_weight( weight ) {} double m_weight; }; typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, VProp, EProp > G; typedef G::vertex_descriptor V; typedef G::edge_descriptor E; struct found_goal {}; template< class Vertex, class Edge > class GoalVisitor : public boost::default_astar_visitor { public: GoalVisitor(Vertex goal) : m_goal(goal) {} template <class Graph> void examine_vertex(Vertex u, Graph& g) { cout << "examine: " << u << endl; if(u == m_goal) throw found_goal(); } template <class Graph> void discover_vertex(Vertex u, Graph& g) { cout << "discover: " << u << endl; } template <class Graph> void black_target(Edge u, Graph& g) { cout << "black_target: " << boost::source( u, g ) << " -- " << boost::target( u, g ) << endl; } template <class Graph> void edge_relaxed(Edge u, Graph& g) { cout << "edge_relaxed: " << boost::source( u, g ) << " -- " << boost::target( u, g ) << endl; } template <class Graph> void edge_not_relaxed(Edge u, Graph& g) { cout << "edge_not_relaxed: " << boost::source( u, g ) << " -- " << boost::target( u, g ) << endl; } private: Vertex m_goal; }; template< class Graph, class CostType > class DistanceHeuristic : public boost::astar_heuristic<Graph, CostType > { public: DistanceHeuristic( Graph & graph ) : m_graph(graph) {} template< class Vertex > CostType operator()( Vertex u) { return m_graph[u].m_heuristic; } private: Graph & m_graph; }; class EdgeWeightWriter { public: EdgeWeightWriter( G & graph ): m_graph( graph ) {} template< class OStream > void operator()( OStream& out, V v ) { // out << " [label= \"" << v <<"\"]"; } template< class OStream > void operator()( OStream& out, E v ) { out.precision( 30 ); out << " [label= \"" << m_graph[v].m_weight <<"\"]"; } private: G & m_graph; }; int main() { G g; V ar[181]; for( unsigned int i = 0; i < 181; ++i ) { ar[i] = add_vertex( VProp(i, 1.0), g ); } // add_edge( ar[1], ar[18 ], EProp( 2.20307469298885294506362697575 ), g ); // add_edge( ar[0], ar[30 ], EProp( 1.58945958901181461087048774061 ), g ); // add_edge( ar[0], ar[66 ], EProp( 0.937232823257896585644743936427 ), g ); // add_edge( ar[66], ar[100 ], EProp( 2.72761497732282665040770552878 ), g ); // add_edge( ar[66], ar[101 ], EProp( 2.87914914272965027919326530537 ), g ); // add_edge( ar[30], ar[142 ], EProp( 4.8843528076143511995610424492 ), g ); // add_edge( ar[18], ar[142 ], EProp( 3.29201592753501959265349796624 ), g ); add_edge( ar[1], ar[18 ], EProp( 2.20 ), g ); add_edge( ar[0], ar[30 ], EProp( 1.58 ), g ); add_edge( ar[0], ar[66 ], EProp( 0.93 ), g ); add_edge( ar[66], ar[100 ], EProp( 2.72 ), g ); add_edge( ar[66], ar[101 ], EProp( 2.87 ), g ); add_edge( ar[30], ar[142 ], EProp( 4.88 ), g ); add_edge( ar[18], ar[142 ], EProp( 3.29 ), g ); map< V, V > predecessor; associative_property_map< map< V, V > > predecessorMap( predecessor ); /** * solution to this: 1->18->142->30->0 */ try { astar_search(g, ar[0], DistanceHeuristic<G, double>( g ), predecessor_map( predecessorMap ). weight_map( get(&EProp::m_weight, g) ). color_map( get(&VProp::m_color, g) ). distance_map( get(&VProp::m_distance, g) ). visitor(GoalVisitor<V, E>( ar[1] ) ) ); } catch ( found_goal ) { cout << "found" << endl; for(V v = ar[1];; v = predecessor[v]) { cout << v; if(predecessor[v] == v) break; cout << "->"; } cout << endl; } boost::write_graphviz( std::cerr, g, EdgeWeightWriter( g ), EdgeWeightWriter( g ), default_writer() ); }
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net