void examine_edge(Edge e, Graph& g) { // Comparison needs to be more complicated because distance and weight // types may not be the same; see bug 8398 // (https://svn.boost.org/trac/boost/ticket/8398) D source_dist = get(m_distance, source(e, g)); if (m_compare(m_combine(source_dist, get(m_weight, e)), source_dist)) boost::throw_exception(negative_edge()); m_vis.examine_edge(e, g); }
inline void astar_search_no_init_tree (const VertexListGraph &g, typename graph_traits<VertexListGraph>::vertex_descriptor s, AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor, CostMap cost, DistanceMap distance, WeightMap weight, CompareFunction compare, CombineFunction combine, CostInf /*inf*/, CostZero zero) { typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex; typedef typename property_traits<DistanceMap>::value_type Distance; typedef d_ary_heap_indirect< std::pair<Distance, Vertex>, 4, null_property_map<std::pair<Distance, Vertex>, std::size_t>, function_property_map<graph_detail::select1st<Distance, Vertex>, std::pair<Distance, Vertex> >, CompareFunction> MutableQueue; MutableQueue Q( make_function_property_map<std::pair<Distance, Vertex> >(graph_detail::select1st<Distance, Vertex>()), null_property_map<std::pair<Distance, Vertex>, std::size_t>(), compare); vis.discover_vertex(s, g); Q.push(std::make_pair(get(cost, s), s)); while (!Q.empty()) { Vertex v; Distance v_rank; boost::tie(v_rank, v) = Q.top(); Q.pop(); vis.examine_vertex(v, g); BGL_FORALL_OUTEDGES_T(v, e, g, VertexListGraph) { Vertex w = target(e, g); vis.examine_edge(e, g); Distance e_weight = get(weight, e); if (compare(e_weight, zero)) BOOST_THROW_EXCEPTION(negative_edge()); bool decreased = relax(e, g, weight, predecessor, distance, combine, compare); Distance w_d = combine(get(distance, v), e_weight); if (decreased) { vis.edge_relaxed(e, g); Distance w_rank = combine(get(distance, w), h(w)); put(cost, w, w_rank); vis.discover_vertex(w, g); Q.push(std::make_pair(w_rank, w)); } else { vis.edge_not_relaxed(e, g); } } vis.finish_vertex(v, g); }
void dijkstra_shortest_paths_no_color_map_no_init (const Graph& graph, typename graph_traits<Graph>::vertex_descriptor start_vertex, PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map, VertexIndexMap index_map, DistanceCompare distance_compare, DistanceWeightCombine distance_weight_combine, DistanceInfinity distance_infinity, DistanceZero distance_zero, DijkstraVisitor visitor) { typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename property_traits<DistanceMap>::value_type Distance; typedef indirect_cmp<DistanceMap, DistanceCompare> DistanceIndirectCompare; DistanceIndirectCompare distance_indirect_compare(distance_map, distance_compare); // Choose vertex queue type #if BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP typedef relaxed_heap<Vertex, DistanceIndirectCompare, VertexIndexMap> VertexQueue; VertexQueue vertex_queue(num_vertices(graph), distance_indirect_compare, index_map); #else // Default - use d-ary heap (d = 4) typedef detail::vertex_property_map_generator<Graph, VertexIndexMap, std::size_t> IndexInHeapMapHelper; typedef typename IndexInHeapMapHelper::type IndexInHeapMap; typedef d_ary_heap_indirect<Vertex, 4, IndexInHeapMap, DistanceMap, DistanceCompare> VertexQueue; boost::scoped_array<std::size_t> index_in_heap_map_holder; IndexInHeapMap index_in_heap = IndexInHeapMapHelper::build(graph, index_map, index_in_heap_map_holder); VertexQueue vertex_queue(distance_map, index_in_heap, distance_compare); #endif // Add vertex to the queue vertex_queue.push(start_vertex); // Starting vertex will always be the first discovered vertex visitor.discover_vertex(start_vertex, graph); while (!vertex_queue.empty()) { Vertex min_vertex = vertex_queue.top(); vertex_queue.pop(); visitor.examine_vertex(min_vertex, graph); // Check if any other vertices can be reached Distance min_vertex_distance = get(distance_map, min_vertex); if (!distance_compare(min_vertex_distance, distance_infinity)) { // This is the minimum vertex, so all other vertices are unreachable return; } // Examine neighbors of min_vertex BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph) { visitor.examine_edge(current_edge, graph); // Check if the edge has a negative weight if (distance_compare(get(weight_map, current_edge), distance_zero)) { boost::throw_exception(negative_edge()); } // Extract the neighboring vertex and get its distance Vertex neighbor_vertex = target(current_edge, graph); Distance neighbor_vertex_distance = get(distance_map, neighbor_vertex); bool is_neighbor_undiscovered = !distance_compare(neighbor_vertex_distance, distance_infinity); // Attempt to relax the edge bool was_edge_relaxed = relax(current_edge, graph, weight_map, predecessor_map, distance_map, distance_weight_combine, distance_compare); if (was_edge_relaxed) { visitor.edge_relaxed(current_edge, graph); if (is_neighbor_undiscovered) { visitor.discover_vertex(neighbor_vertex, graph); vertex_queue.push(neighbor_vertex); } else { vertex_queue.update(neighbor_vertex); } } else { visitor.edge_not_relaxed(current_edge, graph); } } // end out edge iteration visitor.finish_vertex(min_vertex, graph); } // end while queue not empty
void examine_edge(Edge e, Graph& g) { if (m_compare(get(m_weight, e), m_zero)) throw negative_edge(); m_vis.examine_edge(e, g); }
void examine_edge(Edge e, const Graph& g) { if (m_compare(get(m_weight, e), m_zero)) BOOST_THROW_EXCEPTION(negative_edge()); m_vis.examine_edge(e, g); }
void examine_edge(Edge e, Graph& g) { if (m_compare(get(m_weight, e), m_zero)) boost::throw_exception(negative_edge()); m_vis.examine_edge(e, g); }