我想你只是想要最短的路径(dijkstra 没问题)。
关键是要意识到您可以使用客户edge_weight
属性映射。这可能是boost::property_map::transform_value_property_map<>
这样的:
auto my_custom_weight_map =
boost::make_transform_value_property_map(
[](float w) { return w>100? 10*w : w; },
boost::get(boost::edge_weight, g));
您会看到任何超过 100 的边权重都会增加十倍。
然后,你基本上已经完成了:
astar_search_tree(g, start,
distance_heuristic<mygraph_t, cost>(goal),
boost::weight_map(my_custom_weight_map) // THIS LINE ADDED
.predecessor_map(make_iterator_property_map(p.begin(), get(boost::vertex_index, g)))
.distance_map(make_iterator_property_map(d.begin(), get(boost::vertex_index, g)))
.visitor(astar_goal_visitor<vertex>(goal))
);
结果是:
Start vertex: A
Goal vertex: E
Shortest path from A to E: A -> B -> C -> D -> E
Total travel time: 210
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/astar_search.hpp>
#include <boost/property_map/transform_value_property_map.hpp>
#include <iostream>
#include <list>
// auxiliary types
struct location {
float y, x; // lat, long
};
typedef float cost;
// euclidean distance heuristic
template <class Graph, class CostType>
class distance_heuristic : public boost::astar_heuristic<Graph, CostType> {
public:
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
distance_heuristic(Vertex goal) : m_goal(goal) {}
CostType operator()(Vertex /*u*/) {
return 0; // Not really needed here
}
private:
Vertex m_goal;
};
struct found_goal {}; // exception for termination
// visitor that terminates when we find the goal
template <class Vertex> class astar_goal_visitor : public boost::default_astar_visitor {
public:
astar_goal_visitor(Vertex goal) : m_goal(goal) {}
template <class Graph> void examine_vertex(Vertex u, Graph &/*g*/) {
if (u == m_goal)
throw found_goal();
}
private:
Vertex m_goal;
};
int main() {
// specify some types
typedef boost::adjacency_list<boost::listS, boost::vecS,
boost::undirectedS, boost::no_property,
boost::property<boost::edge_weight_t, cost>
> mygraph_t;
typedef boost::property_map<mygraph_t, boost::edge_weight_t>::type WeightMap;
typedef mygraph_t::vertex_descriptor vertex;
typedef mygraph_t::edge_descriptor edge_descriptor;
typedef std::pair<int, int> edge;
enum nodes { A, B, C, D, E, N };
const char *name[] = { "A", "B", "C", "D", "E", "F" };
edge edge_array[] = {
edge(A, B), edge(B, C), edge(C, D), edge(D, E), edge(B, D) // B to D is the problem here, it should be excluded
};
cost weights[] = { // estimated travel time (mins)
// 107, 174, 283, 71, 436
35, 58, 94, 23, 145
};
unsigned int num_edges = sizeof(edge_array) / sizeof(edge);
// create graph
mygraph_t g(N);
WeightMap weightmap = get(boost::edge_weight, g);
for (std::size_t j = 0; j < num_edges; ++j) {
edge_descriptor e;
bool inserted;
boost::tie(e, inserted) = add_edge(edge_array[j].first, edge_array[j].second, g);
weightmap[e] = weights[j];
}
// pick start/goal
vertex start = A;
vertex goal = E;
std::cout << "Start vertex: " << name[start] << std::endl;
std::cout << "Goal vertex: " << name[goal] << std::endl;
std::vector<mygraph_t::vertex_descriptor> p(num_vertices(g));
using boost::get;
// do a real edit
std::vector<cost> d(num_vertices(g));
auto my_custom_weight_map =
boost::make_transform_value_property_map(
[](float w) { return w>100? 10*w : w; },
boost::get(boost::edge_weight, g));
try {
// call astar named parameter interface
astar_search_tree(g, start,
distance_heuristic<mygraph_t, cost>(goal),
boost::weight_map(my_custom_weight_map)
.predecessor_map(make_iterator_property_map(p.begin(), get(boost::vertex_index, g)))
.distance_map(make_iterator_property_map(d.begin(), get(boost::vertex_index, g)))
.visitor(astar_goal_visitor<vertex>(goal))
);
} catch (found_goal fg) { // found a path to the goal
std::list<vertex> shortest_path;
for (vertex v = goal;; v = p[v]) {
shortest_path.push_front(v);
if (p[v] == v)
break;
}
std::cout << "Shortest path from " << name[start] << " to " << name[goal] << ": ";
std::list<vertex>::iterator spi = shortest_path.begin();
std::cout << name[start];
for (++spi; spi != shortest_path.end(); ++spi)
std::cout << " -> " << name[*spi];
std::cout << std::endl << "Total travel time: " << d[goal] << std::endl;
return 0;
}
std::cout << "Didn't find a path from " << name[start] << "to" << name[goal] << "!" << std::endl;
return 0;
}