diff --git a/NEWS.md b/NEWS.md index 6eb3d04476c..cac582e6b72 100644 --- a/NEWS.md +++ b/NEWS.md @@ -138,6 +138,15 @@ Summary of changes by function * pgr_edwardMoore * Output columns standardized to ``(seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost)`` + .. rubric:: Version 3.2.0 + * New experimental signature: + * pgr_edwardMoore(Combinations) + .. rubric:: Version 3.0.0 + * New experimental function. + +* pgr_kingOrdering + + * New experimental function. * pgr_KSP @@ -298,6 +307,10 @@ New experimental functions * [#2951](https://github.com/pgRouting/pgrouting/issues/2951): pgr_bandwidth +* Ordering + + * [#2954](https://github.com/pgRouting/pgrouting/issues/2954): pgr_kingOrdering + SQL signatures and output standardization [#2904](https://github.com/pgRouting/pgrouting/issues/2904): Standardize output columns of functions with different output diff --git a/doc/_static/page_history.js b/doc/_static/page_history.js index b86b5d8a87e..654c17cc2a4 100644 --- a/doc/_static/page_history.js +++ b/doc/_static/page_history.js @@ -15,7 +15,8 @@ var titles = [ var newpages = [ - {v: '4.0', pages: ['pgr_bandwidth']}, + {v: '4.0', pages: ['pgr_bandwidth', 'pgr_kingOrdering']}, + {v: '3.8', pages: ['pgr_contractionDeadEnd', 'pgr_contractionLinear', 'pgr_separateCrossing', 'pgr_separateTouching']}, diff --git a/doc/ordering/CMakeLists.txt b/doc/ordering/CMakeLists.txt index be5034c16e1..ebdf7465848 100644 --- a/doc/ordering/CMakeLists.txt +++ b/doc/ordering/CMakeLists.txt @@ -2,6 +2,7 @@ SET(LOCAL_FILES ordering-family.rst pgr_cuthillMckeeOrdering.rst pgr_topologicalSort.rst + pgr_kingOrdering.rst ) foreach (f ${LOCAL_FILES}) diff --git a/doc/ordering/ordering-family.rst b/doc/ordering/ordering-family.rst index 04cd2677b07..2c7d38736e2 100644 --- a/doc/ordering/ordering-family.rst +++ b/doc/ordering/ordering-family.rst @@ -24,6 +24,8 @@ Ordering - Family of functions * :doc:`pgr_cuthillMckeeOrdering` - Return reverse Cuthill-McKee ordering of an undirected graph. * :doc:`pgr_topologicalSort` - Linear ordering of the vertices for directed acyclic graph. +* :doc:`pgr_kingOrdering` - Returns the King ordering of an undirected graphs + acyclic graph. .. official-end @@ -32,6 +34,7 @@ Ordering - Family of functions pgr_cuthillMckeeOrdering pgr_topologicalSort + pgr_kingOrdering See Also ------------------------------------------------------------------------------- diff --git a/doc/ordering/pgr_cuthillMckeeOrdering.rst b/doc/ordering/pgr_cuthillMckeeOrdering.rst index 8a14a71bc13..4940809deaa 100644 --- a/doc/ordering/pgr_cuthillMckeeOrdering.rst +++ b/doc/ordering/pgr_cuthillMckeeOrdering.rst @@ -94,6 +94,8 @@ Edges SQL Result columns ------------------------------------------------------------------------------- +.. node_ordering_start + Returns set of ``(seq, node)`` =============== =========== ====================================== @@ -103,6 +105,8 @@ Column Type Description ``node`` ``BIGINT`` New ordering in reverse order. =============== =========== ====================================== +.. node_ordering_end + See Also ------------------------------------------------------------------------------- diff --git a/doc/ordering/pgr_kingOrdering.rst b/doc/ordering/pgr_kingOrdering.rst new file mode 100644 index 00000000000..c1dadca8740 --- /dev/null +++ b/doc/ordering/pgr_kingOrdering.rst @@ -0,0 +1,139 @@ +.. + **************************************************************************** + pgRouting Manual + Copyright(c) pgRouting Contributors + + This documentation is licensed under a Creative Commons Attribution-Share + Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/ + **************************************************************************** + +.. index:: + single: Ordering Family ; pgr_kingOrdering + single: kingOrdering - Experimental on v4.0 + +| + +``pgr_kingOrdering`` - Experimental +=============================================================================== + +``pgr_kingOrdering`` — Returns the King ordering of an undirected graphs + +.. include:: experimental.rst + :start-after: warning-begin + :end-before: end-warning + +.. rubric:: Version 4.0.0 + + * New experimental function. + +Description +------------------------------------------------------------------------------- + +In numerical linear algebra and graph theory, the King ordering algorithm +is a heuristic designed to reorder the vertices of a graph so as to reduce +its bandwidth. + +The method follows a breadth-first search (BFS) traversal,but with a refinement: +at each step, the unvisited neighbors of the current vertex are inserted into +the queue in ascending order of their pseudo-degree, where the pseudo-degree of +a vertex is the number of edges connecting it to yet-unvisited vertices. This +prioritization often yields a smaller bandwidth compared to simpler BFS orderings. + +**The main characteristics are:** + +- The implementation targets undirected graphs. +- Bandwidth minimization is an NP-complete problem; King ordering provides a practical local minimization approach. +- The time complexity is: :math:`O(m^2 \log(m)|E|)` + + - where :math:`|E|` is the number of edges, + - :math:`m` is the maximum degree among all vertices. + +|Boost| Boost Graph Inside + +Signatures +------------------------------------------------------------------------------ + +.. index:: + single: kingOrdering - Experimental on v4.0 + +.. admonition:: \ \ + :class: signatures + + | pgr_kingOrdering(`Edges SQL`_) + + | Returns set of |result_node_order| + | OR EMPTY SET + +:Example: Graph ordering of pgRouting :doc:`sampledata` + +.. literalinclude:: kingOrdering.queries + :start-after: -- q1 + :end-before: -- q2 + +Parameters +------------------------------------------------------------------------------- + +.. include:: pgRouting-concepts.rst + :start-after: only_edge_param_start + :end-before: only_edge_param_end + +Inner Queries +------------------------------------------------------------------------------- + +Edges SQL +............................................................................... + +.. include:: pgRouting-concepts.rst + :start-after: basic_edges_sql_start + :end-before: basic_edges_sql_end + +Result columns +------------------------------------------------------------------------------- + +.. include:: pgr_cuthillMckeeOrdering.rst + :start-after: node_ordering_start + :end-before: node_ordering_end + +Additional Examples +------------------------------------------------------------------------------- + +.. graphviz:: + + graph G { + node [shape=circle, style=filled, fillcolor=white, color=black, fontcolor=black, fontsize=10]; + edge [color=black, penwidth=1]; + + 4 -- 7; + 7 -- 9; + 7 -- 0; + 0 -- 2; + 2 -- 5; + 5 -- 9; + 9 -- 8; + 9 -- 1; + 5 -- 1; + 9 -- 6; + 6 -- 3; + 1 -- 3; + + {rank=same; 4; 8; 6;} + {rank=same; 7; 9; 3;} + {rank=same; 0; 2; 5; 1;} + } + +.. literalinclude:: kingOrdering.queries + :start-after: -- q2 + :end-before: -- q3 + +See Also +------------------------------------------------------------------------------- + +* :doc:`sampledata` +* `Boost: King Ordering + `__ + +.. rubric:: Indices and tables + +* :ref:`genindex` +* :ref:`search` + diff --git a/doc/src/pgRouting-introduction.rst b/doc/src/pgRouting-introduction.rst index c06b03b287e..4f75028b0b9 100644 --- a/doc/src/pgRouting-introduction.rst +++ b/doc/src/pgRouting-introduction.rst @@ -66,6 +66,7 @@ This Release Contributors Individuals in this release v4.0.0 (in alphabetical order) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Fan Wu Regina Obe, Saloni kumari, Vicky Vergara @@ -119,6 +120,7 @@ David Techer, Denis Rykov, Ema Miyawaki, Esteban Zimanyi, +Fan Wu, Florian Thurkow, Frederic Junod, Gerald Fenoy, diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index c737882b279..2eea712e8b5 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -212,7 +212,13 @@ Summary of changes by function .. include:: pgr_edwardMoore.rst :start-after: Version 4.0.0 - :end-before: .. rubric + :end-before: Description + +* pgr_kingOrdering + + .. include:: pgr_kingOrdering.rst + :start-after: Version 4.0.0 + :end-before: Description * pgr_KSP @@ -354,6 +360,10 @@ New experimental functions * :issue:`2951`: pgr_bandwidth +* Ordering + + * :issue:`2954`: pgr_kingOrdering + SQL signatures and output standardization ............................................................................... diff --git a/docqueries/ordering/CMakeLists.txt b/docqueries/ordering/CMakeLists.txt index 9ae17c3d87b..02e5a6767b4 100644 --- a/docqueries/ordering/CMakeLists.txt +++ b/docqueries/ordering/CMakeLists.txt @@ -2,6 +2,7 @@ SET(LOCAL_FILES cuthillMckeeOrdering topologicalSort + kingOrdering ) foreach (f ${LOCAL_FILES}) diff --git a/docqueries/ordering/kingOrdering.pg b/docqueries/ordering/kingOrdering.pg new file mode 100644 index 00000000000..f8327a72b93 --- /dev/null +++ b/docqueries/ordering/kingOrdering.pg @@ -0,0 +1,47 @@ +-- CopyRight(c) pgRouting developers +-- Creative Commons Attribution-Share Alike 3.0 License : https://creativecommons.org/licenses/by-sa/3.0/ +/* -- q1 */ +SELECT * FROM pgr_kingOrdering( + 'SELECT id, source, target, cost, reverse_cost FROM edges' + ); + +/* -- q2 */ +CREATE TABLE additional_sample_1( + id SERIAL PRIMARY KEY, + source INTEGER, + target INTEGER, + cost DOUBLE PRECISION, + reverse_cost DOUBLE PRECISION +); + +INSERT INTO additional_sample_1 (source, target, cost, reverse_cost) VALUES +(4, 7, 1, 1), +(7, 4, 1, 1), +(7, 9, 1, 1), +(9, 7, 1, 1), +(7, 0, 1, 1), +(0, 7, 1, 1), +(0, 2, 1, 1), +(2, 0, 1, 1), +(2, 5, 1, 1), +(5, 2, 1, 1), +(5, 9, 1, 1), +(9, 5, 1, 1), +(9, 8, 1, 1), +(8, 9, 1, 1), +(9, 1, 1, 1), +(1, 9, 1, 1), +(5, 1, 1, 1), +(1, 5, 1, 1), +(9, 6, 1, 1), +(6, 9, 1, 1), +(6, 3, 1, 1), +(3, 6, 1, 1), +(1, 3, 1, 1), +(3, 1, 1, 1); + +SELECT * FROM pgr_kingOrdering( + 'SELECT id, source, target, cost, reverse_cost FROM additional_sample_1' +); + +/* -- q3 */ \ No newline at end of file diff --git a/docqueries/ordering/kingOrdering.result b/docqueries/ordering/kingOrdering.result new file mode 100644 index 00000000000..598493a930c --- /dev/null +++ b/docqueries/ordering/kingOrdering.result @@ -0,0 +1,84 @@ +BEGIN; +BEGIN +SET client_min_messages TO NOTICE; +SET +/* -- q1 */ +SELECT * FROM pgr_kingOrdering( + 'SELECT id, source, target, cost, reverse_cost FROM edges' + ); + seq | node +-----+------ + 1 | 13 + 2 | 14 + 3 | 2 + 4 | 4 + 5 | 1 + 6 | 9 + 7 | 3 + 8 | 8 + 9 | 5 + 10 | 7 + 11 | 12 + 12 | 6 + 13 | 11 + 14 | 17 + 15 | 10 + 16 | 16 + 17 | 15 +(17 rows) + +/* -- q2 */ +CREATE TABLE additional_sample_1( + id SERIAL PRIMARY KEY, + source INTEGER, + target INTEGER, + cost DOUBLE PRECISION, + reverse_cost DOUBLE PRECISION +); +CREATE TABLE +INSERT INTO additional_sample_1 (source, target, cost, reverse_cost) VALUES +(4, 7, 1, 1), +(7, 4, 1, 1), +(7, 9, 1, 1), +(9, 7, 1, 1), +(7, 0, 1, 1), +(0, 7, 1, 1), +(0, 2, 1, 1), +(2, 0, 1, 1), +(2, 5, 1, 1), +(5, 2, 1, 1), +(5, 9, 1, 1), +(9, 5, 1, 1), +(9, 8, 1, 1), +(8, 9, 1, 1), +(9, 1, 1, 1), +(1, 9, 1, 1), +(5, 1, 1, 1), +(1, 5, 1, 1), +(9, 6, 1, 1), +(6, 9, 1, 1), +(6, 3, 1, 1), +(3, 6, 1, 1), +(1, 3, 1, 1), +(3, 1, 1, 1); +INSERT 0 24 +SELECT * FROM pgr_kingOrdering( + 'SELECT id, source, target, cost, reverse_cost FROM additional_sample_1' +); + seq | node +-----+------ + 1 | 0 + 2 | 4 + 3 | 2 + 4 | 7 + 5 | 8 + 6 | 5 + 7 | 9 + 8 | 1 + 9 | 6 + 10 | 3 +(10 rows) + +/* -- q3 */ +ROLLBACK; +ROLLBACK diff --git a/docqueries/ordering/test.conf b/docqueries/ordering/test.conf index 74ee3644ad6..2a4628f6527 100644 --- a/docqueries/ordering/test.conf +++ b/docqueries/ordering/test.conf @@ -5,6 +5,7 @@ 'files' => [qw( cuthillMckeeOrdering.pg topologicalSort.pg + kingOrdering.pg )] }, diff --git a/include/drivers/ordering_driver.hpp b/include/drivers/ordering_driver.hpp new file mode 100644 index 00000000000..947c8d2c53c --- /dev/null +++ b/include/drivers/ordering_driver.hpp @@ -0,0 +1,45 @@ +/*PGR-GNU***************************************************************** +File: ordering_driver.hpp + +Generated with Template by: +Copyright (c) 2025 pgRouting developers +Mail: project@pgrouting.org + +Developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at gmail.com + +------ + +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_DRIVERS_ORDERING_DRIVER_HPP_ +#define INCLUDE_DRIVERS_ORDERING_DRIVER_HPP_ +#pragma once + +#include +#include + + +void +do_ordering( + std::string, int, + int64_t**, size_t*, + char **, char **, char **); + + +#endif // INCLUDE_DRIVERS_ORDERING_DRIVER_HPP_ diff --git a/include/ordering/kingOrdering.hpp b/include/ordering/kingOrdering.hpp new file mode 100644 index 00000000000..0b1e6a43822 --- /dev/null +++ b/include/ordering/kingOrdering.hpp @@ -0,0 +1,85 @@ +/*PGR-GNU***************************************************************** +File: kingOrdering.hpp + +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at gmail.com + +------ + +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_ORDERING_KINGORDERING_HPP_ +#define INCLUDE_ORDERING_KINGORDERING_HPP_ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include "cpp_common/base_graph.hpp" +#include "cpp_common/interruption.hpp" +#include + + +namespace pgrouting { + +template +std::vector +kingOrdering(G &graph) { + using V = typename G::V; + + size_t n = boost::num_vertices(graph.graph); + std::vector results(n); + + auto index_map = boost::get(boost::vertex_index, graph.graph); + + std::vector colors(n); + auto color_map = boost::make_iterator_property_map(colors.begin(), index_map); + auto degree_map = boost::make_degree_map(graph.graph); + std::vector inv_permutation(n); + + CHECK_FOR_INTERRUPTS(); + boost::king_ordering( + graph.graph, + inv_permutation.rbegin(), + color_map, + degree_map, + index_map); + + size_t j = 0; + for (auto i = inv_permutation.begin(); i != inv_permutation.end(); ++i, ++j) { + results[j] = static_cast(graph.graph[index_map[*i]].id); + } + + return results; +} + +} // namespace pgrouting + +#endif // INCLUDE_ORDERING_KINGORDERING_HPP_ diff --git a/include/process/ordering_process.h b/include/process/ordering_process.h new file mode 100644 index 00000000000..ea633eef490 --- /dev/null +++ b/include/process/ordering_process.h @@ -0,0 +1,49 @@ +/*PGR-GNU***************************************************************** +File: ordering_process.h + +Function's developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at gmail.com + +------ + +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_PROCESS_ORDERING_PROCESS_H_ +#define INCLUDE_PROCESS_ORDERING_PROCESS_H_ +#pragma once + +#ifdef __cplusplus +#include +#include + +#else +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void pgr_process_ordering(const char*, int, int64_t**, size_t*); + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDE_PROCESS_ORDERING_PROCESS_H_ diff --git a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po index fb2d91906b3..85185c4bc9c 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.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-08-20 17:25+0000\n" +"POT-Creation-Date: 2025-08-23 02:38+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3401,6 +3401,11 @@ msgid "" " acyclic graph." msgstr "" +msgid "" +":doc:`pgr_kingOrdering` - Returns the King ordering of an undirected " +"graphs acyclic graph." +msgstr "" + msgid ":doc:`metrics-family`" msgstr "" @@ -4081,6 +4086,21 @@ msgstr "" msgid "pgr_edwardMoore" msgstr "" +msgid "Version 3.2.0" +msgstr "" + +msgid "New experimental signature:" +msgstr "" + +msgid "pgr_edwardMoore(Combinations)" +msgstr "" + +msgid "Version 3.0.0" +msgstr "" + +msgid "pgr_kingOrdering" +msgstr "" + msgid "pgr_KSP" msgstr "" @@ -4370,6 +4390,14 @@ msgid "" "pgr_bandwidth" msgstr "" +msgid "Ordering" +msgstr "" + +msgid "" +"`#2954 `__: " +"pgr_kingOrdering" +msgstr "" + msgid "SQL signatures and output standardization" msgstr "" @@ -8246,7 +8274,7 @@ msgstr "" msgid "Individuals in this release v4.0.0 (in alphabetical order)" msgstr "" -msgid "Regina Obe, Saloni kumari, Vicky Vergara" +msgid "Fan Wu Regina Obe, Saloni kumari, Vicky Vergara" msgstr "" msgid "" @@ -8295,11 +8323,11 @@ msgid "" "Takubo, Andrea Nardelli, Anthony Tasca, Anton Patrushev, Aryan Gupta, " "Ashraf Hossain, Ashish Kumar, Aurélie Bousquet, Cayetano Benavent, " "Christian Gonzalez, Daniel Kastl, Dapeng Wang, Dave Potts, David Techer, " -"Denis Rykov, Ema Miyawaki, Esteban Zimanyi, Florian Thurkow, Frederic " -"Junod, Gerald Fenoy, Gudesa Venkata Sai Akhil, Hang Wu, Himanshu Raj, " -"Imre Samu, Jay Mahadeokar, Jinfu Leng, Kai Behncke, Kishore Kumar, Ko " -"Nagase, Mahmoud Sakr, Manikata Kondeti, Mario Basa, Martin Wiesenhaan, " -"Maxim Dubinin, Maoguang Wang, Mohamed Bakli, Mohamed Zia, Mukul Priya, " +"Denis Rykov, Ema Miyawaki, Esteban Zimanyi, Fan Wu, Florian Thurkow, " +"Frederic Junod, Gerald Fenoy, Gudesa Venkata Sai Akhil, Hang Wu, Himanshu" +" Raj, Imre Samu, Jay Mahadeokar, Jinfu Leng, Kai Behncke, Kishore Kumar, " +"Ko Nagase, Mahmoud Sakr, Manikata Kondeti, Mario Basa, Martin Wiesenhaan," +" Maxim Dubinin, Maoguang Wang, Mohamed Bakli, Mohamed Zia, Mukul Priya, " "Nitish Chauhan, Rajat Shinde, Razequl Islam, Regina Obe, Rohith Reddy, " "Saloni Kumari, Sarthak Agarwal, Shobhit Chaurasia, Sourabh Garg, Stephen " "Woodbridge, Swapnil Joshi, Sylvain Housseman, Sylvain Pasche, Veenit " @@ -8801,9 +8829,6 @@ msgid "" "`__" msgstr "" -msgid "Version 3.0.0" -msgstr "" - msgid "Name change from pgr_eucledianTSP" msgstr "" @@ -8905,9 +8930,6 @@ msgstr "" msgid "pgr_aStar(Many to One) added ``start_vid`` column." msgstr "" -msgid "Version 3.2.0" -msgstr "" - msgid "New proposed signature:" msgstr "" @@ -9447,9 +9469,6 @@ msgstr "" msgid "``pgr_bellmanFord`` — Shortest path using Bellman-Ford algorithm." msgstr "" -msgid "New experimental signature:" -msgstr "" - msgid "pgr_bellmanFord(Combinations)" msgstr "" @@ -12553,9 +12572,6 @@ msgid "" "algorithm." msgstr "" -msgid "pgr_edwardMoore(Combinations)" -msgstr "" - msgid "" "Edward Moore’s Algorithm is an improvement of the Bellman-Ford Algorithm." " It can compute the shortest paths from a single source vertex to all " @@ -13279,6 +13295,52 @@ msgid "" "`_" msgstr "" +msgid "``pgr_kingOrdering`` - Experimental" +msgstr "" + +msgid "``pgr_kingOrdering`` — Returns the King ordering of an undirected graphs" +msgstr "" + +msgid "" +"In numerical linear algebra and graph theory, the King ordering algorithm" +" is a heuristic designed to reorder the vertices of a graph so as to " +"reduce its bandwidth." +msgstr "" + +msgid "" +"The method follows a breadth-first search (BFS) traversal,but with a " +"refinement: at each step, the unvisited neighbors of the current vertex " +"are inserted into the queue in ascending order of their pseudo-degree, " +"where the pseudo-degree of a vertex is the number of edges connecting it " +"to yet-unvisited vertices. This prioritization often yields a smaller " +"bandwidth compared to simpler BFS orderings." +msgstr "" + +msgid "The implementation targets undirected graphs." +msgstr "" + +msgid "" +"Bandwidth minimization is an NP-complete problem; King ordering provides " +"a practical local minimization approach." +msgstr "" + +msgid "The time complexity is: :math:`O(m^2 \\log(m)|E|)`" +msgstr "" + +msgid "where :math:`|E|` is the number of edges," +msgstr "" + +msgid ":math:`m` is the maximum degree among all vertices." +msgstr "" + +msgid "pgr_kingOrdering(`Edges SQL`_)" +msgstr "" + +msgid "" +"`Boost: King Ordering " +"`__" +msgstr "" + msgid "``pgr_kruskal``" msgstr "" @@ -16663,9 +16725,6 @@ msgstr "" msgid "pgr_findCloseEdges(Many points)" msgstr "" -msgid "Ordering" -msgstr "" - msgid "pgr_cuthillMckeeOrdering" msgstr "" diff --git a/locale/pot/pgrouting_doc_strings.pot b/locale/pot/pgrouting_doc_strings.pot index ab530b56299..ef8c31932d7 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 v4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-08-20 17:25+0000\n" +"POT-Creation-Date: 2025-08-23 02:38+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3076,6 +3076,9 @@ msgstr "" msgid ":doc:`pgr_topologicalSort` - Linear ordering of the vertices for directed acyclic graph." msgstr "" +msgid ":doc:`pgr_kingOrdering` - Returns the King ordering of an undirected graphs acyclic graph." +msgstr "" + msgid ":doc:`metrics-family`" msgstr "" @@ -3676,6 +3679,21 @@ msgstr "" msgid "pgr_edwardMoore" msgstr "" +msgid "Version 3.2.0" +msgstr "" + +msgid "New experimental signature:" +msgstr "" + +msgid "pgr_edwardMoore(Combinations)" +msgstr "" + +msgid "Version 3.0.0" +msgstr "" + +msgid "pgr_kingOrdering" +msgstr "" + msgid "pgr_KSP" msgstr "" @@ -3913,6 +3931,12 @@ msgstr "" msgid "`#2951 `__: pgr_bandwidth" msgstr "" +msgid "Ordering" +msgstr "" + +msgid "`#2954 `__: pgr_kingOrdering" +msgstr "" + msgid "SQL signatures and output standardization" msgstr "" @@ -7054,7 +7078,7 @@ msgstr "" msgid "Individuals in this release v4.0.0 (in alphabetical order)" msgstr "" -msgid "Regina Obe, Saloni kumari, Vicky Vergara" +msgid "Fan Wu Regina Obe, Saloni kumari, Vicky Vergara" msgstr "" msgid "And all the people that give us a little of their time making comments, finding issues, making pull requests etc. in any of our products: osm2pgrouting, pgRouting, pgRoutingLayer, workshop." @@ -7093,7 +7117,7 @@ msgstr "" msgid "Individuals (in alphabetical order)" msgstr "" -msgid "Aasheesh Tiwari, Abhinav Jain, Aditya Pratap Singh, Adrien Berchet, Akio Takubo, Andrea Nardelli, Anthony Tasca, Anton Patrushev, Aryan Gupta, Ashraf Hossain, Ashish Kumar, Aurélie Bousquet, Cayetano Benavent, Christian Gonzalez, Daniel Kastl, Dapeng Wang, Dave Potts, David Techer, Denis Rykov, Ema Miyawaki, Esteban Zimanyi, Florian Thurkow, Frederic Junod, Gerald Fenoy, Gudesa Venkata Sai Akhil, Hang Wu, Himanshu Raj, Imre Samu, Jay Mahadeokar, Jinfu Leng, Kai Behncke, Kishore Kumar, Ko Nagase, Mahmoud Sakr, Manikata Kondeti, Mario Basa, Martin Wiesenhaan, Maxim Dubinin, Maoguang Wang, Mohamed Bakli, Mohamed Zia, Mukul Priya, Nitish Chauhan, Rajat Shinde, Razequl Islam, Regina Obe, Rohith Reddy, Saloni Kumari, Sarthak Agarwal, Shobhit Chaurasia, Sourabh Garg, Stephen Woodbridge, Swapnil Joshi, Sylvain Housseman, Sylvain Pasche, Veenit Kumar, Vidhan Jain, Virginia Vergara, Yige Huang" +msgid "Aasheesh Tiwari, Abhinav Jain, Aditya Pratap Singh, Adrien Berchet, Akio Takubo, Andrea Nardelli, Anthony Tasca, Anton Patrushev, Aryan Gupta, Ashraf Hossain, Ashish Kumar, Aurélie Bousquet, Cayetano Benavent, Christian Gonzalez, Daniel Kastl, Dapeng Wang, Dave Potts, David Techer, Denis Rykov, Ema Miyawaki, Esteban Zimanyi, Fan Wu, Florian Thurkow, Frederic Junod, Gerald Fenoy, Gudesa Venkata Sai Akhil, Hang Wu, Himanshu Raj, Imre Samu, Jay Mahadeokar, Jinfu Leng, Kai Behncke, Kishore Kumar, Ko Nagase, Mahmoud Sakr, Manikata Kondeti, Mario Basa, Martin Wiesenhaan, Maxim Dubinin, Maoguang Wang, Mohamed Bakli, Mohamed Zia, Mukul Priya, Nitish Chauhan, Rajat Shinde, Razequl Islam, Regina Obe, Rohith Reddy, Saloni Kumari, Sarthak Agarwal, Shobhit Chaurasia, Sourabh Garg, Stephen Woodbridge, Swapnil Joshi, Sylvain Housseman, Sylvain Pasche, Veenit Kumar, Vidhan Jain, Virginia Vergara, Yige Huang" msgstr "" msgid "Corporate Sponsors (in alphabetical order)" @@ -7519,9 +7543,6 @@ msgstr "" msgid "Using `Boost: metric TSP approx `__" msgstr "" -msgid "Version 3.0.0" -msgstr "" - msgid "Name change from pgr_eucledianTSP" msgstr "" @@ -7609,9 +7630,6 @@ msgstr "" msgid "pgr_aStar(Many to One) added ``start_vid`` column." msgstr "" -msgid "Version 3.2.0" -msgstr "" - msgid "New proposed signature:" msgstr "" @@ -8071,9 +8089,6 @@ msgstr "" msgid "``pgr_bellmanFord`` — Shortest path using Bellman-Ford algorithm." msgstr "" -msgid "New experimental signature:" -msgstr "" - msgid "pgr_bellmanFord(Combinations)" msgstr "" @@ -10576,9 +10591,6 @@ msgstr "" msgid "``pgr_edwardMoore`` — Returns the shortest path using Edward-Moore algorithm." msgstr "" -msgid "pgr_edwardMoore(Combinations)" -msgstr "" - msgid "Edward Moore’s Algorithm is an improvement of the Bellman-Ford Algorithm. It can compute the shortest paths from a single source vertex to all other vertices in a weighted directed graph. The main difference between Edward Moore's Algorithm and Bellman Ford's Algorithm lies in the run time." msgstr "" @@ -11188,6 +11200,39 @@ msgstr "" msgid "Boost `Johnson `_" msgstr "" +msgid "``pgr_kingOrdering`` - Experimental" +msgstr "" + +msgid "``pgr_kingOrdering`` — Returns the King ordering of an undirected graphs" +msgstr "" + +msgid "In numerical linear algebra and graph theory, the King ordering algorithm is a heuristic designed to reorder the vertices of a graph so as to reduce its bandwidth." +msgstr "" + +msgid "The method follows a breadth-first search (BFS) traversal,but with a refinement: at each step, the unvisited neighbors of the current vertex are inserted into the queue in ascending order of their pseudo-degree, where the pseudo-degree of a vertex is the number of edges connecting it to yet-unvisited vertices. This prioritization often yields a smaller bandwidth compared to simpler BFS orderings." +msgstr "" + +msgid "The implementation targets undirected graphs." +msgstr "" + +msgid "Bandwidth minimization is an NP-complete problem; King ordering provides a practical local minimization approach." +msgstr "" + +msgid "The time complexity is: :math:`O(m^2 \\log(m)|E|)`" +msgstr "" + +msgid "where :math:`|E|` is the number of edges," +msgstr "" + +msgid ":math:`m` is the maximum degree among all vertices." +msgstr "" + +msgid "pgr_kingOrdering(`Edges SQL`_)" +msgstr "" + +msgid "`Boost: King Ordering `__" +msgstr "" + msgid "``pgr_kruskal``" msgstr "" @@ -13840,9 +13885,6 @@ msgstr "" msgid "pgr_findCloseEdges(Many points)" msgstr "" -msgid "Ordering" -msgstr "" - msgid "pgr_cuthillMckeeOrdering" msgstr "" diff --git a/pgtap/ordering/kingOrdering/edge_cases.pg b/pgtap/ordering/kingOrdering/edge_cases.pg new file mode 100644 index 00000000000..de0689ee553 --- /dev/null +++ b/pgtap/ordering/kingOrdering/edge_cases.pg @@ -0,0 +1,153 @@ + +/*PGR-GNU***************************************************************** + +Copyright (c) 2018 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*/ +BEGIN; + +UPDATE edges SET cost = sign(cost), reverse_cost = sign(reverse_cost); +SELECT CASE WHEN NOT min_version('4.0.0') THEN plan(1) ELSE plan(7) END; + + +CREATE OR REPLACE FUNCTION edge_cases() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN + +IF NOT min_version('4.0.0') THEN + RETURN QUERY + SELECT skip(1, 'Function is new on 4.0.0'); + RETURN; +END IF; + +-- 0 edge, 0 vertex test + +PREPARE q1 AS +SELECT * FROM pgr_kingOrdering( +'SELECT id, source, target, cost, reverse_cost FROM edges WHERE id > 18' +); + +RETURN QUERY +SELECT is_empty('q1', 'Graph with 0 edge and 0 vertex -> Empty row is returned'); + +-- 1 vertex test: 6 -- 6 + +PREPARE q2 AS +SELECT * +FROM pgr_kingOrdering('SELECT id, source, source AS target, cost, reverse_cost FROM edges WHERE id = 2'); + +RETURN QUERY +SELECT set_eq('q2', $$VALUES (1, 6)$$, '6 -- 6: Same node returned'); + +-- 2 vertices test (connected): 3 -- 7; 7 -- 3 + +PREPARE q3 AS +SELECT * +FROM pgr_kingOrdering('SELECT id, source, target, cost, reverse_cost FROM edges WHERE id = 7' +); + +RETURN QUERY +SELECT set_eq('q3', $$VALUES (1,3), (2,7)$$, '3 --7; 7 -- 3: Natural order of edges'); + +-- 2 vertices test (connected): 7 -- 3; 3 -- 7 + +PREPARE q4 AS +SELECT * +FROM pgr_kingOrdering('SELECT id, target AS source, source AS target, cost, reverse_cost FROM edges WHERE id = 7' +); + +RETURN QUERY +SELECT set_eq('q4', $$VALUES (1,3), (2,7)$$, '7 --3; 3 -- 7: Does not matter if 3 comes first or second'); + +-- 2 vertices test (isolated) + +CREATE TABLE isolated_vertices_table ( + id BIGSERIAL, + source BIGINT, + target BIGINT, + cost FLOAT, + reverse_cost FLOAT +); + +INSERT INTO isolated_vertices_table +(source, target, cost, reverse_cost) VALUES +(2, 2, -1, 1), +(1, 1, 1, -1); + +PREPARE q5 AS +SELECT node +FROM pgr_kingOrdering('SELECT id, source, target, cost, reverse_cost FROM isolated_vertices_table' +); + +RETURN QUERY +SELECT set_eq('q5', $$VALUES (1), (2)$$, 'Both isolated vertices are returned for a disconnected graph'); + +DROP TABLE IF EXISTS isolated_vertices_table; + +-- 3 vertices test + +PREPARE q6 AS +SELECT * +FROM pgr_kingOrdering('SELECT id, source, target, cost, reverse_cost FROM edges WHERE id <= 2' +); + +RETURN QUERY +SELECT set_eq('q6', $$VALUES (1, 5), (2, 6), (3, 10)$$, 'Three connected vertices are ordered as expected'); + +-- pgRouting sample data + +CREATE TABLE expected_result ( +seq BIGINT, +node BIGINT); + +INSERT INTO expected_result (seq, node) VALUES +(1, 13), +(2, 14), +(3, 2), +(4, 4), +(5, 1), +(6, 9), +(7, 3), +(8, 8), +(9, 5), +(10, 7), +(11, 12), +(12, 6), +(13, 11), +(14, 17), +(15, 10), +(16, 16), +(17, 15); + +PREPARE q7 AS +SELECT * FROM pgr_kingOrdering('SELECT id, source, target, cost, reverse_cost FROM edges' +); + +PREPARE r7 AS +SELECT * FROM expected_result; + +RETURN QUERY SELECT set_eq('q7','r7','King ordering result matches expected sequence for pgRouting sample data'); + +END; +$BODY$ +LANGUAGE plpgsql; + +SELECT edge_cases(); + + +SELECT * FROM finish(); +ROLLBACK; diff --git a/pgtap/ordering/kingOrdering/inner_query.pg b/pgtap/ordering/kingOrdering/inner_query.pg new file mode 100644 index 00000000000..6ecbddde3ea --- /dev/null +++ b/pgtap/ordering/kingOrdering/inner_query.pg @@ -0,0 +1,46 @@ + +/*PGR-GNU***************************************************************** + +Copyright (c) 2018 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*/ +BEGIN; + +UPDATE edges SET cost = sign(cost), reverse_cost = sign(reverse_cost); +SELECT CASE WHEN NOT min_version('4.0.0') THEN plan(1) ELSE plan(54) END; + +CREATE OR REPLACE FUNCTION inner_query() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN + +IF NOT min_version('4.0.0') THEN + RETURN QUERY + SELECT skip(1, 'pgr_kingOrdering is new on 4.0.0'); + RETURN; +END IF; + +RETURN QUERY +SELECT style_dijkstra('pgr_kingOrdering(', ')'); + +END; +$BODY$ +LANGUAGE plpgsql; + +SELECT inner_query(); + +SELECT finish(); +ROLLBACK; diff --git a/pgtap/ordering/kingOrdering/no_crash_test.pg b/pgtap/ordering/kingOrdering/no_crash_test.pg new file mode 100644 index 00000000000..a2121c829df --- /dev/null +++ b/pgtap/ordering/kingOrdering/no_crash_test.pg @@ -0,0 +1,67 @@ + +/*PGR-GNU***************************************************************** + +Copyright (c) 2018 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*/ +BEGIN; + +UPDATE edges SET cost = sign(cost), reverse_cost = sign(reverse_cost); +SELECT CASE WHEN NOT min_version('4.0.0') THEN plan(1) ELSE plan(4) END; + +PREPARE edges AS +SELECT id, source, target, cost, reverse_cost FROM edges; + +PREPARE null_ret AS +SELECT id FROM vertices WHERE id IN (-1); + +PREPARE null_ret_arr AS +SELECT array_agg(id) FROM vertices WHERE id IN (-1); + + + +CREATE OR REPLACE FUNCTION no_crash() +RETURNS SETOF TEXT AS +$BODY$ +DECLARE +params TEXT[]; +subs TEXT[]; +BEGIN + IF NOT min_version('4.0.0') THEN + RETURN QUERY + SELECT skip(1, 'Function is new on 4.0.0'); + RETURN; + END IF; + + -- pgr_kingOrdering + params = ARRAY[ + '$$SELECT id, source, target, cost, reverse_cost FROM edges$$' + ]::TEXT[]; + subs = ARRAY[ + 'NULL' + ]::TEXT[]; + + RETURN query SELECT * FROM no_crash_test('pgr_kingOrdering', params, subs); + +END +$BODY$ +LANGUAGE plpgsql VOLATILE; + + +SELECT * FROM no_crash(); + +SELECT finish(); +ROLLBACK; diff --git a/pgtap/ordering/kingOrdering/types_check.pg b/pgtap/ordering/kingOrdering/types_check.pg new file mode 100644 index 00000000000..76b77adbf01 --- /dev/null +++ b/pgtap/ordering/kingOrdering/types_check.pg @@ -0,0 +1,56 @@ + +/*PGR-GNU***************************************************************** + +Copyright (c) 2018 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*/ +BEGIN; + +SELECT CASE WHEN min_version('4.0.0') THEN plan(5) ELSE plan(1) END; + +CREATE OR REPLACE FUNCTION types_check() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN + + IF NOT min_version('4.0.0') THEN + RETURN QUERY SELECT skip(1, 'pgr_kingOrdering: Function is new on 4.0.0'); + RETURN; + END IF; + + RETURN QUERY SELECT has_function('pgr_kingordering'); + RETURN QUERY SELECT has_function('pgr_kingordering', ARRAY['text']); + RETURN QUERY SELECT function_returns('pgr_kingordering', ARRAY['text'], 'setof record'); + + RETURN QUERY + SELECT function_args_eq('pgr_kingordering', + $$SELECT '{"", seq, node}'::TEXT[] $$ + ); + + RETURN QUERY + SELECT function_types_eq('pgr_kingordering', + $$VALUES + ('{text,int8,int8}'::TEXT[]) + $$ + ); +END; +$BODY$ +LANGUAGE plpgsql; + +SELECT types_check(); + +SELECT * FROM finish(); +ROLLBACK; diff --git a/sql/ordering/CMakeLists.txt b/sql/ordering/CMakeLists.txt index 9bb6ede9dd2..7886a6dfc3d 100644 --- a/sql/ordering/CMakeLists.txt +++ b/sql/ordering/CMakeLists.txt @@ -1,6 +1,8 @@ SET(LOCAL_FILES _cuthillMckeeOrdering.sql cuthillMckeeOrdering.sql + _kingOrdering.sql + kingOrdering.sql ) # Do not modify below this line @@ -12,4 +14,4 @@ foreach (f ${LOCAL_FILES}) list(APPEND PACKAGE_SQL_FILES ${CMAKE_CURRENT_BINARY_DIR}/${f}) endforeach() -set(PROJECT_SQL_FILES ${PROJECT_SQL_FILES} ${PACKAGE_SQL_FILES} PARENT_SCOPE) \ No newline at end of file +set(PROJECT_SQL_FILES ${PROJECT_SQL_FILES} ${PACKAGE_SQL_FILES} PARENT_SCOPE) diff --git a/sql/ordering/_kingOrdering.sql b/sql/ordering/_kingOrdering.sql new file mode 100644 index 00000000000..031d6fb794b --- /dev/null +++ b/sql/ordering/_kingOrdering.sql @@ -0,0 +1,44 @@ +/*PGR-GNU***************************************************************** +File: _kingOrdering.sql + +Generated with Template by: +Copyright (c) 2025 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at gmail.com + +------ + +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*/ + +--v4.0 +CREATE FUNCTION _pgr_kingOrdering( + TEXT, + OUT seq BIGINT, + OUT node BIGINT + ) + +RETURNS SETOF RECORD AS +'MODULE_PATHNAME' +LANGUAGE C VOLATILE STRICT +COST ${COST_HIGH} ROWS ${ROWS_HIGH}; + + +COMMENT ON FUNCTION _pgr_kingOrdering(TEXT) +IS 'pgRouting internal function'; diff --git a/sql/ordering/kingOrdering.sql b/sql/ordering/kingOrdering.sql new file mode 100644 index 00000000000..93478be11b6 --- /dev/null +++ b/sql/ordering/kingOrdering.sql @@ -0,0 +1,50 @@ +/*PGR-GNU***************************************************************** +File: kingOrdering.sql + +Generated with Template by: +Copyright (c) 2025 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at gmail.com + +------ + +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*/ + +--v4.0 +CREATE FUNCTION pgr_kingOrdering( + TEXT, -- edges_sql (required) + OUT seq BIGINT, + OUT node BIGINT) +RETURNS SETOF RECORD AS +$BODY$ + SELECT seq, node + FROM _pgr_kingOrdering(_pgr_get_statement($1)); +$BODY$ +LANGUAGE SQL VOLATILE STRICT +COST ${COST_HIGH} ROWS ${ROWS_HIGH}; + +COMMENT ON FUNCTION pgr_kingOrdering(TEXT) +IS 'pgr_kingOrdering +- EXPERIMENTAL +- Parameters: + - Edges SQL with columns: id, source, target, cost [,reverse_cost] +- Documentation: + - ${PROJECT_DOC_LINK}/pgr_kingOrdering.html +'; diff --git a/sql/sigs/pgrouting--4.0.sig b/sql/sigs/pgrouting--4.0.sig index b3cc81bfa55..0f0ef7acfc4 100644 --- a/sql/sigs/pgrouting--4.0.sig +++ b/sql/sigs/pgrouting--4.0.sig @@ -164,6 +164,8 @@ _pgr_isplanar(text) pgr_isplanar(text) _pgr_johnson(text,boolean) pgr_johnson(text,boolean) +_pgr_kingordering(text) +pgr_kingordering(text) pgr_kruskalbfs(text,anyarray,bigint) pgr_kruskalbfs(text,bigint,bigint) pgr_kruskaldd(text,anyarray,double precision) diff --git a/src/ordering/CMakeLists.txt b/src/ordering/CMakeLists.txt index f4921ab138d..0eaa075a9ab 100644 --- a/src/ordering/CMakeLists.txt +++ b/src/ordering/CMakeLists.txt @@ -1,4 +1,7 @@ ADD_LIBRARY(ordering OBJECT + kingOrdering.c cuthillMckeeOrdering.c cuthillMckeeOrdering_driver.cpp - ) \ No newline at end of file + ordering_driver.cpp + ordering_process.cpp + ) diff --git a/src/ordering/kingOrdering.c b/src/ordering/kingOrdering.c new file mode 100644 index 00000000000..e44aebf80a3 --- /dev/null +++ b/src/ordering/kingOrdering.c @@ -0,0 +1,104 @@ +/*PGR-GNU***************************************************************** +File: kingOrdering.c + +Generated with Template by: +Copyright (c) 2025 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at gmail.com +------ +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*/ + +#include +#include "c_common/postgres_connection.h" + +#include "c_common/debug_macro.h" +#include "c_common/e_report.h" +#include "c_common/time_msg.h" + +#include "process/ordering_process.h" + +PGDLLEXPORT Datum _pgr_kingordering(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(_pgr_kingordering); + + +PGDLLEXPORT Datum +_pgr_kingordering(PG_FUNCTION_ARGS) { + FuncCallContext *funcctx; + TupleDesc tuple_desc; + + int64_t *result_tuples = NULL; + size_t result_count = 0; + + if (SRF_IS_FIRSTCALL()) { + MemoryContext oldcontext; + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + + pgr_process_ordering( + text_to_cstring(PG_GETARG_TEXT_P(0)), + 2, /*King Ordering*/ + &result_tuples, + &result_count); + + funcctx->max_calls = result_count; + funcctx->user_fctx = result_tuples; + if (get_call_result_type(fcinfo, NULL, &tuple_desc) + != TYPEFUNC_COMPOSITE) { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + } + + funcctx->tuple_desc = tuple_desc; + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + tuple_desc = funcctx->tuple_desc; + result_tuples = (int64_t*) funcctx->user_fctx; + + if (funcctx->call_cntr < funcctx->max_calls) { + HeapTuple tuple; + Datum result; + Datum *values; + bool* nulls; + + size_t num = 2; + values = palloc(num * sizeof(Datum)); + nulls = palloc(num * sizeof(bool)); + + + size_t i; + for (i = 0; i < num; ++i) { + nulls[i] = false; + } + + values[0] = Int64GetDatum((int64_t)funcctx->call_cntr + 1); + values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr]); + + tuple = heap_form_tuple(tuple_desc, values, nulls); + result = HeapTupleGetDatum(tuple); + SRF_RETURN_NEXT(funcctx, result); + } else { + SRF_RETURN_DONE(funcctx); + } +} diff --git a/src/ordering/ordering_driver.cpp b/src/ordering/ordering_driver.cpp new file mode 100644 index 00000000000..ae7691ef59c --- /dev/null +++ b/src/ordering/ordering_driver.cpp @@ -0,0 +1,134 @@ +/*PGR-GNU***************************************************************** +File: ordering_driver.cpp +Generated with Template by: +Copyright (c) 2025 pgRouting developers +Mail: project@pgrouting.org + +Developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at gmail.com +------ + +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*/ + +#include "drivers/ordering_driver.hpp" + +#include +#include +#include +#include +#include + + +#include "cpp_common/pgdata_getters.hpp" +#include "cpp_common/alloc.hpp" +#include "cpp_common/assert.hpp" + +#include "ordering/kingOrdering.hpp" + + + +void +do_ordering( + std::string edges_sql, + int which, + + int64_t **return_tuples, + size_t *return_count, + + char **log_msg, + char **notice_msg, + char **err_msg) { + + using pgrouting::pgr_alloc; + using pgrouting::to_pg_msg; + using pgrouting::pgr_free; + using pgrouting::kingOrdering; + using pgrouting::pgget::get_edges; + using pgrouting::UndirectedGraph; + + std::ostringstream log; + std::ostringstream err; + std::ostringstream notice; + std::string hint = ""; + + try { + pgassert(!(*log_msg)); + pgassert(!(*notice_msg)); + pgassert(!(*err_msg)); + pgassert(!(*return_tuples)); + pgassert(*return_count == 0); + + hint = edges_sql; + auto edges = get_edges(std::string(edges_sql), true, false); + if (edges.empty()) { + *notice_msg = to_pg_msg("No edges found"); + *return_tuples = NULL; + *return_count = 0; + return; + } + hint = ""; + + std::vector results; + auto vertices(pgrouting::extract_vertices(edges)); + UndirectedGraph undigraph(vertices); + undigraph.insert_edges(edges); + + if (which == 2) { + results = kingOrdering(undigraph); + } + auto count = results.size(); + + if (count == 0) { + *notice_msg = to_pg_msg("No results found \n"); + *return_tuples = NULL; + *return_count = 0; + return; + } + + (*return_tuples) = pgr_alloc(count, (*return_tuples)); + for (size_t i = 0; i < count; i++) { + *((*return_tuples) + i) = results[i]; + } + + (*return_count) = count; + + pgassert(*err_msg == NULL); + *log_msg = to_pg_msg(log); + *notice_msg = to_pg_msg(notice); + } catch (AssertFailedException &except) { + (*return_tuples) = pgr_free(*return_tuples); + (*return_count) = 0; + err << except.what(); + *err_msg = to_pg_msg(err); + *log_msg = to_pg_msg(log); + } catch (const std::string &ex) { + *err_msg = to_pg_msg(ex); + *log_msg = hint.empty()? to_pg_msg(hint) : to_pg_msg(log); + } catch (std::exception &except) { + (*return_tuples) = pgr_free(*return_tuples); + (*return_count) = 0; + err << except.what(); + *err_msg = to_pg_msg(err); + *log_msg = to_pg_msg(log); + } catch (...) { + (*return_tuples) = pgr_free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg("Caught unknown exception"); + *log_msg = to_pg_msg(log); + } +} diff --git a/src/ordering/ordering_process.cpp b/src/ordering/ordering_process.cpp new file mode 100644 index 00000000000..37b7d20d5b1 --- /dev/null +++ b/src/ordering/ordering_process.cpp @@ -0,0 +1,86 @@ +/*PGR-GNU***************************************************************** +File: ordering_process.cpp + +Copyright (c) 2025 pgRouting developers +Mail: project@pgrouting.org + +Developer: +Copyright (c) 2025 pgRouting developers +Mail: wifiblack0131 at gmail.com + +------ + +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*/ + +#include "process/ordering_process.h" + +#include + +extern "C" { +#include "c_common/postgres_connection.h" +#include "c_common/e_report.h" +#include "c_common/time_msg.h" +} + +#include "cpp_common/assert.hpp" +#include "drivers/ordering_driver.hpp" + +/** + which = 0 -> sloan + which = 1 -> cuthillmckee + which = 2 -> king + + + This is c++ code, linked as C code, because pgr_process_foo is called from C code + */ +void pgr_process_ordering( + const char* edges_sql, + int which, + int64_t **result_tuples, + size_t *result_count) { + pgassert(edges_sql); + pgassert(!(*result_tuples)); + pgassert(*result_count == 0); + pgr_SPI_connect(); + char* log_msg = NULL; + char* notice_msg = NULL; + char* err_msg = NULL; + + clock_t start_t = clock(); + do_ordering( + std::string(edges_sql), + which, + result_tuples, result_count, + &log_msg, ¬ice_msg, &err_msg); + if (which == 0) { + time_msg(std::string(" processing pgr_sloanOrdering").c_str(), start_t, clock()); + } else if (which == 1) { + time_msg(std::string("processing pgr_cuthillMckeeOrdering").c_str(), start_t, clock()); + } else if (which == 2) { + time_msg(std::string("processing pgr_kingOrdering").c_str(), start_t, clock()); + } + + if (err_msg && (*result_tuples)) { + pfree(*result_tuples); + (*result_tuples) = NULL; + (*result_count) = 0; + } + + pgr_global_report(&log_msg, ¬ice_msg, &err_msg); + + pgr_SPI_finish(); +}