我正在阅读boost :: graph文档以备将来使用。我对A *算法特别感兴趣。boost :: graph astar算法无例外
看看boost :: graph :: astar_search的用法示例,似乎停止算法的方法是引发异常并将其捕获到算法的外部。
由于我不想抛出任何异常,导致C++中的异常处理非常复杂,效率不高,我不知道boost :: graph是否提供了另一种方法来在达到目标时停止算法。
有没有人有另一个例子没有使用任何例外?
我正在阅读boost :: graph文档以备将来使用。我对A *算法特别感兴趣。boost :: graph astar算法无例外
看看boost :: graph :: astar_search的用法示例,似乎停止算法的方法是引发异常并将其捕获到算法的外部。
由于我不想抛出任何异常,导致C++中的异常处理非常复杂,效率不高,我不知道boost :: graph是否提供了另一种方法来在达到目标时停止算法。
有没有人有另一个例子没有使用任何例外?
根据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
感谢提到常见问题解答。得出相同的结论,即需要修改算法。 – neodelphi 2013-05-30 20:13:53
'原因的异常处理在C++中是非常复杂的,不是很efficient'在哪里你从这里得到这个? – 2013-04-26 21:54:43
@dauphic看看异常被捕获时真正发生在汇编中的情况(真正有很多代码在运行!)。为了性能比较,还测试了一些“返回代码VS异常”。例外情况应该保持例外,我认为将它用于算法目的不是一个好主意。 – neodelphi 2013-04-26 22:11:20