2013-04-26 54 views
3

我正在阅读boost :: graph文档以备将来使用。我对A *算法特别感兴趣。boost :: graph astar算法无例外

看看boost :: graph :: astar_search的用法示例,似乎停止算法的方法是引发异常并将其捕获到算法的外部。

由于我不想抛出任何异常,导致C++中的异常处理非常复杂,效率不高,我不知道boost :: graph是否提供了另一种方法来在达到目标时停止算法。

有没有人有另一个例子没有使用任何例外?

+3

'原因的异常处理在C++中是非常复杂的,不是很efficient'在哪里你从这里得到这个? – 2013-04-26 21:54:43

+1

@dauphic看看异常被捕获时真正发生在汇编中的情况(真正有很多代码在运行!)。为了性能比较,还测试了一些“返回代码VS异常”。例外情况应该保持例外,我认为将它用于算法目的不是一个好主意。 – neodelphi 2013-04-26 22:11:20

回答

5

根据FAQ,早期退出BFS的唯一方法是抛出异常并“查看boost邮件列表以获取详细信息”,但是我从未发现过这样的细节。

要不要使用异常与A *,你必须修改算法,并用停止条件介绍自己的访客:

#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

感谢提到常见问题解答。得出相同的结论,即需要修改算法。 – neodelphi 2013-05-30 20:13:53