Boost logo

Boost Users :

Subject: Re: [Boost-users] [graph] dijkstra additional constrains that will stop the search (ex. distance from source)
From: a.hagen-zanker_at_[hidden]
Date: 2013-04-17 10:57:25


From: Boost-users [mailto:boost-users-bounces_at_[hidden]] On Behalf Of The Maschine

boost::dijkstra_shortest_paths(m_ugraph, *vertex_iterator_begin, boost::predecessor_map(predecessorMap).distance_map(distanceMap));
currently works ok.
Finds the shortest path based on the "edge_weight" (this is what I need).

The addition I need: I need the search for the shortest path to stop if outside a radius. (my graph is a street network).

lets say max "travel distance" = 4 
Source -> V1(length=1) -> V2(length=3) -> V3(length=2) -> V4(length=1) -> V5(length=1) ->VEnd

The search should end on V3 and V3 should be "unreachable" from the source (V4,V5 and Vend should be unreachable too)

The distance_map should have the distances for V1 and V2 based on the "edge_weight".

This explanation seems to be better.

Thanks
Tasos

Hi Tasos,

You could consider that "unreachable" is the same as "d = travel distance". You could use a closed plus and a custom value for infinite distance. You would need to create a closed plus that is a bit more robust than the closed_plus currently in BGL, e.g.:

struct robust_closed_plus {
  robust_closed_plus (double d) : d(d)
  {}

  double operator(double a, double b){
    return (d-a < b) >? d : a+b;
  }
  double d;
};

Then you can use dijkstra_shortest_path, using your travel distance as infinity.

robust_closed_plus plusser(travel_distance);

boost::dijkstra_shortest_paths(m_ugraph, *vertex_iterator_begin
  , boost::predecessor_map(predecessorMap)
  .distance_map(distanceMap)
  .distance_compare(plusser)
  .distane_inf(travel_distance);

This should already give you the correct result, but will also make you visit more vertices than necessary. Still combine with a visitor like Jeremiah suggested before:

struct hit_inf{};

template<typename DistanceMap>
struct inf_quit_visitor: boost::default_dijkstra_visitor {
  inf_quit_visitor (DistanceMap dm, double inf) : dm(dm), inf(inf)
  {}

  template<typename V, typename G>
  void examine_vertex(V v, const G& g) {
     if (get(dm, v) == inf)
       throw hit_inf();
   }

  DistanceMap dm;
  double inf;
};

robust_closed_plus plusser(travel_distance);

inf_quit_visitor<DistanceMap> quitter(distanceMap, travel_distance);

try
{
  boost::dijkstra_shortest_paths(m_ugraph, *vertex_iterator_begin,
    boost::predecessor_map(predecessorMap)
    .distance_map(distanceMap)
    .distance_compare(plusser)
    .distane_inf(travel_distance)
    .visitor(quitter) );
} catch(hit_inf&) {
}

Hope this helps, Alex


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