我正在使用boost::graph及其Dijkstra实现。
当有人使用Dijkstra算法时,可能是为了知道图中2个节点之间的最短路径。但由于需要检查图中所有节点才能找到最短路径,通常(如boost算法)Dijkstra会返回一个起点与图中所有其他节点之间的距离。
当您只想要2个节点之间的路径时,这个算法的一种简单改进是在算法到达目标节点时停止。然后,您可以确定对于此最终目标节点,您拥有的距离是最短的。
如何告诉boost Dijkstra算法在到达特定节点时停止?
我正在使用boost::graph及其Dijkstra实现。
当有人使用Dijkstra算法时,可能是为了知道图中2个节点之间的最短路径。但由于需要检查图中所有节点才能找到最短路径,通常(如boost算法)Dijkstra会返回一个起点与图中所有其他节点之间的距离。
当您只想要2个节点之间的路径时,这个算法的一种简单改进是在算法到达目标节点时停止。然后,您可以确定对于此最终目标节点,您拥有的距离是最短的。
如何告诉boost Dijkstra算法在到达特定节点时停止?
感谢Sehe及其见解,我遵循Dijkstra访问者的方法解决了我的问题。以下是解决方案:
我创建了一个访问者类,它来自于Dijkstra的访问者类型:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
// Graph Definitions
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef boost::graph_traits<Graph>::edge_descriptor Edge;
// Visitor that throw an exception when finishing the destination vertex
class my_visitor : boost::default_bfs_visitor{
protected:
Vertex destination_vertex_m;
public:
my_visitor(Vertex destination_vertex_l)
: destination_vertex_m(destination_vertex_l) {};
void initialize_vertex(const Vertex &s, const Graph &g) const {}
void discover_vertex(const Vertex &s, const Graph &g) const {}
void examine_vertex(const Vertex &s, const Graph &g) const {}
void examine_edge(const Edge &e, const Graph &g) const {}
void edge_relaxed(const Edge &e, const Graph &g) const {}
void edge_not_relaxed(const Edge &e, const Graph &g) const {}
void finish_vertex(const Vertex &s, const Graph &g) const {
if (destination_vertex_m == s)
throw(2);
}
};
然后我使用了带有try-catch块的Boost Dijkstra来获取异常。
// To store predecessor
std::vector<Vertex> predecessor_map_p (boost::num_vertices(graph_m));
// To store distances
std::vector<double> distance_map_p (boost::num_vertices(graph_m));
// Vertex that will have set to the origin and the destination :
Vertex vertex_origin_num_p,vertex_destination_num_p;
// Visitor to throw an exception when the end is reached
my_visitor vis(vertex_destination_num_p);
try {
boost::dijkstra_shortest_paths(
graph_m,
vertex_origin_num_p,
predecessor_map(boost::make_iterator_property_map(predecessor_map_p->data(), vid_l)).
distance_map(boost::make_iterator_property_map(distance_map_p->data(), vid_l)).
visitor(vis)
);
}
catch (int exception) {
std::cout << "The Dijsktra algorithm stopped" << std::endl;
}
boost::ref(my_visitor)
(但我不确定它是否有效,在这种情况下没有使用过)。无论如何,这种语法通常对函数对象有效,因为 reference_wrapper
转发函数调用运算符。 - sehe