12#include <ext/algorithm>
24namespace shortest_path {
55 typename F1 = std::function<
typename TGraph::edge_type::weight_type(
const TNode &)>,
56 typename F2 = std::function<
typename TGraph::edge_type::weight_type(
const TNode &)>,
57 typename F3 = std::function<void(
const TNode &,
const typename TGraph::edge_type::weight_type &)>>
63 F1 f_heuristic_forward,
64 F2 f_heuristic_backward,
65 F3 f_user = [](
const TNode &,
66 const typename TGraph::edge_type::weight_type &) {});
71 typename F1 = std::function<
typename TGraph::edge_type::weight_type(
const TNode &,
const TNode &)>
80 [&](
const TNode &n) {
return f_heuristic(goal, n); },
81 [&](
const TNode &n) {
return f_heuristic(
start, n); });
90 template<
typename TNode,
typename TWeight>
105 template<
typename FSuccEdge,
typename TNode,
typename TWeight,
typename F1,
typename F2,
typename F3>
106 static void relaxation(FSuccEdge successor_edges,
107 Data<TNode, TWeight> &data,
114 template<
typename TNode,
typename TWeight,
typename F>
115 inline static void init(MM::Data<TNode, TWeight> &data,
const TNode &
start, F f_heuristic);
124template<
typename TGraph,
typename TNode,
typename F1,
typename F2,
typename F3>
129 F1 f_heuristic_forward,
130 F2 f_heuristic_backward,
133 using weight_type =
typename TGraph::edge_type::weight_type;
139 Data<TNode, weight_type> forward_data;
140 Data<TNode, weight_type> backward_data;
143 init(forward_data,
start, f_heuristic_forward);
144 auto f_forward_update = [&](
const auto &s) ->
void {
145 if (backward_data.g_map.find(s) != backward_data.g_map.end()) {
146 if (forward_data.g_map.at(s) + backward_data.g_map.at(s) < p) {
147 p = forward_data.g_map.at(s) + backward_data.g_map.at(s);
148 intersection_nodes.push_back(s);
154 init(backward_data, goal, f_heuristic_backward);
155 auto f_backward_update = [&](
const auto &s) ->
void {
156 if (forward_data.g_map.find(s) != forward_data.g_map.end()) {
157 if (backward_data.g_map.at(s) + forward_data.g_map.at(s) < p) {
158 p = backward_data.g_map.at(s) + forward_data.g_map.at(s);
159 intersection_nodes.push_back(s);
164 while (!forward_data.queue.empty() && !backward_data.queue.empty()) {
167 std::get<0>(*backward_data.queue.begin())),
168 forward_data.f_set.begin()->first,
169 backward_data.f_set.begin()->first,
170 forward_data.g_set.begin()->first + backward_data.g_set.begin()->first + eps)
178 intersection_nodes.back());
182 if (std::get<0>(*forward_data.queue.begin()) < std::get<0>(*backward_data.queue.begin())) {
184 relaxation([&](
const auto &
node) ->
auto {
return graph.successorEdges(
node); },
191 relaxation([&](
const auto &
node) ->
auto {
return graph.predecessorEdges(
node); },
193 f_heuristic_backward,
204template<
typename FSuccEdge,
typename TNode,
typename TWeight,
typename F1,
typename F2,
typename F3>
205void MM::relaxation(FSuccEdge successor_edges,
206 MM::Data<TNode, TWeight> &data,
210 TNode n = std::get<2>(*data.queue.begin());
211 data.queue.erase(data.queue.begin());
212 data.f_set.erase(data.f_set.find(
ext::make_pair(data.f_map[n], n)));
213 data.g_set.erase(data.g_set.find(
ext::make_pair(data.g_map[n], n)));
216 f_user(n, data.g_map[n]);
218 for (
const auto &s_edge: successor_edges(n)) {
222 if (s_edge.weight() < 0) {
223 throw std::out_of_range(
"MM: Detect negative weight on edge in graph.");
227 TWeight gscore = data.g_map.at(n) + s_edge.weight();
230 auto search_g = data.g_map.find(s);
233 if (search_g == data.g_map.end() || data.g_map.at(s) > gscore) {
235 auto search_q = data.queue.find(
ext::make_tuple(
std::max(data.f_map[s], 2 * data.g_map[s]), data.g_map[s], s));
237 if (search_q != data.queue.end()) {
239 data.queue.erase(search_q);
240 data.g_set.erase(data.g_set.find(
ext::make_pair(data.g_map[s], s)));
241 data.f_set.erase(data.f_set.find(
ext::make_pair(data.f_map[s], s)));
244 data.g_map[s] = gscore;
246 data.f_map[s] = gscore + f_heuristic(s);
248 data.p.insert_or_assign(s, n);
258template<
typename TNode,
typename TWeight,
typename F>
259void MM::init(MM::Data<TNode, TWeight> &data,
const TNode &
start, F f_heuristic) {
260 data.g_map[
start] = 0;
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
Class extending the pair class from the standard library. Original reason is to allow printing of the...
Definition: pair.hpp:43
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
static ext::pair< ext::vector< TNode >, TWeight > reconstructWeightedPath(const ext::map< TNode, TNode > &p, const ext::map< TNode, TWeight > &g, const TNode &start, const TNode &goal)
Definition: ReconstructPath.hpp:132
static TGraph::edge_type::weight_type getMinEdgeValue(const TGraph &graph)
Definition: SupportFunction.hpp:71
static TNode const & other(const TEdge &e, const TNode &n)
static ext::pair< ext::vector< TNode >, typename TGraph::edge_type::weight_type > findPathBidirectional(const TGraph &graph, const TNode &start, const TNode &goal, F1 f_heuristic_forward, F2 f_heuristic_backward, F3 f_user=[](const TNode &, const typename TGraph::edge_type::weight_type &) {})
Definition: MM.hpp:126
static ext::pair< ext::vector< TNode >, typename TGraph::edge_type::weight_type > findPathBidirectionalRegistration(const TGraph &graph, const TNode &start, const TNode &goal, F1 f_heuristic)
Definition: MM.hpp:75
constexpr const T & max(const T &a)
Root case of maximum computation. The maximum from one value is the value itself.
Definition: algorithm.hpp:278
constexpr const T & min(const T &a)
Definition: algorithm.hpp:310
constexpr auto make_tuple(Elements &&... args)
Helper of extended tuple construction. The tuple is constructed from values pack, types are deduced.
Definition: tuple.hpp:203
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
Definition: ReconstructPath.hpp:14
void start(measurements::stealth_string name, measurements::Type type)
Definition: measurements.cpp:14