From 54199cd0228a2eeb47d59529cca8b76466d5c4aa Mon Sep 17 00:00:00 2001 From: Vicky Vergara Date: Fri, 19 May 2023 09:48:52 -0600 Subject: [PATCH] Astar code simplification (#2517) * [visitors] moving visitors to different file * [astar][C++] pgr_astar.hpp -> astar.hpp * :broom: deleting unused code * Using combinations for departures & destinations * using std::set * using detail namespace * using function instead of class * [doc] updating news and release notes --- NEWS | 2 + doc/src/release_notes.rst | 2 + include/astar/astar.hpp | 207 +++++++++ include/astar/pgr_astar.hpp | 406 ------------------ include/drivers/astar/astar_driver.h | 40 +- include/visitors/astar_visitors.hpp | 61 +++ .../en/LC_MESSAGES/pgrouting_doc_strings.po | 7 +- locale/pot/pgrouting_doc_strings.pot | 5 +- src/astar/astar.c | 3 +- src/astar/astar_driver.cpp | 94 ++-- 10 files changed, 319 insertions(+), 508 deletions(-) create mode 100644 include/astar/astar.hpp delete mode 100644 include/astar/pgr_astar.hpp create mode 100644 include/visitors/astar_visitors.hpp diff --git a/NEWS b/NEWS index 3fc20ae10a1..013bac35928 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,8 @@ pgRouting 3.6.0 Release Notes * `2505 ` Using namespace. * `2512 ` [Dijkstra] Removing duplicate code on Dijkstra. +* `2517 ` Astar code + simplification. **Documentation** diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index c7ae50d60b2..48db6f8403b 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -42,6 +42,8 @@ pgRouting 3.6.0 Release Notes * `2505 ` Using namespace. * `2512 ` [Dijkstra] Removing duplicate code on Dijkstra. +* `2517 ` Astar code + simplification. .. rubric:: Documentation diff --git a/include/astar/astar.hpp b/include/astar/astar.hpp new file mode 100644 index 00000000000..a723a84e1c3 --- /dev/null +++ b/include/astar/astar.hpp @@ -0,0 +1,207 @@ +/*PGR-GNU***************************************************************** + +File: astar.hpp + +Copyright (c) 2023 Vicky Vergara +Copyright (c) 2015 Vicky Vergara +Mail: vicky at erosion.dev + +------ + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + ********************************************************************PGR-GNU*/ + +#ifndef INCLUDE_ASTAR_PGR_ASTAR_HPP_ +#define INCLUDE_ASTAR_PGR_ASTAR_HPP_ +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include "visitors/astar_visitors.hpp" +#include "cpp_common/basePath_SSEC.hpp" +#include "cpp_common/pgr_base_graph.hpp" +#include "cpp_common/interruption.h" +#include "c_types/ii_t_rt.h" + +namespace detail { + +template +class distance_heuristic : public boost::astar_heuristic { + public: + distance_heuristic( + B_G &g, + const std::set &destinations, + int heuristic, + double factor) + : m_g(g), + m_goals(destinations), + m_factor(factor), + m_heuristic(heuristic) {} + + double operator()(V u) { + if (m_heuristic == 0) return 0; + if (m_goals.empty()) return 0; + double best_h((std::numeric_limits::max)()); + for (auto goal : m_goals) { + double current((std::numeric_limits::max)()); + double dx = m_g[goal].x() - m_g[u].x(); + double dy = m_g[goal].y() - m_g[u].y(); + switch (m_heuristic) { + case 0: + current = 0; + break; + case 1: + current = std::fabs((std::max)(dx, dy)) * m_factor; + break; + case 2: + current = std::fabs((std::min)(dx, dy)) * m_factor; + break; + case 3: + current = (dx * dx + dy * dy) * m_factor * m_factor; + break; + case 4: + current = std::sqrt(dx * dx + dy * dy) * m_factor; + break; + case 5: + current = (std::fabs(dx) + std::fabs(dy)) * m_factor; + break; + default: + current = 0; + } + if (current < best_h) { + best_h = current; + } + } + { + auto s_it = m_goals.find(u); + if (!(s_it == m_goals.end())) { + // found one more goal + m_goals.erase(s_it); + } + } + return best_h; + } + + private: + B_G &m_g; + std::set m_goals; + double m_factor; + int m_heuristic; +}; + +template +bool astar_1_to_many( + G &graph, + std::vector &predecessors, + std::vector &distances, + V departure, + const std::set &destinations, + int heuristic, + double factor, + double epsilon) { + typedef typename G::B_G B_G; + bool found = false; + CHECK_FOR_INTERRUPTS(); + try { + boost::astar_search( + graph.graph, departure, + distance_heuristic( + graph.graph, destinations, + heuristic, factor * epsilon), + boost::predecessor_map(&predecessors[0]) + .weight_map(get(&pgrouting::Basic_edge::cost, graph.graph)) + .distance_map(&distances[0]) + .visitor(pgrouting::visitors::astar_many_goals_visitor(destinations))); + } + catch(pgrouting::found_goals &) { + found = true; // Target vertex found + } + return found; +} + +template +std::deque get_paths( + const G &graph, + const std::vector &predecessors, + const std::vector &distances, + V source, + const std::set &targets, + bool only_cost) { + using Path = pgrouting::Path; + std::deque paths; + for (const auto &target : targets) { + auto p = Path(graph, + source, target, + predecessors, distances, + false); + paths.push_back(Path(graph, p, only_cost)); + } + return paths; +} + +} // namespace detail + +namespace pgrouting { +namespace algorithms { + +template < class G > +std::deque astar( + G &graph, + const std::map> &combinations, + int heuristic, + double factor, + double epsilon, + bool only_cost) { + typedef typename G::V V; + std::deque paths; + + for (const auto &c : combinations) { + if (!graph.has_vertex(c.first)) continue; + std::vector predecessors(graph.num_vertices()); + std::vector distances(graph.num_vertices()); + + auto departure(graph.get_V(c.first)); + std::set destinations; + + for (const auto &vertex : c.second) { + if (graph.has_vertex(vertex)) { + destinations.insert(graph.get_V(vertex)); + } + } + + detail::astar_1_to_many(graph, predecessors, distances, departure, destinations, heuristic, factor, epsilon); + auto r_paths = detail::get_paths(graph, predecessors, distances, departure, destinations, only_cost); + + std::stable_sort(r_paths.begin(), r_paths.end(), + [](const Path &e1, const Path &e2)->bool { + return e1.end_id() < e2.end_id(); + }); + paths.insert(paths.end(), r_paths.begin(), r_paths.end()); + } + + return paths; +} + +} // namespace algorithms +} // namespace pgrouting + +#endif // INCLUDE_ASTAR_PGR_ASTAR_HPP_ diff --git a/include/astar/pgr_astar.hpp b/include/astar/pgr_astar.hpp deleted file mode 100644 index 2e49e5db7f2..00000000000 --- a/include/astar/pgr_astar.hpp +++ /dev/null @@ -1,406 +0,0 @@ -/*PGR-GNU***************************************************************** - -File: pgr_astar.hpp - -Copyright (c) 2015 Vicky Vergara -Mail: vicky_vergara@hotmail.com -Mail: project@pgrouting.org - ------- - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - ********************************************************************PGR-GNU*/ - -#ifndef INCLUDE_ASTAR_PGR_ASTAR_HPP_ -#define INCLUDE_ASTAR_PGR_ASTAR_HPP_ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "cpp_common/basePath_SSEC.hpp" -#include "cpp_common/pgr_base_graph.hpp" -#include "cpp_common/interruption.h" -#include "c_types/ii_t_rt.h" - -namespace pgrouting { -namespace algorithms { - -template < class G > -class Pgr_astar { - public: - typedef typename G::V V; - typedef typename G::B_G B_G; - - - void clear() { - predecessors.clear(); - distances.clear(); - } - - //! @name Astar - //@{ - //! one to one - //! astar 1 to 1 - Path astar( - G &graph, - int64_t start_vertex, - int64_t end_vertex, - int heuristic, - double factor, - double epsilon, - bool only_cost) { - clear(); - - predecessors.resize(graph.num_vertices()); - distances.resize(graph.num_vertices()); - - if (!graph.has_vertex(start_vertex) - || !graph.has_vertex(end_vertex)) { - return Path(start_vertex, end_vertex); - } - - auto v_source(graph.get_V(start_vertex)); - auto v_target(graph.get_V(end_vertex)); - - // perform the algorithm - astar_1_to_1(graph, v_source, v_target, heuristic, factor, epsilon); - - auto solution = Path(graph, Path(graph, - v_source, v_target, - predecessors, distances, - false), only_cost); - - return solution; - } - - //! astar 1 to many - std::deque astar( - G &graph, - int64_t start_vertex, - std::vector end_vertex, - int heuristic, - double factor, - double epsilon, - bool only_cost) { - clear(); - - predecessors.resize(graph.num_vertices()); - distances.resize(graph.num_vertices()); - - if (!graph.has_vertex(start_vertex)) return std::deque(); - auto v_source(graph.get_V(start_vertex)); - - std::vector v_targets; - for (const auto &vertex : end_vertex) { - if (graph.has_vertex(vertex)) { - v_targets.push_back(graph.get_V(vertex)); - } - } - - astar_1_to_many(graph, - v_source, - v_targets, - heuristic, - factor, - epsilon); - - auto paths = get_paths(graph, v_source, v_targets, only_cost); - - std::stable_sort(paths.begin(), paths.end(), - [](const Path &e1, const Path &e2)->bool { - return e1.end_id() < e2.end_id(); - }); - - return paths; - } - - // preparation for many to many - std::deque astar( - G &graph, - std::vector start_vertex, - std::vector end_vertex, - int heuristic, - double factor, - double epsilon, - bool only_cost) { - std::deque paths; - for (const auto &start : start_vertex) { - auto r_paths = astar(graph, start, end_vertex, - heuristic, factor, epsilon, only_cost); - paths.insert(paths.begin(), r_paths.begin(), r_paths.end()); - } - - std::sort(paths.begin(), paths.end(), - [](const Path &e1, const Path &e2)->bool { - return e1.end_id() < e2.end_id(); - }); - std::stable_sort(paths.begin(), paths.end(), - [](const Path &e1, const Path &e2)->bool { - return e1.start_id() < e2.start_id(); - }); - return paths; - } - - // preparation for parallel arrays - std::deque astar( - G &graph, - const std::vector &combinations, - int heuristic, - double factor, - double epsilon, - bool only_cost) { - // a call to 1 to many is faster for each of the sources - std::deque paths; - - // group targets per distinct source - std::map< int64_t, std::vector > vertex_map; - for (const II_t_rt &comb : combinations) { - std::map< int64_t, std::vector >::iterator it = vertex_map.find(comb.d1.source); - if (it != vertex_map.end()) { - it->second.push_back(comb.d2.target); - } else { - std::vector targets{comb.d2.target}; - vertex_map[comb.d1.source] = targets; - } - } - - for (const auto &start_ends : vertex_map) { - auto r_paths = astar( - graph, - start_ends.first, start_ends.second, - heuristic, factor, epsilon, only_cost); - paths.insert(paths.end(), r_paths.begin(), r_paths.end()); - } - - return paths; - } - //@} - - - - private: - //! @name members; - //@{ - struct found_goals{}; //!< exception for termination - std::vector< V > predecessors; - std::vector< double > distances; - std::deque< V > nodesInDistance; - //@} - - // heuristic for one goal - class distance_heuristic : public boost::astar_heuristic< B_G, double > { - public: - distance_heuristic(B_G &g, V goal, int heuristic, double factor) - : m_g(g), - m_factor(factor), - m_heuristic(heuristic) { - m_goals.insert(goal); - } - distance_heuristic( - B_G &g, - const std::vector< V > &goals, - int heuristic, - double factor) - : m_g(g), - m_goals(goals.begin(), goals.end()), - m_factor(factor), - m_heuristic(heuristic) {} - - double operator()(V u) { - if (m_heuristic == 0) return 0; - if (m_goals.empty()) return 0; - double best_h((std::numeric_limits::max)()); - for (auto goal : m_goals) { - double current((std::numeric_limits::max)()); - double dx = m_g[goal].x() - m_g[u].x(); - double dy = m_g[goal].y() - m_g[u].y(); - switch (m_heuristic) { - case 0: - current = 0; - break; - case 1: - current = std::fabs((std::max)(dx, dy)) * m_factor; - break; - case 2: - current = std::fabs((std::min)(dx, dy)) * m_factor; - break; - case 3: - current = (dx * dx + dy * dy) * m_factor * m_factor; - break; - case 4: - current = std::sqrt(dx * dx + dy * dy) * m_factor; - break; - case 5: - current = (std::fabs(dx) + std::fabs(dy)) * m_factor; - break; - default: - current = 0; - } - if (current < best_h) { - best_h = current; - } - } - { - auto s_it = m_goals.find(u); - if (!(s_it == m_goals.end())) { - // found one more goal - m_goals.erase(s_it); - } - } - return best_h; - } - - private: - B_G &m_g; - std::set< V > m_goals; - double m_factor; - int m_heuristic; - }; // class distance_heuristic - - - //! visitor that terminates when we find the goal - class astar_one_goal_visitor : public boost::default_astar_visitor { - public: - explicit astar_one_goal_visitor(V goal) : m_goal(goal) {} - template - void examine_vertex(V u, B_G &g) { - if (u == m_goal) - throw found_goals(); - // using g, otherwise is throws a warning - num_edges(g); - } - private: - V m_goal; - }; // class astar_one_goal_visitor - - //! class for stopping when all targets are found - class astar_many_goals_visitor : public boost::default_astar_visitor { - public: - explicit astar_many_goals_visitor(const std::vector< V > &goals) - :m_goals(goals.begin(), goals.end()) {} - template - void examine_vertex(V u, B_G &g) { - auto s_it = m_goals.find(u); - if (s_it == m_goals.end()) return; - // found one more goal - m_goals.erase(s_it); - if (m_goals.size() == 0) throw found_goals(); - num_edges(g); - } - private: - std::set< V > m_goals; - }; - - /******************** IMPLEMENTTION ******************/ - - - - //! Call to Astar 1 source to 1 target - bool astar_1_to_1( - G &graph, - V source, - V target, - int heuristic, - double factor, - double epsilon) { - bool found = false; - /* abort in case of an interruption occurs (e.g. the query is being cancelled) */ - CHECK_FOR_INTERRUPTS(); - try { - // Call A* named parameter interface - boost::astar_search( - graph.graph, source, - distance_heuristic(graph.graph, target, - heuristic, factor * epsilon), - boost::predecessor_map(&predecessors[0]) - .weight_map(get(&pgrouting::Basic_edge::cost, graph.graph)) - .distance_map(&distances[0]) - .visitor(astar_one_goal_visitor(target))); - } - catch(found_goals &) { - found = true; // Target vertex found - } - return found; - } - - - //! Call to astar 1 source to many targets - bool astar_1_to_many( - G &graph, - V source, - const std::vector< V > &targets, - int heuristic, - double factor, - double epsilon) { - bool found = false; - /* abort in case of an interruption occurs (e.g. the query is being cancelled) */ - CHECK_FOR_INTERRUPTS(); - try { - boost::astar_search( - graph.graph, source, - distance_heuristic( - graph.graph, targets, - heuristic, factor * epsilon), - boost::predecessor_map(&predecessors[0]) - .weight_map(get(&pgrouting::Basic_edge::cost, graph.graph)) - .distance_map(&distances[0]) - .visitor(astar_many_goals_visitor(targets))); - } - catch(found_goals &) { - found = true; // Target vertex found - } - return found; - } - - - /* - * GET_PATHS - */ - - - std::deque get_paths( - const G &graph, - V source, - const std::vector &targets, - bool only_cost) const { - std::deque paths; - for (const auto &target : targets) { - auto p = Path(graph, - source, target, - predecessors, distances, - false); - paths.push_back(Path(graph, p, only_cost)); - } - return paths; - } -}; - - -} // namespace algorithms -} // namespace pgrouting - -#endif // INCLUDE_ASTAR_PGR_ASTAR_HPP_ diff --git a/include/drivers/astar/astar_driver.h b/include/drivers/astar/astar_driver.h index 51cd5ee0d8c..4f7728f2261 100644 --- a/include/drivers/astar/astar_driver.h +++ b/include/drivers/astar/astar_driver.h @@ -5,8 +5,9 @@ Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org Function's developer: +Copyright (c) 2023 Celia Virginia Vergara Castillo Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: +Mail: vicky at erosion.dev ------ @@ -30,7 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #define INCLUDE_DRIVERS_ASTAR_ASTAR_DRIVER_H_ #pragma once -/* for size-t */ #ifdef __cplusplus # include # include @@ -49,32 +49,16 @@ typedef struct Path_rt Path_rt; extern "C" { #endif - /********************************************************* - edges_sql TEXT, - vertex_table TEXT, - start_vid BIGINT, - end_vid BIGINT directed BOOLEAN DEFAULT true, - ********************************************************/ - void do_pgr_astarManyToMany( - Edge_xy_t *data_edges, - size_t total_edges, - - II_t_rt *combinations, - size_t total_combinations, - - int64_t *start_vidsArr, size_t size_start_vidsArr, - int64_t *end_vidsArr, size_t size_end_vidsArr, - bool directed, - int heuristic, - double factor, - double epsilon, - bool only_cost, - bool normal, - Path_rt **return_tuples, - size_t *return_count, - char** log_msg, - char** notice_msg, - char** err_msg); + void pgr_do_astar( + Edge_xy_t*, size_t, + II_t_rt*, size_t, + int64_t*, size_t, + int64_t*, size_t, + + bool, int, double, double, bool, bool, + + Path_rt**, size_t*, + char**, char**, char**); #ifdef __cplusplus diff --git a/include/visitors/astar_visitors.hpp b/include/visitors/astar_visitors.hpp new file mode 100644 index 00000000000..5d24e61627b --- /dev/null +++ b/include/visitors/astar_visitors.hpp @@ -0,0 +1,61 @@ +/*PGR-GNU***************************************************************** +file: astar_visitors.hpp + +Copyright (c) 2023 Celia Virginia Vergara Castillo +Copyright (c) 2015 Celia Virginia Vergara Castillo +vicky at erosion.dev + +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +------ + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + ********************************************************************PGR-GNU*/ + +#ifndef INCLUDE_VISITORS_ASTAR_VISITORS_HPP_ +#define INCLUDE_VISITORS_ASTAR_VISITORS_HPP_ + +#include +#include +#include "visitors/found_goals.hpp" + +namespace pgrouting { +namespace visitors { + +/** @brief visitor stops when all targets are found */ +template +class astar_many_goals_visitor : public boost::default_astar_visitor { + public: + explicit astar_many_goals_visitor(const std::set &goals) + :m_goals(goals) {} + template + void examine_vertex(V u, B_G &g) { + auto s_it = m_goals.find(u); + if (s_it == m_goals.end()) return; + // found one more goal + m_goals.erase(s_it); + if (m_goals.size() == 0) throw found_goals(); + num_edges(g); + } + private: + std::set m_goals; +}; + +} // namespace visitors +} // namespace pgrouting + +#endif // INCLUDE_VISITORS_ASTAR_VISITORS_HPP_ diff --git a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po index d5b832c283b..3bf322957f6 100644 --- a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po +++ b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: pgRouting v3.6.0-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-16 16:00+0000\n" +"POT-Creation-Date: 2023-05-18 17:55+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -14781,6 +14781,11 @@ msgid "" "Removing duplicate code on Dijkstra." msgstr "" +msgid "" +"`2517 ` Astar code " +"simplification." +msgstr "" + msgid "Documentation" msgstr "" diff --git a/locale/pot/pgrouting_doc_strings.pot b/locale/pot/pgrouting_doc_strings.pot index f52f308aa38..9ab7c2748b7 100644 --- a/locale/pot/pgrouting_doc_strings.pot +++ b/locale/pot/pgrouting_doc_strings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: pgRouting v3.6.0-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-16 16:00+0000\n" +"POT-Creation-Date: 2023-05-18 17:55+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -12598,6 +12598,9 @@ msgstr "" msgid "`2512 ` [Dijkstra] Removing duplicate code on Dijkstra." msgstr "" +msgid "`2517 ` Astar code simplification." +msgstr "" + msgid "Documentation" msgstr "" diff --git a/src/astar/astar.c b/src/astar/astar.c index b1f774f488f..b98589cb038 100644 --- a/src/astar/astar.c +++ b/src/astar/astar.c @@ -105,9 +105,8 @@ process(char* edges_sql, return; } - PGR_DBG("Starting processing"); clock_t start_t = clock(); - do_pgr_astarManyToMany( + pgr_do_astar( edges, total_edges, combinations, total_combinations, diff --git a/src/astar/astar_driver.cpp b/src/astar/astar_driver.cpp index 9611de165ea..e38523bf980 100644 --- a/src/astar/astar_driver.cpp +++ b/src/astar/astar_driver.cpp @@ -1,13 +1,13 @@ /*PGR-GNU***************************************************************** -File: astarOneToOne_driver.cpp +File: astar_driver.cpp -Generated with Template by: Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org Function's developer: +Copyright (c) 2023 Celia Virginia Vergara Castillo Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: +Mail: vicky at erosion.dev ------ @@ -34,57 +34,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include -#include "astar/pgr_astar.hpp" +#include "astar/astar.hpp" +#include "cpp_common/combinations.h" #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" #include "c_types/edge_xy_t.h" #include "c_types/ii_t_rt.h" -namespace { - -template < class G > -std::deque -pgr_astar( - G &graph, - std::vector &combinations, - std::vector sources, - std::vector targets, - int heuristic, - double factor, - double epsilon, - bool only_cost, - bool normal) { - std::sort(sources.begin(), sources.end()); - sources.erase( - std::unique(sources.begin(), sources.end()), - sources.end()); - - std::sort(targets.begin(), targets.end()); - targets.erase( - std::unique(targets.begin(), targets.end()), - targets.end()); - - pgrouting::algorithms::Pgr_astar< G > fn_astar; - auto paths = combinations.empty() ? - fn_astar.astar(graph, sources, targets, heuristic, factor, epsilon, only_cost) - : fn_astar.astar(graph, combinations, heuristic, factor, epsilon, only_cost); - - if (!normal) { - for (auto &path : paths) { - path.reverse(); - } - } - return paths; -} - -} // namespace - -void do_pgr_astarManyToMany( +void pgr_do_astar( Edge_xy_t *edges, size_t total_edges, - II_t_rt *combinations, size_t total_combinations, + II_t_rt *combinationsArr, size_t total_combinations, int64_t *start_vidsArr, size_t size_start_vidsArr, int64_t *end_vidsArr, size_t size_end_vidsArr, @@ -94,11 +56,8 @@ void do_pgr_astarManyToMany( double epsilon, bool only_cost, bool normal, - Path_rt **return_tuples, - size_t *return_count, - char** log_msg, - char** notice_msg, - char** err_msg) { + Path_rt **return_tuples, size_t *return_count, + char** log_msg, char** notice_msg, char** err_msg) { using pgrouting::Path; using pgrouting::pgr_alloc; using pgrouting::pgr_msg; @@ -114,38 +73,35 @@ void do_pgr_astarManyToMany( pgassert(*return_count == 0); pgassert(total_edges != 0); - std::vector - combinations_vector(combinations, combinations + total_combinations); - std::vector< int64_t > end_vids( - end_vidsArr, - end_vidsArr + size_end_vidsArr); - std::vector< int64_t > start_vids( - start_vidsArr, - start_vidsArr + size_start_vidsArr); + auto combinations = total_combinations? + pgrouting::utilities::get_combinations(combinationsArr, total_combinations) + : pgrouting::utilities::get_combinations(start_vidsArr, size_start_vidsArr, end_vidsArr, size_end_vidsArr); graphType gType = directed? DIRECTED: UNDIRECTED; - std::deque< Path >paths; + std::deque paths; if (directed) { - pgrouting::xyDirectedGraph digraph( + pgrouting::xyDirectedGraph graph( pgrouting::extract_vertices(edges, total_edges), gType); - digraph.insert_edges(edges, total_edges); - paths = pgr_astar(digraph, combinations_vector, start_vids, end_vids, - heuristic, factor, epsilon, only_cost, normal); + graph.insert_edges(edges, total_edges); + paths = pgrouting::algorithms::astar(graph, combinations, heuristic, factor, epsilon, only_cost); } else { - pgrouting::xyUndirectedGraph undigraph( + pgrouting::xyUndirectedGraph graph( pgrouting::extract_vertices(edges, total_edges), gType); - undigraph.insert_edges(edges, total_edges); - paths = pgr_astar(undigraph, combinations_vector, start_vids, end_vids, - heuristic, factor, epsilon, only_cost, normal); + graph.insert_edges(edges, total_edges); + paths = pgrouting::algorithms::astar(graph, combinations, heuristic, factor, epsilon, only_cost); + } + if (!normal) { + for (auto &path : paths) { + path.reverse(); + } } size_t count(0); count = count_tuples(paths); - if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; @@ -155,7 +111,6 @@ void do_pgr_astarManyToMany( } (*return_tuples) = pgr_alloc(count, (*return_tuples)); - log << "Converting a set of paths into the tuples\n"; (*return_count) = (collapse_paths(return_tuples, paths)); *log_msg = log.str().empty()? @@ -184,4 +139,3 @@ void do_pgr_astarManyToMany( *log_msg = pgr_msg(log.str().c_str()); } } -