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);
 }
Beispiel #2
0
  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);
 }
Beispiel #5
0
 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);
 }