Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
IDAStar.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/set>
13#include <alib/pair>
14#include <limits>
15#include <algorithm>
16#include <stdexcept>
17
20
21namespace graph {
22
23namespace shortest_path {
24
25class IDAStar {
26// ---------------------------------------------------------------------------------------------------------------------
27 public:
28
48 template<
49 typename TGraph,
50 typename TNode,
51 typename F1 = std::function<typename TGraph::edge_type::weight_type(const TNode &)>,
52 typename F2 = std::function<void(const TNode &, const typename TGraph::edge_type::weight_type &)>>
53 static
54 ext::pair<ext::vector<TNode>, typename TGraph::edge_type::weight_type>
55 findPath(const TGraph &graph,
56 const TNode &start,
57 const TNode &goal,
58 F1 f_heuristic,
59 F2 f_user = [](const TNode &,
60 const typename TGraph::edge_type::weight_type &) {});
61
62 template<
63 typename TGraph,
64 typename TNode,
65 typename F1 = std::function<typename TGraph::edge_type::weight_type(const TNode &, const TNode &)>
66 >
67 static
68 ext::pair<ext::vector<TNode>, typename TGraph::edge_type::weight_type>
70 const TNode &start,
71 const TNode &goal,
72 F1 f_heuristic) {
73 return findPath(graph, start, goal, [&](const TNode &n) { return f_heuristic(goal, n); });
74
75 }
76
77// ---------------------------------------------------------------------------------------------------------------------
78
79// =====================================================================================================================
80
81 private:
82
83 template<typename TNode, typename TWeight>
84 struct Data {
85 ext::vector<TNode> path; // current path
86 ext::set<TNode> path_set; // current path set for quick search
87 TWeight path_size; // size of found path
88 };
89
90// ---------------------------------------------------------------------------------------------------------------------
91
92 template<typename TGraph, typename TNode, typename F1, typename F2>
93 static
95 search(const TGraph &graph,
96 IDAStar::Data<TNode, typename TGraph::edge_type::weight_type> &data,
97 const TNode &goal,
98 typename TGraph::edge_type::weight_type gscore,
99 typename TGraph::edge_type::weight_type bound,
100 F1 f_heuristic,
101 F2 f_user);
102
103// ---------------------------------------------------------------------------------------------------------------------
104
105};
106
107// =====================================================================================================================
108
109template<typename TGraph, typename TNode, typename F1, typename F2>
110ext::pair<ext::vector<TNode>, typename TGraph::edge_type::weight_type>
112 const TNode &start,
113 const TNode &goal,
114 F1 f_heuristic,
115 F2 f_user) {
116 using weight_type = typename TGraph::edge_type::weight_type;
117
118 Data<TNode, weight_type> data;
119 data.path.push_back(start);
120 data.path_set.insert(start);
121
122 weight_type bound = f_heuristic(start);
123 while ( true ) {
124 bool found;
125 weight_type t;
126 ext::tie(found, t) = search(graph, data, goal, 0, bound, f_heuristic, f_user);
127
128 if (found) {
129 return ext::make_pair(data.path, data.path_size); // Return found path
130 } else if (t == std::numeric_limits<weight_type>::max()) {
132 }
133
134 bound = t;
135 }
136}
137
138// ---------------------------------------------------------------------------------------------------------------------
139
140template<typename TGraph, typename TNode, typename F1, typename F2>
142IDAStar::search(const TGraph &graph,
143 IDAStar::Data<TNode, typename TGraph::edge_type::weight_type> &data,
144 const TNode &goal,
145 typename TGraph::edge_type::weight_type gscore,
146 typename TGraph::edge_type::weight_type bound,
147 F1 f_heuristic,
148 F2 f_user) {
149 using weight_type = typename TGraph::edge_type::weight_type;
150
151 TNode n = data.path.back();
152 weight_type f = gscore + f_heuristic(n);
153
154 if (f > bound) {
155 return ext::make_pair(false, f);
156 }
157
158 // Run user function
159 f_user(n, gscore);
160
161 // Check for goal
162 if (n == goal) {
163 data.path_size = gscore;
164 return ext::make_pair(true, f);
165 }
166
168 for (const auto &s_edge: graph.successorEdges(n)) {
169 const TNode &s = common::SupportFunction::other(s_edge, n); // successor
170
171 // Check if node is not in path
172 if (data.path_set.find(s) != data.path_set.end()) {
173 continue;
174 }
175
176 // Check for negative edge
177 if (s_edge.weight() < 0) {
178 throw std::out_of_range("IDAStar: Detect negative weight on edge in graph.");
179 }
180
181 bool found;
182 weight_type t;
183
184 data.path.push_back(s); // Insert node to the path
185 data.path_set.insert(s);
186 ext::tie(found, t) =
187 search(graph, data, goal, gscore + s_edge.weight(), bound, f_heuristic, f_user); // Run recursion
188
189 if (found) {
190 return ext::make_pair(true, t);
191 } else if (t < min) {
192 min = t; // Update min
193 }
194
195 data.path.pop_back(); // Pop node from the path
196 data.path_set.erase(data.path_set.find(s));
197 }
198
199 return ext::make_pair(false, min);
200}
201
202// ---------------------------------------------------------------------------------------------------------------------
203
204} // namespace shortest_path
205
206} // namespace graph
207
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
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
static TNode const & other(const TEdge &e, const TNode &n)
Definition: IDAStar.hpp:25
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: IDAStar.hpp:69
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: IDAStar.hpp:111
constexpr tuple< Elements &... > tie(Elements &... args) noexcept
Helper of extended tuple of references construction. The tuple is constructed to reffer to values in ...
Definition: tuple.hpp:218
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_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