Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Concepts
GreedyBestFS.hpp
Go to the documentation of this file.
1
6// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
7
8#pragma once
9
10#include <functional>
11#include <alib/vector>
12#include <alib/pair>
13#include <alib/set>
14#include <alib/map>
15
18
19namespace graph {
20
21namespace shortest_path {
22
24// ---------------------------------------------------------------------------------------------------------------------
25
26 public:
27
46 template<
47 typename TGraph,
48 typename TNode,
49 typename F1 = std::function<typename TGraph::edge_type::weight_type(const TNode &)>,
50 typename F2 = std::function<void(const TNode &, const typename TGraph::edge_type::weight_type &)>>
51 static
52 ext::pair<ext::vector<TNode>, typename TGraph::edge_type::weight_type>
53 findPath(const TGraph &graph,
54 const TNode &start,
55 const TNode &goal,
56 F1 f_heuristic,
57 F2 f_user = [](const TNode &,
58 const typename TGraph::edge_type::weight_type &) {});
59
60 template<
61 typename TGraph,
62 typename TNode,
63 typename F1 = std::function<typename TGraph::edge_type::weight_type(const TNode &, const TNode &)>
64 >
65 static
66 ext::pair<ext::vector<TNode>, typename TGraph::edge_type::weight_type>
68 const TNode &start,
69 const TNode &goal,
70 F1 f_heuristic) {
71 return findPath(graph, start, goal, [&](const TNode &n) { return f_heuristic(goal, n); });
72 }
73
74// =====================================================================================================================
75
76 private:
77
78 template<typename TNode, typename TWeight>
79 struct Data {
80 ext::set<ext::pair<TWeight, TNode>> queue; // priority queue
81 ext::map<TNode, TWeight> g; // G score
82 ext::map<TNode, TNode> p; // parents
83 };
84
85// ---------------------------------------------------------------------------------------------------------------------
86
87 template<typename FEdges, typename TNode, typename TWeight, typename F1, typename F2, typename F3>
88 static bool relaxation(FEdges successor_edges,
89 Data<TNode, TWeight> &data,
90 F1 f_heuristic,
91 F2 f_user,
92 F3 f_stop);
93
94// ---------------------------------------------------------------------------------------------------------------------
95
96 template<typename TNode, typename TWeight, typename F>
97 inline static void init(GreedyBestFS::Data<TNode, TWeight> &data, const TNode &start, F f_heuristic);
98
99// ---------------------------------------------------------------------------------------------------------------------
100
101};
102
103// =====================================================================================================================
104
105template<typename TGraph, typename TNode, typename F1, typename F2>
106ext::pair<ext::vector<TNode>, typename TGraph::edge_type::weight_type>
108 const TNode &start,
109 const TNode &goal,
110 F1 f_heuristic,
111 F2 f_user) {
112 using weight_type = typename TGraph::edge_type::weight_type;
113
114 Data<TNode, weight_type> data;
115
116 // Init search
117 init(data, start, f_heuristic);
118
119 while (!data.queue.empty()) {
120 bool stop = relaxation([&](const auto &node) -> auto { return graph.successorEdges(node); },
121 data,
122 f_heuristic,
123 f_user,
124 [&goal](const TNode &n) -> bool { return goal == n; });
125
126 if (stop) {
127 break;
128 }
129 }
130
131 return common::ReconstructPath::reconstructWeightedPath(data.p, data.g, start, goal);
132}
133
134// ---------------------------------------------------------------------------------------------------------------------
135
136template<typename FEdges, typename TNode, typename TWeight, typename F1, typename F2, typename F3>
137bool
138GreedyBestFS::relaxation(FEdges successor_edges,
139 GreedyBestFS::Data<TNode, TWeight> &data,
140 F1 f_heuristic,
141 F2 f_user,
142 F3 f_stop) {
143 TNode n = data.queue.begin()->second;
144 data.queue.erase(data.queue.begin());
145
146 // Run user's function
147 f_user(n, data.g[n]);
148
149 // Stop if reach the goal
150 if (f_stop(n)) {
151 return true;
152 }
153
154 for (const auto &s_edge: successor_edges(n)) {
155 const TNode &s = common::SupportFunction::other(s_edge, n); // successor
156
157 // Check for negative edge
158 if (s_edge.weight() < 0) {
159 throw std::out_of_range("GreedyBestFS: Detect negative weight on edge in graph.");
160 }
161
162 // Calculate new G score
163 TWeight gscore = data.g.at(n) + s_edge.weight();
164
165 // Search if the node s was already visited
166 auto search_g = data.g.find(s);
167
168 // If not or the G score can be improve do relaxation
169 if (search_g == data.g.end() || data.g.at(s) > gscore) {
170 data.g[s] = gscore;
171 data.p.insert_or_assign(s, n);
172 if (search_g == data.g.end()) {
173 data.queue.insert(ext::make_pair(f_heuristic(s), s));
174 }
175 }
176 }
177
178 return false;
179}
180
181// ---------------------------------------------------------------------------------------------------------------------
182
183template<typename TNode, typename TWeight, typename F>
184void GreedyBestFS::init(GreedyBestFS::Data<TNode, TWeight> &data, const TNode &start, F f_heuristic) {
185 data.g[start] = 0;
186 data.p.insert_or_assign(start, start);
187 data.queue.insert(ext::make_pair(f_heuristic(start), start));
188}
189
190// ---------------------------------------------------------------------------------------------------------------------
191
192} // namespace shortest_path
193
194} // namespace graph
195
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
Definition: set.hpp:44
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 TNode const & other(const TEdge &e, const TNode &n)
Definition: GreedyBestFS.hpp:23
static ext::pair< ext::vector< TNode >, typename TGraph::edge_type::weight_type > findPath(const TGraph &graph, const TNode &start, const TNode &goal, F1 f_heuristic, F2 f_user=[](const TNode &, const typename TGraph::edge_type::weight_type &) {})
Definition: GreedyBestFS.hpp:107
static ext::pair< ext::vector< TNode >, typename TGraph::edge_type::weight_type > findPathRegistration(const TGraph &graph, const TNode &start, const TNode &goal, F1 f_heuristic)
Definition: GreedyBestFS.hpp:67
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
Definition: Node.cpp:11