2013-04-26 5 views
3

Я читаю boost :: графическую документацию для будущего использования. Меня особенно интересует алгоритм A *.boost :: graph astar algorithm без исключений

Имея взгляд на boost :: graph :: пример использования astar_search, кажется, что способ остановить алгоритм бросает исключение и ловит его в алгоритм.

Поскольку я не хочу исключать какие-либо исключения, обработка исключений на C++ действительно сложна и не очень эффективна, мне интересно, если boost :: graph предлагает другой способ остановить алгоритм, когда цель была достигнута.

У кого-нибудь есть альтернативный пример, не использующий каких-либо исключений?

+3

'причина исключения обработки в C++ является очень сложным и не очень efficient' Где вы получили это? –

+1

@dauphic Посмотрел, что на самом деле происходит в сборке при сбое исключения (действительно много запусков кода!). Также был проведен тест на «исключение VS кода VS» для сравнения производительности. Исключения должны оставаться исключительными, и я думаю, что использование его для цели алгоритма - не очень хорошая идея. – neodelphi

ответ

5

Согласно FAQ, единственный выход для выхода из BFS - это бросить исключение и «увидеть список рассылки для более подробной информации», но я не нашел таких деталей.

Чтобы не использовать исключения с А *, вы должны изменить алгоритм и ввести свой собственный посетитель с условием остановки:

#include <boost/graph/astar_search.hpp> 


namespace boost { namespace graph { 

template < class Visitors = null_visitor > 
struct stopable_astar_visitor : public astar_visitor<Visitors> { 
    stopable_astar_visitor() {} 
    stopable_astar_visitor(Visitors vis) : astar_visitor<Visitors>(vis) {} 

    template < class Vertex, class Graph > 
    bool should_stop(Vertex &v, Graph &g) { 
     return true; 
    } 
}; 

template <typename VertexListGraph, typename AStarHeuristic, 
      typename AStarVisitor, typename PredecessorMap, 
      typename CostMap, typename DistanceMap, 
      typename WeightMap, 
      typename CompareFunction, typename CombineFunction, 
      typename CostZero> 
inline void 
stoppable_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, 
    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); 
    int counter = 0; 
    vis.discover_vertex(s, g); 
    Q.push(std::make_pair(get(cost, s), s)); 
    while (!Q.empty()) { 
     counter++; 
    Vertex v; 
    Distance v_rank; 
    boost::tie(v_rank, v) = Q.top(); 
    Q.pop(); 
    if (vis.should_stop(v, g)) { 
     return; 
    } 
    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); 
    } 
} 
}} // end namespace boost::graph 
+0

Благодарим за упоминание FAQ. Пришел к тому же выводу, что требуется изменить алгоритм. – neodelphi