diff --git a/configuration.conf b/configuration.conf index ee08222bca..3233fefbad 100644 --- a/configuration.conf +++ b/configuration.conf @@ -36,8 +36,10 @@ cpp_common | Y | N | N dagShortestPath | Y | Y | Y costFlow | Y | Y | Y ChPP | Y | Y | Y -spanningTree | Y | Y | Y +spanningTree | Y | Y | Y mincut | Y | Y | Y +topological_sort | Y | Y | N + #---------------------- # SQL only directories #---------------------- diff --git a/doc/components/components-family.rst b/doc/components/components-family.rst index cb7e3fe0df..a41aab62b5 100644 --- a/doc/components/components-family.rst +++ b/doc/components/components-family.rst @@ -7,21 +7,21 @@ Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/ **************************************************************************** -Components - Family of functions (Experimental) +Components - Family of functions (Proposed) =============================================================================== .. include:: proposed.rst - :start-after: begin-warn-expr - :end-before: end-warn-expr + :start-after: stable-begin-warning + :end-before: stable-end-warning .. index from here -* :doc:`pgr_connectedComponents` - Return the connected components of an undirected graph. -* :doc:`pgr_strongComponents` - Return the strongly connected components of a directed graph. -* :doc:`pgr_biconnectedComponents` - Return the biconnected components of an undirected graph. -* :doc:`pgr_articulationPoints` - Return the articulation points of an undirected graph. -* :doc:`pgr_bridges` - Return the bridges of an undirected graph. +* :doc:`pgr_connectedComponents` - Connected components of an undirected graph. +* :doc:`pgr_strongComponents` - Strongly connected components of a directed graph. +* :doc:`pgr_biconnectedComponents` - Biconnected components of an undirected graph. +* :doc:`pgr_articulationPoints` - Articulation points of an undirected graph. +* :doc:`pgr_bridges` - Bridges of an undirected graph. .. index to here @@ -36,480 +36,60 @@ Components - Family of functions (Experimental) pgr_bridges -The problem definition ------------------------------------------------ - -.. rubric:: Connected components - -A connected component of an undirected graph is a set of vertices that are all reachable -from each other. - -**Notice**: This problem defines on an undirected graph. - -Given the following query: - - -pgr_connectedComponentsV(:math:`sql`) - -where :math:`sql = \{(id_i, source_i, target_i, cost_i, reverse\_cost_i)\}` - -and - -- :math:`source = \bigcup source_i`, -- :math:`target = \bigcup target_i`, - -The graphs are defined as follows: - -The weighted undirected graph, :math:`G(V,E)`, is definied by: - -* the set of vertices :math:`V` - - - :math:`V = source \cup target` - - -* the set of edges :math:`E` - - - :math:`E = \begin{cases} - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ if } reverse\_cost = \varnothing \\ - \text{ } \text{ } & \text{ } \\ - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \text{ } \\ - \cup \{(source_i, target_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \quad \text{ if } reverse\_cost \neq \varnothing \\ - \end{cases}` - - -Given: - -- :math:`G(V,E)` - -Then: - -.. math::`pgr_connectedComponentsV(sql) = - \begin{cases} - \text{all connected components } \boldsymbol{\pi} \text{ in } G(V,E) &\quad \text{if } \exists \boldsymbol{\pi} \\ - \varnothing &\quad \text{otherwise} \\ - \end{cases}` - -:math:`\boldsymbol{\pi} = \{(component_i, n\_seq_i, node_i)\}` - -where: - - :math:`component_i = \min \{node_j | node_j \in component_i\}` - - :math:`n\_seq_i` is a sequential value starting from **1** in a component. - - :math:`node_i \in component_i` - - The returned values are ordered: - - - `component` ascending - - `node` ascending - -Example: - - The first component is composed of nodes ``0``, ``1`` and ``4``. - - The second component is composed of node ``3``. - - The third component is composed of nodes ``2`` and ``5``. - -.. image:: images/connected_components.jpeg - :width: 280px - :height: 323px - - -.. rubric:: Strongly connected components - -A strongly connected component of a directed graph is a set of vertices that are all reachable -from each other. - -**Notice**: This problem defines on a directed graph. - -Given the following query: - - -pgr_strongComponentsV(:math:`sql`) - -where :math:`sql = \{(id_i, source_i, target_i, cost_i, reverse\_cost_i)\}` - -and - -- :math:`source = \bigcup source_i`, -- :math:`target = \bigcup target_i`, - -The graphs are defined as follows: - -The weighted directed graph, :math:`G_d(V,E)`, is definied by: - -* the set of vertices :math:`V` - - - :math:`V = source \cup target \cup {start_{vid}} \cup {end_{vid}}` - -* the set of edges :math:`E` - - - :math:`E = \begin{cases} - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ if } reverse\_cost = \varnothing \\ - \text{ } \text{ } & \text{ } \\ - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \quad \text{ if } reverse\_cost \neq \varnothing \\ - \end{cases}` - - -Given: - -- :math:`G(V,E)` - -Then: - -.. math::`\text{pgr_strongComponentsV}(sql) = - \begin{cases} - \text{all strongly connected components } \boldsymbol{\pi} \text{ in } G(V,E) &\quad \text{if } \exists \boldsymbol{\pi} \\ - \varnothing &\quad \text{otherwise} \\ - \end{cases}` - -:math:`\boldsymbol{\pi} = \{(component_i, n\_seq_i, node_i)\}` - -where: - - :math:`component_i = \min {node_j | node_j \in component_i}` - - :math:`n\_seq_i` is a sequential value starting from **1** in a component. - - :math:`node_i \in component_i` - - The returned values are ordered: - - - `component` ascending - - `node` ascending - -Example: - - The first component is composed of nodes ``1``, ``2`` and ``4``. - - The second component is composed of node ``0``. - - The third component is composed of node ``3``. - - The fourth component is composed of node ``5``. - - The fifth component is composed of node ``6``. - -.. image:: images/strong_components.jpeg - :width: 270px - :height: 323px - -.. rubric:: Biconnected components - -The biconnected components of an undirected graph are the maximal subsets of vertices such that the removal of a vertex from -particular component will not disconnect the component. Unlike connected components, vertices may belong to multiple biconnected -components. Vertices can be present in multiple biconnected components, but each edge can only be contained in a single biconnected -component. So, the output only has edge version. - -**Notice**: This problem defines on an undirected graph. - -Given the following query: - - -pgr_biconnectedComponents(:math:`sql`) - -where :math:`sql = \{(id_i, source_i, target_i, cost_i, reverse\_cost_i)\}` - -and - -- :math:`source = \bigcup source_i`, -- :math:`target = \bigcup target_i`, - -The graphs are defined as follows: - -The weighted undirected graph, :math:`G(V,E)`, is definied by: - -* the set of vertices :math:`V` - - - :math:`V = source \cup target` - - -* the set of edges :math:`E` - - - :math:`E = \begin{cases} - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ if } reverse\_cost = \varnothing \\ - \text{ } \text{ } & \text{ } \\ - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \text{ } \\ - \cup \{(source_i, target_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \quad \text{ if } reverse\_cost \neq \varnothing \\ - \end{cases}` - - -Given: - -- :math:`G(V,E)` - -Then: - -.. math::`\text{pgr_biconnectedComponents}(sql) = - \begin{cases} - \text{all biconnected components } \boldsymbol{\pi} \text{ in } G(V,E) &\quad \text{if } \exists \boldsymbol{\pi} \\ - \varnothing &\quad \text{otherwise} \\ - \end{cases}` - -:math:`\boldsymbol{\pi} = \{(component_i, n\_seq_i, node_i)\}` - -where: - - :math:`component_i = \min {node_j | node_j \in component_i}` - - :math:`n\_seq_i` is a sequential value starting from **1** in a component. - - :math:`edge_i \in component_i` - - The returned values are ordered: - - - `component` ascending - - `edge` ascending - -Example: - - The first component is composed of edges ``1 - 2``, ``0 - 1`` and ``0 - 2``. - - The second component is composed of edges ``2 - 4``, ``2 - 3`` and ``3 - 4``. - - The third component is composed of edge ``5 - 6``. - - The fourth component is composed of edge ``6 - 7``. - - The fifth component is composed of edges ``8 - 9``, ``9 - 10`` and ``8 - 10``. - -.. image:: images/biconnected_components.jpeg - :width: 210px - :height: 325px - -.. rubric:: Articulation Points - -Those vertices that belong to more than one biconnected component are called -articulation points or, equivalently, cut vertices. Articulation points are -vertices whose removal would increase the number of connected components in -the graph. - -**Notice**: This problem defines on an undirected graph. - -Given the following query: - - -pgr_articulationPoints(:math:`sql`) - -where :math:`sql = \{(id_i, source_i, target_i, cost_i, reverse\_cost_i)\}` - -and - -- :math:`source = \bigcup source_i`, -- :math:`target = \bigcup target_i`, - -The graphs are defined as follows: - -The weighted undirected graph, :math:`G(V,E)`, is definied by: - -* the set of vertices :math:`V` - - - :math:`V = source \cup target` - - -* the set of edges :math:`E` - - - :math:`E = \begin{cases} - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ if } reverse\_cost = \varnothing \\ - \text{ } \text{ } & \text{ } \\ - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \text{ } \\ - \cup \{(source_i, target_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \quad \text{ if } reverse\_cost \neq \varnothing \\ - \end{cases}` - - -Given: - -- :math:`G(V,E)` - -Then: - -.. math::`\text{pgr_articulationPoints}(sql) = - \begin{cases} - \text{all articulation points } \boldsymbol{\pi} \text{ in } G(V,E) &\quad \text{if } \exists \boldsymbol{\pi} \\ - \varnothing &\quad \text{otherwise} \\ - \end{cases}` - -:math:`\boldsymbol{\pi} = \{node_i\}` - -where: - - :math:`node_i` is an articulation point. - - The returned values are ordered: - - - `node` ascending - -Example: - - Articulation points are nodes ``2`` and ``6``. - -.. image:: images/biconnected_components.jpeg - :width: 210px - :height: 325px - -.. rubric:: Bridges - -A bridge is an edge of an undirected graph whose deletion increases its number -of connected components. - -**Notice**: This problem defines on an undirected graph. - -Given the following query: - - -pgr_bridges(:math:`sql`) - -where :math:`sql = \{(id_i, source_i, target_i, cost_i, reverse\_cost_i)\}` - -and - -- :math:`source = \bigcup source_i`, -- :math:`target = \bigcup target_i`, - -The graphs are defined as follows: - -The weighted undirected graph, :math:`G(V,E)`, is definied by: - -* the set of vertices :math:`V` - - - :math:`V = source \cup target` - - -* the set of edges :math:`E` - - - :math:`E = \begin{cases} - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \quad \text{ if } reverse\_cost = \varnothing \\ - \text{ } \text{ } & \text{ } \\ - \text{ } \{(source_i, target_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, cost_i) \text{ when } cost >=0 \} & \text{ } \\ - \cup \{(target_i, source_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \text{ } \\ - \cup \{(source_i, target_i, reverse\_cost_i) \text{ when } reverse\_cost_i >=0)\} & \quad \text{ if } reverse\_cost \neq \varnothing \\ - \end{cases}` - - -Given: - -- :math:`G(V,E)` - -Then: - -.. math::`\text{pgr_bridges}(sql) = - \begin{cases} - \text{all bridges } \boldsymbol{\pi} \text{ in } G(V,E) &\quad \text{if } \exists \boldsymbol{\pi} \\ - \varnothing &\quad \text{otherwise} \\ - \end{cases}` - -:math:`\boldsymbol{\pi} = \{edge_i\}` - -where: - - :math:`edge_i` is an edge. - - The returned values are ordered: - - - `edge` ascending - -Example: - - Bridges are edges ``5 <--> 6`` and ``6 <--> 7``. - -.. image:: images/biconnected_components.jpeg - :width: 210px - :height: 325px - -.. components_edges_sql_start - -Inner query +Parameters ------------------------------------------------------------------------------- -:edges_sql: an SQL query, which should return a set of rows with the following columns: - -================= =================== ======== ================================================= -Column Type Default Description -================= =================== ======== ================================================= -**id** ``ANY-INTEGER`` Identifier of the edge. -**source** ``ANY-INTEGER`` Identifier of the first end point vertex of the edge. -**target** ``ANY-INTEGER`` Identifier of the second end point vertex of the edge. -**cost** ``ANY-NUMERICAL`` Weight of the edge `(source, target)` - - - When negative: edge `(source, target)` does not exist, therefore it's not part of the graph. - -**reverse_cost** ``ANY-NUMERICAL`` -1 Weight of the edge `(target, source)`, - - - When negative: edge `(target, source)` does not exist, therefore it's not part of the graph. - -================= =================== ======== ================================================= - -Where: - -:ANY-INTEGER: SMALLINT, INTEGER, BIGINT -:ANY-NUMERICAL: SMALLINT, INTEGER, BIGINT, REAL, FLOAT - - -.. components_edges_sql_end - - .. components_parameters_start -Parameters -------------------------------------------------------------------------------- - =================== ====================== ========= ========================================= Parameter Type Default Description =================== ====================== ========= ========================================= -**edges_sql** ``TEXT`` SQL query as described above. +**Edges SQL** ``TEXT`` Inner query as described bellow. =================== ====================== ========= ========================================= .. components_parameters_end +Inner query +------------------------------------------------------------------------------- -.. return_componentsV_start - -.. rubric:: Description of the return values for connected components and strongly connected components - -Returns set of ``(seq, component, n_seq, node)`` - -============== ========== ================================================= -Column Type Description -============== ========== ================================================= -**seq** ``INT`` Sequential value starting from **1**. -**component** ``BIGINT`` Component identifier. It is equal to the minimum node identifier in the component. -**n_seq** ``INT`` It is a sequential value starting from **1** in a component. -**node** ``BIGINT`` Identifier of the vertex. -============== ========== ================================================= - -.. return_componentsV_end - - -.. return_componentsE_start - -.. rubric:: Description of the return values for biconnected components, connected components (edge version) and strongly connected components - -Returns set of ``(seq, component, n_seq, edge)`` +:Edges SQL: an SQL query which should return a set of rows with the following columns: -============== ========== ================================================= -Column Type Description -============== ========== ================================================= -**seq** ``INT`` Sequential value starting from **1**. -**component** ``BIGINT`` Component identifier. It is equal to the minimum edge identifier in the component. -**n_seq** ``INT`` It is a sequential value starting from **1** in a component. -**edge** ``BIGINT`` Identifier of the edge. -============== ========== ================================================= +.. include:: pgRouting-concepts.rst + :start-after: basic_edges_sql_start + :end-before: basic_edges_sql_end -.. return_componentsE_end +Result Columns +------------------------------------------------------------------------------- -.. return_cutvertices_start +pgr_connectedComponents & pgr_strongComponents +............................................................................... -Result Columns (pgr_articulationPoints) -------------------------------------------------------------------------------- +.. include:: pgr_connectedComponents.rst + :start-after: return_componentsV_start + :end-before: return_componentsV_end -Returns set of ``(seq, node)`` -============== ========== ================================================= -Column Type Description -============== ========== ================================================= -**seq** ``INT`` Sequential value starting from **1**. -**node** ``BIGINT`` Identifier of the vertex. -============== ========== ================================================= +pgr_biconnectedComponents +............................................................................... -.. return_cutvertices_end +.. include:: pgr_biconnectedComponents.rst + :start-after: return_componentsE_start + :end-before: return_componentsE_end -.. return_bridges_start +pgr_articulationPoints +............................................................................... -.. rubric:: Description of the return values for bridges +.. include:: pgr_articulationPoints.rst + :start-after: return_articulation_start + :end-before: return_articulation_end -Returns set of ``(seq, node)`` +pgr_bridges +............................................................................... -============== ========== ================================================= -Column Type Description -============== ========== ================================================= -**seq** ``INT`` Sequential value starting from **1**. -**edge** ``BIGINT`` Identifier of the edge. -============== ========== ================================================= +.. include:: pgr_bridges.rst + :start-after: return_bridges_start + :end-before: return_bridges_end -.. return_bridges_end See Also ------------------------------------------------------------------------------- diff --git a/doc/components/images/CMakeLists.txt b/doc/components/images/CMakeLists.txt index 32017ab4bf..519323b976 100644 --- a/doc/components/images/CMakeLists.txt +++ b/doc/components/images/CMakeLists.txt @@ -1,9 +1,5 @@ SET(LOCAL_FILES - connected_components.jpeg - strong_components.jpeg - biconnected_components.jpeg - cc_sampledata.png scc_sampledata.png bcc_sampledata.png diff --git a/doc/components/images/biconnected_components.jpeg b/doc/components/images/biconnected_components.jpeg deleted file mode 100644 index e1812b8554..0000000000 Binary files a/doc/components/images/biconnected_components.jpeg and /dev/null differ diff --git a/doc/components/images/connected_components.jpeg b/doc/components/images/connected_components.jpeg deleted file mode 100644 index e0b9384d31..0000000000 Binary files a/doc/components/images/connected_components.jpeg and /dev/null differ diff --git a/doc/components/images/strong_components.jpeg b/doc/components/images/strong_components.jpeg deleted file mode 100644 index ca11bd46dc..0000000000 Binary files a/doc/components/images/strong_components.jpeg and /dev/null differ diff --git a/doc/components/pgr_articulationPoints.rst b/doc/components/pgr_articulationPoints.rst index e06cac0e8b..58af625686 100644 --- a/doc/components/pgr_articulationPoints.rst +++ b/doc/components/pgr_articulationPoints.rst @@ -7,24 +7,29 @@ Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/ **************************************************************************** -pgr_articulationPoints - Experimental +pgr_articulationPoints - Proposed =============================================================================== ``pgr_articulationPoints`` - Return the articulation points of an undirected graph. In particular, the algorithm implemented by Boost.Graph. .. figure:: images/boost-inside.jpeg - :target: http://www.boost.org/libs/graph/doc/connected_components.html + :target: http://www.boost.org/libs/graph/doc/biconnected_components.html Boost Graph Inside .. include:: proposed.rst - :start-after: begin-warn-expr - :end-before: end-warn-expr + :start-after: stable-begin-warning + :end-before: stable-end-warning .. rubric:: Availability -* **TBD** +* On v3.0.0 + + * Set as `proposed` + * Return columns change: ``seq`` is removed + +* New as experimental on v2.5.0 Description ------------------------------------------------------------------------------- @@ -47,11 +52,14 @@ This implementation can only be used with an undirected graph. Signatures ------------------------------------------------------------------------------- +.. index:: + single: articulationPoints -- Proposed + .. code-block:: none - pgr_articulationPoints(edges_sql) + pgr_articulationPoints(Edges SQL) - RETURNS SET OF (seq, node) + RETURNS SET OF (node) OR EMPTY SET :Example: The articulation points of the graph @@ -60,23 +68,44 @@ Signatures :start-after: -- q1 :end-before: -- q2 +Parameters +------------------------------------------------------------------------------- + .. include:: components-family.rst :start-after: components_parameters_start :end-before: components_parameters_end -.. include:: components-family.rst - :start-after: components_edges_sql_start - :end-before: components_edges_sql_end +Inner query +------------------------------------------------------------------------------- -.. include:: components-family.rst - :start-after: return_cutvertices_start - :end-before: return_cutvertices_end +:edges SQL: an SQL query of an **undirected** graph, which should return a set of rows with the following columns: + +.. include:: pgRouting-concepts.rst + :start-after: basic_edges_sql_start + :end-before: basic_edges_sql_end + +Result Columns +------------------------------------------------------------------------------- + +.. return_articulation_start + +Returns set of ``(node)`` + +============== ========== ================================================= +Column Type Description +============== ========== ================================================= +**node** ``BIGINT`` Identifier of the vertex. +============== ========== ================================================= + +.. return_articulation_end See Also ------------------------------------------------------------------------------- -* http://en.wikipedia.org/wiki/Biconnected_component +* :doc:`components-family` * The queries use the :doc:`sampledata` network. +* Boost: `Biconnected components & articulation points `__ +* wikipedia: `Biconnected component `__ .. rubric:: Indices and tables diff --git a/doc/components/pgr_biconnectedComponents.rst b/doc/components/pgr_biconnectedComponents.rst index f924bb1d2f..63e978af90 100644 --- a/doc/components/pgr_biconnectedComponents.rst +++ b/doc/components/pgr_biconnectedComponents.rst @@ -7,7 +7,7 @@ Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/ **************************************************************************** -pgr_biconnectedComponents - Experimental +pgr_biconnectedComponents - Proposed =============================================================================== ``pgr_biconnectedComponents`` — Return the biconnected components of an undirected graph. @@ -19,12 +19,17 @@ In particular, the algorithm implemented by Boost.Graph. Boost Graph Inside .. include:: proposed.rst - :start-after: begin-warn-expr - :end-before: end-warn-expr + :start-after: stable-begin-warning + :end-before: stable-end-warning .. rubric:: Availability -* **TBD** +* On v3.0.0 + + * Set as `proposed` + * Return columns change: ``n_seq`` is removed + +* New as experimental on v2.5.0 Description ------------------------------------------------------------------------------- @@ -32,9 +37,7 @@ Description The biconnected components of an undirected graph are the maximal subsets of vertices such that the removal of a vertex from particular component will not disconnect the component. Unlike connected components, vertices may belong to multiple biconnected components. Vertices can be present in multiple biconnected components, but each edge can only be contained in a single biconnected -component. So, the output only has edge version. - -This implementation can only be used with an undirected graph. +component. **The main characteristics are:** @@ -51,13 +54,13 @@ Signatures ------------------------------------------------------------------------------- .. index:: - single: biconnectedComponents + single: biconnectedComponents -- Proposed .. code-block:: none - pgr_biconnectedComponents(edges_sql) + pgr_biconnectedComponents(Edges SQL) - RETURNS SET OF (seq, component, n_seq, edge) + RETURNS SET OF (seq, component, edge) OR EMPTY SET :Example: The biconnected components of the graph @@ -66,29 +69,48 @@ Signatures :start-after: -- q1 :end-before: -- q2 +Parameters +------------------------------------------------------------------------------- + .. include:: components-family.rst :start-after: components_parameters_start :end-before: components_parameters_end -.. include:: components-family.rst - :start-after: components_edges_sql_start - :end-before: components_edges_sql_end +Inner query +------------------------------------------------------------------------------- + +:edges SQL: an SQL query of an **undirected** graph, which should return a set of rows with the following columns: + +.. include:: pgRouting-concepts.rst + :start-after: basic_edges_sql_start + :end-before: basic_edges_sql_end Result Columns ------------------------------------------------------------------------------- -.. include:: components-family.rst - :start-after: return_componentsE_start - :end-before: return_componentsE_end +.. return_componentsE_start + +Returns set of ``(seq, component, edge)`` + +============== ========== ================================================= +Column Type Description +============== ========== ================================================= +**seq** ``INT`` Sequential value starting from **1**. +**component** ``BIGINT`` Component identifier. It is equal to the minimum edge identifier in the component. +**edge** ``BIGINT`` Identifier of the edge. +============== ========== ================================================= + +.. return_componentsE_end See Also ------------------------------------------------------------------------------- -* http://en.wikipedia.org/wiki/Biconnected_component +* :doc:`components-family` * The queries use the :doc:`sampledata` network. +* Boost: `Biconnected components `__ +* wikipedia: `Biconnected component `__ .. rubric:: Indices and tables * :ref:`genindex` * :ref:`search` - diff --git a/doc/components/pgr_bridges.rst b/doc/components/pgr_bridges.rst index be8bcc5c5c..d6ce8197b5 100644 --- a/doc/components/pgr_bridges.rst +++ b/doc/components/pgr_bridges.rst @@ -7,7 +7,7 @@ Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/ **************************************************************************** -pgr_bridges - Experimental +pgr_bridges - Proposed =============================================================================== ``pgr_bridges`` - Return the bridges of an undirected graph. @@ -18,12 +18,17 @@ pgr_bridges - Experimental Boost Graph Inside .. include:: proposed.rst - :start-after: begin-warn-expr - :end-before: end-warn-expr + :start-after: stable-begin-warning + :end-before: stable-end-warning .. rubric:: Availability -* **TBD** +* On v3.0.0 + + * Set as `proposed` + * Return columns change: ``seq`` is removed + +* New as experimental on v2.5.0 Description ------------------------------------------------------------------------------- @@ -45,13 +50,13 @@ Signatures ------------------------------------------------------------------------------- .. index:: - single: bridges + single: bridges -- Proposed .. code-block:: none - pgr_bridges(edges_sql) + pgr_bridges(Edges SQL) - RETURNS SET OF (seq, node) + RETURNS SET OF (edge) OR EMPTY SET :Example: The bridges of the graph @@ -60,19 +65,35 @@ Signatures :start-after: -- q1 :end-before: -- q2 +Parameters +------------------------------------------------------------------------------- + .. include:: components-family.rst :start-after: components_parameters_start :end-before: components_parameters_end -.. include:: components-family.rst - :start-after: components_edges_sql_start - :end-before: components_edges_sql_end +Inner query +------------------------------------------------------------------------------- + +:edges SQL: an SQL query of an **undirected** graph, which should return a set of rows with the following columns: + +.. include:: pgRouting-concepts.rst + :start-after: basic_edges_sql_start + :end-before: basic_edges_sql_end Result Columns ------------------------------------------------------------------------------- -.. include:: components-family.rst - :start-after: return_bridges_start - :end-before: return_bridges_end +.. return_bridges_start + +Returns set of ``(edge)`` + +============== ========== ================================================= +Column Type Description +============== ========== ================================================= +**edge** ``BIGINT`` Identifier of the edge that is a bridge. +============== ========== ================================================= + +.. return_bridges_end See Also ------------------------------------------------------------------------------- diff --git a/doc/components/pgr_connectedComponents.rst b/doc/components/pgr_connectedComponents.rst index 6ba1766ec7..173a6ba708 100644 --- a/doc/components/pgr_connectedComponents.rst +++ b/doc/components/pgr_connectedComponents.rst @@ -7,11 +7,10 @@ Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/ **************************************************************************** -pgr_connectedComponents - Experimental +pgr_connectedComponents - Proposed =============================================================================== -``pgr_connectedComponents`` — Return the connected components of an undirected graph using a DFS-based approach. -In particular, the algorithm implemented by Boost.Graph. +``pgr_connectedComponents`` — Connected components of an undirected graph using a DFS-based approach. .. figure:: images/boost-inside.jpeg :target: http://www.boost.org/libs/graph/doc/connected_components.html @@ -19,19 +18,23 @@ In particular, the algorithm implemented by Boost.Graph. Boost Graph Inside .. include:: proposed.rst - :start-after: begin-warn-expr - :end-before: end-warn-expr + :start-after: stable-begin-warning + :end-before: stable-end-warning .. rubric:: Availability -* **TBD** +* On v3.0.0 + + * Set as `proposed` + * Return columns change: ``n_seq`` is removed + +* New as experimental on v2.5.0 Description ------------------------------------------------------------------------------- A connected component of an undirected graph is a set of vertices that are all reachable from each other. -This implementation can only be used with an undirected graph. **The main characteristics are:** @@ -49,13 +52,13 @@ Signatures ------------------------------------------------------------------------------- .. index:: - single: connectedComponents + single: connectedComponents -- Proposed .. code-block:: none pgr_connectedComponents(edges_sql) - RETURNS SET OF (seq, component, n_seq, node) + RETURNS SET OF (seq, component, node) OR EMPTY SET :Example: The connected components of the graph @@ -64,26 +67,47 @@ Signatures :start-after: -- q1 :end-before: -- q2 +Parameters +------------------------------------------------------------------------------- + .. include:: components-family.rst :start-after: components_parameters_start :end-before: components_parameters_end -.. include:: components-family.rst - :start-after: components_edges_sql_start - :end-before: components_edges_sql_end +Inner query +------------------------------------------------------------------------------- + +:edges SQL: an SQL query of an **undirected** graph, which should return a set of rows with the following columns: + +.. include:: pgRouting-concepts.rst + :start-after: basic_edges_sql_start + :end-before: basic_edges_sql_end + Result Columns ------------------------------------------------------------------------------- -.. include:: components-family.rst - :start-after: return_componentsV_start - :end-before: return_componentsV_end +.. return_componentsV_start + +Returns set of ``(seq, component, node)`` + +============== ========== ================================================= +Column Type Description +============== ========== ================================================= +**seq** ``INT`` Sequential value starting from **1**. +**component** ``BIGINT`` Component identifier. It is equal to the minimum node identifier in the component. +**node** ``BIGINT`` Identifier of the vertex that belongs to **component**. +============== ========== ================================================= + +.. return_componentsV_end See Also ------------------------------------------------------------------------------- -* http://en.wikipedia.org/wiki/Connected_component_%28graph_theory%29 +* :doc:`components-family` * The queries use the :doc:`sampledata` network. +* Boost: `Connected components `__ +* wikipedia: `Connected component `__ .. rubric:: Indices and tables diff --git a/doc/components/pgr_strongComponents.rst b/doc/components/pgr_strongComponents.rst index 7e4a1fa847..1aabdba3b3 100644 --- a/doc/components/pgr_strongComponents.rst +++ b/doc/components/pgr_strongComponents.rst @@ -7,11 +7,10 @@ Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/ **************************************************************************** -pgr_strongComponents - Experimental +pgr_strongComponents - Proposed =============================================================================== -``pgr_strongComponents`` — Return the strongly connected components of a directed graph using Tarjan's algorithm based on DFS. -In particular, the algorithm implemented by Boost.Graph. +``pgr_strongComponents`` — Strongly connected components of a directed graph using Tarjan's algorithm based on DFS. .. figure:: images/boost-inside.jpeg :target: http://www.boost.org/libs/graph/doc/strong_components.html @@ -19,19 +18,23 @@ In particular, the algorithm implemented by Boost.Graph. Boost Graph Inside .. include:: proposed.rst - :start-after: begin-warn-expr - :end-before: end-warn-expr + :start-after: stable-begin-warning + :end-before: stable-end-warning -.. rubric:: Availiability +.. rubric:: Availability -* **TBD** +* On v3.0.0 + + * Set as `proposed` + * Return columns change: ``n_seq`` is removed + +* New as experimental on v2.5.0 Description ------------------------------------------------------------------------------- A strongly connected component of a directed graph is a set of vertices that are all reachable from each other. -This implementation can only be used with a directed graph. **The main characteristics are:** @@ -48,13 +51,13 @@ Signatures ------------------------------------------------------------------------------- .. index:: - single: strongComponents + single: strongComponents -- Proposed .. code-block:: none - pgr_strongComponents(edges_sql) + pgr_strongComponents(Edges SQL) - RETURNS SET OF (seq, component, n_seq, node) + RETURNS SET OF (seq, component, node) OR EMPTY SET :Example: The strong components of the graph @@ -63,26 +66,38 @@ Signatures :start-after: -- q1 :end-before: -- q2 +Parameters +------------------------------------------------------------------------------- + + .. include:: components-family.rst :start-after: components_parameters_start :end-before: components_parameters_end -.. include:: components-family.rst - :start-after: components_edges_sql_start - :end-before: components_edges_sql_end +Inner query +------------------------------------------------------------------------------- + +:edges SQL: an SQL query of a **directed** graph, which should return a set of rows with the following columns: + +.. include:: pgRouting-concepts.rst + :start-after: basic_edges_sql_start + :end-before: basic_edges_sql_end + Result Columns ------------------------------------------------------------------------------- -.. include:: components-family.rst +.. include:: pgr_connectedComponents.rst :start-after: return_componentsV_start :end-before: return_componentsV_end See Also ------------------------------------------------------------------------------- -* http://en.wikipedia.org/wiki/Strongly_connected_component +* :doc:`components-family` * The queries use the :doc:`sampledata` network. +* Boost: `Strong components `__ +* wikipedia: `Strongly connected component `__ .. rubric:: Indices and tables diff --git a/doc/dijkstra/pgr_dijkstra.rst b/doc/dijkstra/pgr_dijkstra.rst index 1fef8abb7c..83edabf4d1 100644 --- a/doc/dijkstra/pgr_dijkstra.rst +++ b/doc/dijkstra/pgr_dijkstra.rst @@ -101,10 +101,10 @@ One to One pgr_dijkstra(TEXT edges_sql, BIGINT start_vid, BIGINT end_vid, BOOLEAN directed:=true); - RETURNS SET OF (seq, path_seq, node, edge, cost, agg_cost) + RETURNS SET OF (seq, path_seq, node, edge, cost, agg_cost) OR EMPTY SET -:Example: From vertex :math:`2` to vertex :math:`3` on an **undirected** graph +:Example: From vertex :math:`2` to vertex :math:`3` on an **undirected** graph .. literalinclude:: doc-pgr_dijkstra.queries :start-after: -- q2 @@ -120,7 +120,7 @@ One to many pgr_dijkstra(TEXT edges_sql, BIGINT start_vid, ARRAY[ANY_INTEGER] end_vids, BOOLEAN directed:=true); - RETURNS SET OF (seq, path_seq, end_vid, node, edge, cost, agg_cost) + RETURNS SET OF (seq, path_seq, end_vid, node, edge, cost, agg_cost) OR EMPTY SET :Example: From vertex :math:`2` to vertices :math:`\{3, 5\}` on an **undirected** graph @@ -139,7 +139,7 @@ Many to One pgr_dijkstra(TEXT edges_sql, ARRAY[ANY_INTEGER] start_vids, BIGINT end_vid, BOOLEAN directed:=true); - RETURNS SET OF (seq, path_seq, start_vid, node, edge, cost, agg_cost) + RETURNS SET OF (seq, path_seq, start_vid, node, edge, cost, agg_cost) OR EMPTY SET :Example: From vertices :math:`\{2, 11\}` to vertex :math:`5` on a **directed** graph @@ -158,7 +158,7 @@ Many to Many pgr_dijkstra(TEXT edges_sql, ARRAY[ANY_INTEGER] start_vids, ARRAY[ANY_INTEGER] end_vids, BOOLEAN directed:=true); - RETURNS SET OF (seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost) + RETURNS SET OF (seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost) OR EMPTY SET :Example: From vertices :math:`\{2, 11\}` to vertices :math:`\{3, 5\}` on an **undirected** graph diff --git a/doc/queries/doc-pgr_articulationPoints.queries b/doc/queries/doc-pgr_articulationPoints.queries index 1e8a60f785..ed43a5b439 100644 --- a/doc/queries/doc-pgr_articulationPoints.queries +++ b/doc/queries/doc-pgr_articulationPoints.queries @@ -6,24 +6,24 @@ SET SELECT * FROM pgr_articulationPoints( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | node ------+------ - 1 | 2 - 2 | 5 - 3 | 8 - 4 | 10 + node +------ + 2 + 5 + 8 + 10 (4 rows) -- q2 SELECT * FROM pgr_articulationPoints( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | node ------+------ - 1 | 2 - 2 | 5 - 3 | 8 - 4 | 10 + node +------ + 2 + 5 + 8 + 10 (4 rows) ROLLBACK; diff --git a/doc/queries/doc-pgr_biconnectedComponents.queries b/doc/queries/doc-pgr_biconnectedComponents.queries index 183b2e7179..73b2dcc9e4 100644 --- a/doc/queries/doc-pgr_biconnectedComponents.queries +++ b/doc/queries/doc-pgr_biconnectedComponents.queries @@ -6,52 +6,52 @@ SET SELECT * FROM pgr_biconnectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | edge ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 2 | 1 | 2 - 3 | 2 | 2 | 3 - 4 | 2 | 3 | 4 - 5 | 2 | 4 | 5 - 6 | 2 | 5 | 8 - 7 | 2 | 6 | 9 - 8 | 2 | 7 | 10 - 9 | 2 | 8 | 11 - 10 | 2 | 9 | 12 - 11 | 2 | 10 | 13 - 12 | 2 | 11 | 15 - 13 | 2 | 12 | 16 - 14 | 6 | 1 | 6 - 15 | 7 | 1 | 7 - 16 | 14 | 1 | 14 - 17 | 17 | 1 | 17 - 18 | 18 | 1 | 18 + seq | component | edge +-----+-----------+------ + 1 | 1 | 1 + 2 | 2 | 2 + 3 | 2 | 3 + 4 | 2 | 4 + 5 | 2 | 5 + 6 | 2 | 8 + 7 | 2 | 9 + 8 | 2 | 10 + 9 | 2 | 11 + 10 | 2 | 12 + 11 | 2 | 13 + 12 | 2 | 15 + 13 | 2 | 16 + 14 | 6 | 6 + 15 | 7 | 7 + 16 | 14 | 14 + 17 | 17 | 17 + 18 | 18 | 18 (18 rows) -- q2 SELECT * FROM pgr_biconnectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | edge ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 2 | 1 | 2 - 3 | 2 | 2 | 3 - 4 | 2 | 3 | 4 - 5 | 2 | 4 | 5 - 6 | 2 | 5 | 8 - 7 | 2 | 6 | 9 - 8 | 2 | 7 | 10 - 9 | 2 | 8 | 11 - 10 | 2 | 9 | 12 - 11 | 2 | 10 | 13 - 12 | 2 | 11 | 15 - 13 | 2 | 12 | 16 - 14 | 6 | 1 | 6 - 15 | 7 | 1 | 7 - 16 | 14 | 1 | 14 - 17 | 17 | 1 | 17 - 18 | 18 | 1 | 18 + seq | component | edge +-----+-----------+------ + 1 | 1 | 1 + 2 | 2 | 2 + 3 | 2 | 3 + 4 | 2 | 4 + 5 | 2 | 5 + 6 | 2 | 8 + 7 | 2 | 9 + 8 | 2 | 10 + 9 | 2 | 11 + 10 | 2 | 12 + 11 | 2 | 13 + 12 | 2 | 15 + 13 | 2 | 16 + 14 | 6 | 6 + 15 | 7 | 7 + 16 | 14 | 14 + 17 | 17 | 17 + 18 | 18 | 18 (18 rows) ROLLBACK; diff --git a/doc/queries/doc-pgr_bridges.queries b/doc/queries/doc-pgr_bridges.queries index fd7b907b8a..6e5ce6ec7b 100644 --- a/doc/queries/doc-pgr_bridges.queries +++ b/doc/queries/doc-pgr_bridges.queries @@ -6,28 +6,28 @@ SET SELECT * FROM pgr_bridges( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | edge ------+------ - 1 | 1 - 2 | 6 - 3 | 7 - 4 | 14 - 5 | 17 - 6 | 18 + edge +------ + 1 + 6 + 7 + 14 + 17 + 18 (6 rows) -- q2 SELECT * FROM pgr_bridges( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | edge ------+------ - 1 | 1 - 2 | 6 - 3 | 7 - 4 | 14 - 5 | 17 - 6 | 18 + edge +------ + 1 + 6 + 7 + 14 + 17 + 18 (6 rows) ROLLBACK; diff --git a/doc/queries/doc-pgr_connectedComponents.queries b/doc/queries/doc-pgr_connectedComponents.queries index 3636e0a7f5..d17c8afff3 100644 --- a/doc/queries/doc-pgr_connectedComponents.queries +++ b/doc/queries/doc-pgr_connectedComponents.queries @@ -6,50 +6,50 @@ SET SELECT * FROM pgr_connectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) -- q2 SELECT * FROM pgr_connectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) ROLLBACK; diff --git a/doc/queries/doc-pgr_strongComponents.queries b/doc/queries/doc-pgr_strongComponents.queries index a78b576613..1a6a230d50 100644 --- a/doc/queries/doc-pgr_strongComponents.queries +++ b/doc/queries/doc-pgr_strongComponents.queries @@ -6,50 +6,50 @@ SET SELECT * FROM pgr_strongComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) -- q2 SELECT * FROM pgr_strongComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) ROLLBACK; diff --git a/doc/src/pgRouting-concepts.rst b/doc/src/pgRouting-concepts.rst index db12f9d8df..4983aa46df 100644 --- a/doc/src/pgRouting-concepts.rst +++ b/doc/src/pgRouting-concepts.rst @@ -209,8 +209,6 @@ Description of the edges_sql query for dijkstra like functions .. basic_edges_sql_start -:Edges SQL: an SQL query, which should return a set of rows with the following columns: - ================= =================== ======== ================================================= Column Type Default Description ================= =================== ======== ================================================= diff --git a/doc/src/proposed.rst b/doc/src/proposed.rst index a988f5436a..199032ecce 100644 --- a/doc/src/proposed.rst +++ b/doc/src/proposed.rst @@ -37,6 +37,12 @@ Stable Proposed Functions :start-after: index proposed from here :end-before: index proposed to here +:doc:`components-family` + +.. include:: components-family.rst + :start-after: index from here + :end-before: index to here + :doc:`withPoints-family` @@ -73,6 +79,7 @@ Stable Proposed Functions .. toctree:: :hidden: + components-family withPoints-family cost-category costMatrix-category @@ -134,12 +141,6 @@ Experimental Functions :end-before: index to here -:doc:`components-family` - -.. include:: components-family.rst - :start-after: index from here - :end-before: index to here - :doc:`transformation-family` .. include:: transformation-family.rst @@ -152,7 +153,6 @@ Experimental Functions costFlow-family chinesePostmanProblem-family contraction-family - components-family transformation-family .. rubric:: Others diff --git a/include/c_types/pgr_components_rt.h b/include/c_types/pgr_components_rt.h index 13bb16cc9a..207e75b66e 100644 --- a/include/c_types/pgr_components_rt.h +++ b/include/c_types/pgr_components_rt.h @@ -38,7 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. typedef struct { int64_t component; - int n_seq; int64_t identifier; } pgr_components_rt; diff --git a/include/c_types/pgr_topological_sort_t.h b/include/c_types/pgr_topological_sort_t.h new file mode 100644 index 0000000000..9959338bcc --- /dev/null +++ b/include/c_types/pgr_topological_sort_t.h @@ -0,0 +1,39 @@ +/*PGR-GNU***************************************************************** +File: pgr_topological_sort_t.h + +Function's developer: +Copyright (c) 2019 Hang Wu +mail: nike0good@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*/ +/*! @file */ + +#ifndef INCLUDE_C_TYPES_PGR_TOPOLOGICAL_SORT_T_H_ +#define INCLUDE_C_TYPES_PGR_TOPOLOGICAL_SORT_T_H_ +#pragma once + +/* for int64_t */ +#ifdef __cplusplus +# include +#else +# include +#endif + +typedef struct { + int seq; + int sorted_v; +} pgr_topological_sort_t; + +#endif // INCLUDE_C_TYPES_PGR_TOPOLOGICAL_SORT_T_H_ diff --git a/include/components/componentsResult.h b/include/components/componentsResult.h new file mode 100644 index 0000000000..166a57ba70 --- /dev/null +++ b/include/components/componentsResult.h @@ -0,0 +1,49 @@ +/*PGR-GNU***************************************************************** + +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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_COMPONENTS_COMPONENTSRESULT_H_ +#define INCLUDE_COMPONENTS_COMPONENTSRESULT_H_ +#pragma once + +#include "c_types/pgr_components_rt.h" + +#include + +namespace pgrouting { +namespace algorithms { + +namespace detail { + +std::vector +componentsResult( + std::vector> &components); + +} // namespace detail + +} // namespace algorithms +} // namespace pgrouting + +#endif // INCLUDE_COMPONENTS_COMPONENTSRESULT_H_ diff --git a/include/components/pgr_components.hpp b/include/components/pgr_components.hpp index 34f5463e88..e95d375a62 100644 --- a/include/components/pgr_components.hpp +++ b/include/components/pgr_components.hpp @@ -39,211 +39,36 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include -#include "pgr_componentsGraph.hpp" +#include "cpp_common/pgr_base_graph.hpp" +#include "cpp_common/identifiers.hpp" +#include "components/componentsResult.h" -template < class G > class Pgr_components; -// user's functions -// for development +namespace pgrouting { +namespace algorithms { -//****************************************** - -template < class G > -class Pgr_components { - public: - typedef typename G::V V; - typedef typename G::E E; - typedef typename G::E_i E_i; - - //! Connected Components Vertex Version - std::vector connectedComponents( - G &graph); - - //! Strongly Connected Components Vertex Version - std::vector strongComponents( - G &graph); - - //! Biconnected Components - std::vector biconnectedComponents( - G &graph); - - //! Articulation Points - std::vector articulationPoints( - G &graph); - - //! Bridges - std::vector bridges( - G &graph); - - private: - //! Generate Results, Vertex Version - std::vector generate_results( - std::vector< std::vector< int64_t > >); -}; - - -/******************** IMPLEMENTTION ******************/ - -//! Generate Results, Vertex Version -template < class G > -std::vector -Pgr_components< G >::generate_results( - std::vector< std::vector< int64_t > > components) { - // sort identifier - size_t num_comps = components.size(); - for (size_t i = 0; i < num_comps; i++) { - std::sort(components[i].begin(), components[i].end()); - } - sort(components.begin(), components.end()); - - // generate results - std::vector< pgr_components_rt > results; - for (size_t i = 0; i < num_comps; i++) { - int64_t tempComp = components[i][0]; - size_t sizeCompi = components[i].size(); - for (size_t j = 0; j < sizeCompi; j++) { - pgr_components_rt tmp; - tmp.identifier = components[i][j]; - tmp.n_seq = static_cast< int > (j + 1); - tmp.component = tempComp; - results.push_back(tmp); - } - } - return results; -} - -//! Connected Components Vertex Version -template < class G > +/** + * works for undirected graph + **/ std::vector -Pgr_components< G >::connectedComponents( - G &graph) { - size_t totalNodes = num_vertices(graph.graph); - - // perform the algorithm - std::vector< int > components(totalNodes); - int num_comps = boost::connected_components(graph.graph, &components[0]); - - // get the results - std::vector< std::vector< int64_t > > results; - results.resize(num_comps); - for (size_t i = 0; i < totalNodes; i++) - results[components[i]].push_back(graph[i].id); - - return generate_results(results); -} +pgr_connectedComponents(pgrouting::UndirectedGraph &graph); //! Strongly Connected Components Vertex Version -template < class G > std::vector -Pgr_components< G >::strongComponents( - G &graph) { - size_t totalNodes = num_vertices(graph.graph); - - // perform the algorithm - std::vector< int > components(totalNodes); - int num_comps = boost::strong_components(graph.graph, - boost::make_iterator_property_map(components.begin(), - get(boost::vertex_index, - graph.graph))); - - // get the results - std::vector< std::vector< int64_t > > results; - results.resize(num_comps); - for (size_t i = 0; i < totalNodes; i++) - results[components[i]].push_back(graph[i].id); - - return generate_results(results); -} - -//! Biconnected Components -template < class G > +strongComponents(pgrouting::DirectedGraph &graph); + +//! Biconnected Components (for undirected) std::vector -Pgr_components< G >::biconnectedComponents( - G &graph) { - // perform the algorithm - struct order_edges { - bool operator() (const E &left, const E &right) const { - return left.get_property() < right.get_property(); - } - }; - typedef std::map< E, size_t > edge_map; - edge_map bicmp_map; - - boost::associative_property_map< edge_map > bimap(bicmp_map); - size_t num_comps = biconnected_components(graph.graph, bimap); - - // get the results - E_i ei, ei_end; - std::vector< std::vector< int64_t > > components(num_comps); - for (boost::tie(ei, ei_end) = edges(graph.graph); ei != ei_end; ei++) - components[bimap[*ei]].push_back(graph[*ei].id); - - return generate_results(components); -} +biconnectedComponents(pgrouting::UndirectedGraph &graph); //! Articulation Points -template < class G > -std::vector -Pgr_components< G >::articulationPoints( - G &graph) { - // perform the algorithm - std::vector art_points; - boost::articulation_points(graph.graph, std::back_inserter(art_points)); - - // get the results - std::vector results; - size_t totalArtp = art_points.size(); - results.resize(totalArtp); - for (size_t i = 0; i < totalArtp; i++) - results[i].identifier = graph[art_points[i]].id; - - // sort identifier - std::sort(results.begin(), results.end(), - [](const pgr_components_rt &left, const pgr_components_rt &right) { - return left.identifier < right.identifier; }); - - return results; -} +Identifiers +articulationPoints(pgrouting::UndirectedGraph &graph); //! Bridges -template < class G > -std::vector -Pgr_components< G >::bridges( - G &graph) { - size_t totalNodes = num_vertices(graph.graph); - std::vector< int > tmp_comp(totalNodes); - std::vector results; - int ini_comps = boost::connected_components(graph.graph, &tmp_comp[0]); - - // perform the algorithm - E_i ei, ei_end; - std::vector< std::pair > stored_edges; - for (boost::tie(ei, ei_end) = edges(graph.graph); ei != ei_end; ++ei) { - stored_edges.push_back(std::make_pair(*ei, graph[*ei].id)); - } - - for (const auto pair_edge : stored_edges) { - E edge = pair_edge.first; - - boost::remove_edge(edge, graph.graph); - - int now_comps = boost::connected_components(graph.graph, &tmp_comp[0]); - if (now_comps > ini_comps) { - pgr_components_rt temp; - temp.identifier = pair_edge.second; - results.push_back(temp); - } - - boost::add_edge(boost::source(edge, graph.graph), - boost::target(edge, graph.graph), - graph.graph); - } - - // sort identifier - std::sort(results.begin(), results.end(), - [](const pgr_components_rt &left, const pgr_components_rt &right) { - return left.identifier < right.identifier; }); - - return results; -} +Identifiers +bridges(pgrouting::UndirectedGraph &graph); + +} // namespace algorithms +} // namespace pgrouting #endif // INCLUDE_COMPONENTS_PGR_COMPONENTS_HPP_ diff --git a/include/components/pgr_componentsGraph.hpp b/include/components/pgr_componentsGraph.hpp deleted file mode 100644 index 7bf3555221..0000000000 --- a/include/components/pgr_componentsGraph.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/*PGR-GNU***************************************************************** -File: pgr_componentsGraph.hpp - -Generated with Template by: -Copyright (c) 2015 pgRouting developers -Mail: project@pgrouting.org - -Function's developer: -Copyright (c) 2017 Maoguang Wang -Mail: xjtumg1007@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_COMPONENTS_PGR_COMPONENTSGRAPH_HPP_ -#define INCLUDE_COMPONENTS_PGR_COMPONENTSGRAPH_HPP_ -#pragma once - - -#include - -#include "cpp_common/pgr_base_graph.hpp" - - -namespace pgrouting { - -namespace graph { - -template -class Pgr_componentsGraph; - -} // namespace graph - -typedef graph::Pgr_componentsGraph < -boost::adjacency_list < boost::vecS, boost::vecS, - boost::undirectedS, - Basic_vertex, Basic_edge >, - Basic_vertex, Basic_edge > ComponentsUndiGraph; - -namespace graph { - -template -class Pgr_componentsGraph : public Pgr_base_graph { - public: - G graph; - - explicit Pgr_componentsGraph< G, T_V, T_E >(graphType gtype) - : Pgr_base_graph< G, T_V, T_E >(gtype) { - } - - template < typename T > - void insert_edges(const T *edges, int64_t count) { - insert_edges(std::vector < T >(edges, edges + count)); - } - - template - void insert_edges(const std::vector < T > &edges) { - for (const auto edge : edges) { - graph_add_edge(edge); - } - } - - private: - template < typename T > - void - graph_add_edge(const T &edge) { - bool inserted; - typename Pgr_base_graph< G, T_V, T_E >::E e; - if ((edge.cost < 0) && (edge.reverse_cost < 0)) - return; - - /* - * true: for source - * false: for target - */ - auto vm_s = Pgr_base_graph< G, T_V, T_E >::get_V(T_V(edge, true)); - auto vm_t = Pgr_base_graph< G, T_V, T_E >::get_V(T_V(edge, false)); - - pgassert((Pgr_base_graph< G, T_V, T_E >::vertices_map).find(edge.source) - != - (Pgr_base_graph< G, T_V, T_E >::vertices_map).end()); - pgassert((Pgr_base_graph< G, T_V, T_E >::vertices_map).find(edge.target) - != - (Pgr_base_graph< G, T_V, T_E >::vertices_map).end()); - if (edge.cost >= 0) { - boost::tie(e, inserted) = - boost::add_edge(vm_s, vm_t, graph); - graph[e].cost = edge.cost; - graph[e].id = edge.id; - } else if (edge.reverse_cost >= 0) { - boost::tie(e, inserted) = - boost::add_edge(vm_t, vm_s, graph); - graph[e].cost = edge.reverse_cost; - graph[e].id = edge.id; - } - } -}; - -} // namespace graph -} // namespace pgrouting - -#endif // INCLUDE_COMPONENTS_PGR_COMPONENTSGRAPH_HPP_ diff --git a/include/cpp_common/pgr_topological_sort_t.h b/include/cpp_common/pgr_topological_sort_t.h new file mode 100644 index 0000000000..8dc420fcbf --- /dev/null +++ b/include/cpp_common/pgr_topological_sort_t.h @@ -0,0 +1,42 @@ +/*PGR-GNU***************************************************************** +File: pgr_topological_sort_t.h + +Copyright (c) 2015 Aditya Pratap Singh +Mail: adityapratap.singh28@gmail.com + +Function's developer: +Copyright (c) 2019 Hang Wu +mail: nike0good@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*/ +/*! @file */ + +#ifndef INCLUDE_C_TYPES_PGR_TOPOLOGICAL_SORT_T_H_ +#define INCLUDE_C_TYPES_PGR_TOPOLOGICAL_SORT_T_H_ +#pragma once + +/* for int64_t */ +#ifdef __cplusplus +# include +#else +# include +#endif + +typedef struct { + int seq; + int sorted_v; +} pgr_topological_sort_t; + +#endif // INCLUDE_C_TYPES_PGR_STOERWAGNER_T_H_ diff --git a/include/drivers/components/articulationPoints_driver.h b/include/drivers/components/articulationPoints_driver.h index 154254017f..0bfccd5d38 100644 --- a/include/drivers/components/articulationPoints_driver.h +++ b/include/drivers/components/articulationPoints_driver.h @@ -56,7 +56,7 @@ extern "C" { do_pgr_articulationPoints( pgr_edge_t *data_edges, size_t total_edges, - pgr_components_rt **return_tuples, + int64_t **return_tuples, size_t *return_count, char ** log_msg, char ** notice_msg, diff --git a/include/drivers/components/bridges_driver.h b/include/drivers/components/bridges_driver.h index 55f7cdead2..2a2aaa8836 100644 --- a/include/drivers/components/bridges_driver.h +++ b/include/drivers/components/bridges_driver.h @@ -56,7 +56,7 @@ extern "C" { do_pgr_bridges( pgr_edge_t *data_edges, size_t total_edges, - pgr_components_rt **return_tuples, + int64_t **return_tuples, size_t *return_count, char ** log_msg, char ** notice_msg, diff --git a/include/drivers/topological_sort/topological_sort_driver.h b/include/drivers/topological_sort/topological_sort_driver.h new file mode 100644 index 0000000000..91424eb7d4 --- /dev/null +++ b/include/drivers/topological_sort/topological_sort_driver.h @@ -0,0 +1,65 @@ +/*PGR-GNU***************************************************************** + +File: topological_sort_driver.h + +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2019 Hang Wu +mail: nike0good@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_TOPOLOGICAL_SORT_TOPOLOGICAL_SORT_DRIVER_H_ +#define INCLUDE_DRIVERS_TOPOLOGICAL_SORT_TOPOLOGICAL_SORT_DRIVER_H_ + +/* for size-t */ +#ifdef __cplusplus +# include +#else +# include +#endif + +#include "c_types/pgr_edge_t.h" +#include "c_types/pgr_topological_sort_t.h" + +#ifdef __cplusplus +extern "C" { +#endif + + // CREATE OR REPLACE FUNCTION pgr_topological_sort( + // sql text, + void do_pgr_topological_sort( + pgr_edge_t *data_edges, + size_t total_tuples, + + pgr_topological_sort_t **return_tuples, + size_t *return_count, + + char** log_msg, + char** notice_msg, + char** err_msg); + +#ifdef __cplusplus + } +#endif + +#endif // INCLUDE_DRIVERS_TOPOLOGICAL_SORT_DRIVER_H_ diff --git a/sql/components/CMakeLists.txt b/sql/components/CMakeLists.txt index 58962f769a..0219d4518a 100644 --- a/sql/components/CMakeLists.txt +++ b/sql/components/CMakeLists.txt @@ -1,9 +1,14 @@ SET(LOCAL_FILES + _connectedComponents.sql connectedComponents.sql + _strongComponents.sql strongComponents.sql + _biconnectedComponents.sql biconnectedComponents.sql + _articulationPoints.sql articulationPoints.sql + _bridges.sql bridges.sql ) diff --git a/sql/components/_articulationPoints.sql b/sql/components/_articulationPoints.sql new file mode 100644 index 0000000000..b5c633a118 --- /dev/null +++ b/sql/components/_articulationPoints.sql @@ -0,0 +1,47 @@ +/*PGR-GNU***************************************************************** +File: _articulationPoints.sql + +Generated with Template by: +Copyright (c) 2016 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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*/ + +------------------------- +-- pgr_articulationPoints +------------------------- + +CREATE OR REPLACE FUNCTION _pgr_articulationPoints( + edges_sql TEXT, + + OUT seq INTEGER, + OUT node BIGINT) +RETURNS SETOF RECORD AS +'MODULE_PATHNAME', 'articulationPoints' +LANGUAGE c IMMUTABLE STRICT; + + +-- COMMENTS + +COMMENT ON FUNCTION _pgr_articulationPoints(TEXT) +IS 'pgRouting internal function'; diff --git a/sql/components/_biconnectedComponents.sql b/sql/components/_biconnectedComponents.sql new file mode 100644 index 0000000000..259fea6e07 --- /dev/null +++ b/sql/components/_biconnectedComponents.sql @@ -0,0 +1,48 @@ +/*PGR-GNU***************************************************************** +File: _biconnectedComponents.sql + +Generated with Template by: +Copyright (c) 2016 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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*/ + +---------------------------- +-- pgr_biconnectedComponents +---------------------------- + + +CREATE OR REPLACE FUNCTION _pgr_biconnectedComponents( + edges_sql TEXT, + + OUT seq INTEGER, + OUT component BIGINT, + OUT edge BIGINT) +RETURNS SETOF RECORD AS +'MODULE_PATHNAME', 'biconnectedComponents' +LANGUAGE c IMMUTABLE STRICT; + +-- COMMENTS + +COMMENT ON FUNCTION _pgr_biconnectedComponents(TEXT) +IS 'pgRouting internal function'; diff --git a/sql/components/_bridges.sql b/sql/components/_bridges.sql new file mode 100644 index 0000000000..2a8ee8c88e --- /dev/null +++ b/sql/components/_bridges.sql @@ -0,0 +1,46 @@ +/*PGR-GNU***************************************************************** +File: _bridges.sql + +Generated with Template by: +Copyright (c) 2016 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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*/ + +-------------- +-- pgr_bridges +-------------- + +CREATE OR REPLACE FUNCTION _pgr_bridges( + edges_sql TEXT, + + OUT seq INTEGER, + OUT edge BIGINT) +RETURNS SETOF RECORD AS +'MODULE_PATHNAME', 'bridges' +LANGUAGE C IMMUTABLE STRICT; + +-- COMMENTS + +COMMENT ON FUNCTION _pgr_bridges(TEXT) +IS 'pgRouting internal function'; diff --git a/sql/components/_connectedComponents.sql b/sql/components/_connectedComponents.sql new file mode 100644 index 0000000000..968e8e82ff --- /dev/null +++ b/sql/components/_connectedComponents.sql @@ -0,0 +1,54 @@ +/*PGR-GNU***************************************************************** +File: _connectedComponents.sql + +Generated with Template by: +Copyright (c) 2016 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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*/ + +--------------- +--------------- +-- COMPONENTS +--------------- +--------------- + +-------------------------- +-- pgr_connectedComponents +-------------------------- + +CREATE OR REPLACE FUNCTION _pgr_connectedComponents( + edges_sql TEXT, + + OUT seq BIGINT, + OUT component BIGINT, + OUT node BIGINT) + +RETURNS SETOF RECORD AS +'MODULE_PATHNAME', 'connectedComponents' +LANGUAGE c IMMUTABLE STRICT; + +-- COMMENTS + +COMMENT ON FUNCTION _pgr_connectedComponents(TEXT) +IS 'pgRouting internal function'; diff --git a/sql/components/_strongComponents.sql b/sql/components/_strongComponents.sql new file mode 100644 index 0000000000..784d0486e1 --- /dev/null +++ b/sql/components/_strongComponents.sql @@ -0,0 +1,49 @@ +/*PGR-GNU***************************************************************** +File: _strongComponents.sql + +Generated with Template by: +Copyright (c) 2016 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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*/ + +----------------------- +-- pgr_strongComponents +----------------------- + + +CREATE OR REPLACE FUNCTION _pgr_strongComponents( + edges_sql TEXT, + + OUT seq INTEGER, + OUT component BIGINT, + OUT node BIGINT) + +RETURNS SETOF RECORD AS +'MODULE_PATHNAME', 'strongComponents' +LANGUAGE c IMMUTABLE STRICT; + +-- COMMENTS + +COMMENT ON FUNCTION _pgr_strongComponents(TEXT) +IS 'pgRouting internal function'; diff --git a/sql/components/articulationPoints.sql b/sql/components/articulationPoints.sql index e047b6ff0a..ffd8aad0a9 100644 --- a/sql/components/articulationPoints.sql +++ b/sql/components/articulationPoints.sql @@ -27,37 +27,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -------------------------- --- pgr_articulationPoints -------------------------- - -CREATE OR REPLACE FUNCTION _pgr_articulationPoints( - edges_sql TEXT, - - OUT seq INTEGER, - OUT node BIGINT) -RETURNS SETOF RECORD AS -'MODULE_PATHNAME', 'articulationPoints' -LANGUAGE c IMMUTABLE STRICT; - - CREATE OR REPLACE FUNCTION pgr_articulationPoints( TEXT, -- edges_sql (required) - OUT seq INTEGER, OUT node BIGINT) -RETURNS SETOF RECORD AS +RETURNS SETOF BIGINT AS $BODY$ - SELECT * + SELECT node FROM _pgr_articulationPoints(_pgr_get_statement($1)); $BODY$ LANGUAGE SQL VOLATILE STRICT; -- COMMENTS -COMMENT ON FUNCTION _pgr_articulationPoints(TEXT) -IS 'pgRouting internal function'; - COMMENT ON FUNCTION pgr_articulationPoints(TEXT) IS'pgr_articulationPoints - EXPERIMENTAL diff --git a/sql/components/biconnectedComponents.sql b/sql/components/biconnectedComponents.sql index bd0c174dba..e64a578958 100644 --- a/sql/components/biconnectedComponents.sql +++ b/sql/components/biconnectedComponents.sql @@ -27,29 +27,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ ----------------------------- --- pgr_biconnectedComponents ----------------------------- - - -CREATE OR REPLACE FUNCTION _pgr_biconnectedComponents( - edges_sql TEXT, - - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT edge BIGINT) -RETURNS SETOF RECORD AS -'MODULE_PATHNAME', 'biconnectedComponents' -LANGUAGE c IMMUTABLE STRICT; - - CREATE OR REPLACE FUNCTION pgr_biconnectedComponents( TEXT, -- edges_sql (required) OUT seq INTEGER, OUT component BIGINT, - OUT n_seq INTEGER, OUT edge BIGINT) RETURNS SETOF RECORD AS $BODY$ @@ -61,9 +43,6 @@ LANGUAGE SQL VOLATILE STRICT; -- COMMENTS -COMMENT ON FUNCTION _pgr_biconnectedComponents(TEXT) -IS 'pgRouting internal function'; - COMMENT ON FUNCTION pgr_biconnectedComponents(TEXT) IS'pgr_biconnectedComponents - EXPERIMENTAL diff --git a/sql/components/bridges.sql b/sql/components/bridges.sql index 57ee11b5c2..6423185db6 100644 --- a/sql/components/bridges.sql +++ b/sql/components/bridges.sql @@ -27,36 +27,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ --------------- --- pgr_bridges --------------- - -CREATE OR REPLACE FUNCTION _pgr_bridges( - edges_sql TEXT, - - OUT seq INTEGER, - OUT edge BIGINT) -RETURNS SETOF RECORD AS -'MODULE_PATHNAME', 'bridges' -LANGUAGE C IMMUTABLE STRICT; - CREATE OR REPLACE FUNCTION pgr_bridges( TEXT, -- edges_sql (required) - OUT seq INTEGER, OUT edge BIGINT) -RETURNS SETOF RECORD AS +RETURNS SETOF BIGINT AS $BODY$ - SELECT * + SELECT edge FROM _pgr_bridges(_pgr_get_statement($1)); $BODY$ LANGUAGE SQL VOLATILE STRICT; -- COMMENTS -COMMENT ON FUNCTION _pgr_bridges(TEXT) -IS 'pgRouting internal function'; - COMMENT ON FUNCTION pgr_bridges(TEXT) IS'pgr_bridges - EXPERIMENTAL diff --git a/sql/components/connectedComponents.sql b/sql/components/connectedComponents.sql index fdee7937df..4b1419f8e4 100644 --- a/sql/components/connectedComponents.sql +++ b/sql/components/connectedComponents.sql @@ -37,25 +37,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- pgr_connectedComponents -------------------------- -CREATE OR REPLACE FUNCTION _pgr_connectedComponents( - edges_sql TEXT, - - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT node BIGINT) - -RETURNS SETOF RECORD AS -'MODULE_PATHNAME', 'connectedComponents' -LANGUAGE c IMMUTABLE STRICT; - - CREATE OR REPLACE FUNCTION pgr_connectedComponents( TEXT, -- edges_sql (required) - OUT seq INTEGER, + OUT seq BIGINT, OUT component BIGINT, - OUT n_seq INTEGER, OUT node BIGINT) RETURNS SETOF RECORD AS $BODY$ @@ -67,9 +53,6 @@ LANGUAGE SQL VOLATILE STRICT; -- COMMENTS -COMMENT ON FUNCTION _pgr_connectedComponents(TEXT) -IS 'pgRouting internal function'; - COMMENT ON FUNCTION pgr_connectedComponents(TEXT) IS'pgr_connectedComponents - EXPERIMENTAL diff --git a/sql/components/strongComponents.sql b/sql/components/strongComponents.sql index 75ea626598..a776cc6154 100644 --- a/sql/components/strongComponents.sql +++ b/sql/components/strongComponents.sql @@ -27,29 +27,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ ------------------------ --- pgr_strongComponents ------------------------ - - -CREATE OR REPLACE FUNCTION _pgr_strongComponents( - edges_sql TEXT, - - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT node BIGINT) - -RETURNS SETOF RECORD AS -'MODULE_PATHNAME', 'strongComponents' -LANGUAGE c IMMUTABLE STRICT; - CREATE OR REPLACE FUNCTION pgr_strongComponents( TEXT, -- edges_sql (required) OUT seq INTEGER, OUT component BIGINT, - OUT n_seq INTEGER, OUT node BIGINT) RETURNS SETOF RECORD AS $BODY$ @@ -60,10 +42,6 @@ LANGUAGE SQL VOLATILE STRICT; -- COMMENTS -COMMENT ON FUNCTION _pgr_strongComponents(TEXT) -IS 'pgRouting internal function'; - - COMMENT ON FUNCTION pgr_strongComponents(TEXT) IS'pgr_strongComponents - EXPERIMENTAL diff --git a/sql/sigs/pgrouting--3.0.0.sig b/sql/sigs/pgrouting--3.0.0.sig index 6476c01f1a..838849f5ea 100644 --- a/sql/sigs/pgrouting--3.0.0.sig +++ b/sql/sigs/pgrouting--3.0.0.sig @@ -178,6 +178,8 @@ _pgr_stoerwagner(text) pgr_stoerwagner(text) _pgr_strongcomponents(text) pgr_strongcomponents(text) +_pgr_topological_sort(text) +pgr_topological_sort(text) _pgr_trsp(text,integer,double precision,integer,double precision,boolean,boolean,text) pgr_trsp(text,integer,double precision,integer,double precision,boolean,boolean,text) pgr_trsp(text,integer,integer,boolean,boolean,text) diff --git a/sql/topological_sort/CMakeLists.txt b/sql/topological_sort/CMakeLists.txt new file mode 100644 index 0000000000..e668f6a5f0 --- /dev/null +++ b/sql/topological_sort/CMakeLists.txt @@ -0,0 +1,12 @@ + +SET(LOCAL_FILES + _topological_sort.sql + topological_sort.sql + ) + +foreach (f ${LOCAL_FILES}) + configure_file(${f} ${f}) + list(APPEND PACKAGE_SQL_FILES ${CMAKE_CURRENT_BINARY_DIR}/${f}) +endforeach() + +set(PGROUTING_SQL_FILES ${PGROUTING_SQL_FILES} ${PACKAGE_SQL_FILES} PARENT_SCOPE) diff --git a/sql/topological_sort/_topological_sort.sql b/sql/topological_sort/_topological_sort.sql new file mode 100644 index 0000000000..6188fddf45 --- /dev/null +++ b/sql/topological_sort/_topological_sort.sql @@ -0,0 +1,45 @@ +/*PGR-GNU***************************************************************** + +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Copyright (c) 2019 Hang Wu +mail: nike0good@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*/ + +--------------- +--------------- +-- topological_sort +--------------- +--------------- + +CREATE OR REPLACE FUNCTION _pgr_topological_sort( + edges_sql TEXT, + + OUT seq INTEGER, + OUT sorted_v INTEGER) +RETURNS SETOF RECORD AS +'MODULE_PATHNAME', 'topological_sort' +LANGUAGE C VOLATILE STRICT; + +-- COMMENTS + +COMMENT ON FUNCTION _pgr_topological_sort(TEXT) +IS 'pgRouting internal function'; diff --git a/sql/topological_sort/topological_sort.sql b/sql/topological_sort/topological_sort.sql new file mode 100644 index 0000000000..8398e60505 --- /dev/null +++ b/sql/topological_sort/topological_sort.sql @@ -0,0 +1,56 @@ +/*PGR-GNU***************************************************************** + +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Copyright (c) 2019 Hang Wu +mail: nike0good@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*/ + +--------------- +-- pgr_topological_sort +--------------- + +CREATE OR REPLACE FUNCTION pgr_topological_sort( + TEXT, -- edges_sql (required) + + OUT seq INTEGER, + OUT sorted_v INTEGER) +RETURNS SETOF RECORD AS +$BODY$ + SELECT a.seq, a.sorted_v + FROM _pgr_topological_sort(_pgr_get_statement($1)) AS a; +$BODY$ +LANGUAGE sql VOLATILE STRICT +COST 100 +ROWS 1000; + + +-- COMMENTS + +COMMENT ON FUNCTION pgr_topological_sort(TEXT) +IS 'pgr_topological_sort +- Parameters: + - Edges SQL with columns: id, source, target, cost [,reverse_cost] +- Documentation: + - ${PGROUTING_DOC_LINK}/pgr_topological_sort.html +'; + + diff --git a/src/components/CMakeLists.txt b/src/components/CMakeLists.txt index b6d7b31af1..48d0d7084d 100644 --- a/src/components/CMakeLists.txt +++ b/src/components/CMakeLists.txt @@ -5,6 +5,8 @@ ADD_LIBRARY(components OBJECT articulationPoints.c bridges.c + componentsResult.cpp + pgr_components.cpp connectedComponents_driver.cpp strongComponents_driver.cpp biconnectedComponents_driver.cpp diff --git a/src/components/articulationPoints.c b/src/components/articulationPoints.c index d5c57e7e9f..55149390e9 100644 --- a/src/components/articulationPoints.c +++ b/src/components/articulationPoints.c @@ -28,70 +28,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -/** @file articulationPoints.c - * @brief Connecting code with postgres. - * - * This file is fully documented for understanding - * how the postgres connectinon works - * - * TODO Remove unnecessary comments before submiting the function. - * some comments are in form of PGR_DBG message - */ - -/** - * postgres_connection.h - * - * - should always be first in the C code - */ +/** @file articulationPoints.c */ + #include #include "c_common/postgres_connection.h" -/* for macro PGR_DBG */ #include "c_common/debug_macro.h" -/* for pgr_global_report */ #include "c_common/e_report.h" -/* for time_msg & clock */ #include "c_common/time_msg.h" -/* for functions to get edges information */ #include "c_common/edges_input.h" -#include "drivers/components/articulationPoints_driver.h" // the link to the C++ code of the function +#include "drivers/components/articulationPoints_driver.h" PGDLLEXPORT Datum articulationPoints(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(articulationPoints); -/******************************************************************************/ -/* MODIFY AS NEEDED */ static void process( char* edges_sql, - pgr_components_rt **result_tuples, + int64_t **result_tuples, size_t *result_count) { - /* - * https://www.postgresql.org/docs/current/static/spi-spi-connect.html - */ pgr_SPI_connect(); (*result_tuples) = NULL; (*result_count) = 0; - PGR_DBG("Load data"); pgr_edge_t *edges = NULL; size_t total_edges = 0; pgr_get_edges(edges_sql, &edges, &total_edges); - PGR_DBG("Total %ld edges in query:", total_edges); if (total_edges == 0) { - PGR_DBG("No edges found"); pgr_SPI_finish(); return; } - PGR_DBG("Starting processing"); clock_t start_t = clock(); char *log_msg = NULL; char *notice_msg = NULL; @@ -99,14 +73,6 @@ process( do_pgr_articulationPoints( edges, total_edges, -#if 0 - /* - * handling arrays example - */ - - start_vidsArr, size_start_vidsArr, - end_vidsArr, size_end_vidsArr, -#endif result_tuples, result_count, @@ -115,7 +81,6 @@ process( &err_msg); time_msg(" processing pgr_articulationPoints", start_t, clock()); - PGR_DBG("Returning %ld tuples", *result_count); if (err_msg) { if (*result_tuples) pfree(*result_tuples); @@ -126,31 +91,16 @@ process( if (log_msg) pfree(log_msg); if (notice_msg) pfree(notice_msg); if (err_msg) pfree(err_msg); -#if 0 - /* - * handling arrays example - */ - - if (end_vidsArr) pfree(end_vidsArr); - if (start_vidsArr) pfree(start_vidsArr); -#endif pgr_SPI_finish(); } -/* */ -/******************************************************************************/ PGDLLEXPORT Datum articulationPoints(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - /**************************************************************************/ - /* MODIFY AS NEEDED */ - /* */ - pgr_components_rt *result_tuples = NULL; + int64_t *result_tuples = NULL; size_t result_count = 0; - /* */ - /**************************************************************************/ if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; @@ -158,31 +108,11 @@ PGDLLEXPORT Datum articulationPoints(PG_FUNCTION_ARGS) { oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - TEXT, - BIGINT, - BIGINT, - **********************************************************************/ - - - PGR_DBG("Calling process"); process( text_to_cstring(PG_GETARG_TEXT_P(0)), -#if 0 - /* - * handling arrays example - */ - - PG_GETARG_ARRAYTYPE_P(1), - PG_GETARG_ARRAYTYPE_P(2), -#endif &result_tuples, &result_count); - /* */ - /**********************************************************************/ #if PGSQL_VERSION > 94 funcctx->max_calls = (uint32_t)result_count; @@ -204,7 +134,7 @@ PGDLLEXPORT Datum articulationPoints(PG_FUNCTION_ARGS) { funcctx = SRF_PERCALL_SETUP(); tuple_desc = funcctx->tuple_desc; - result_tuples = (pgr_components_rt*) funcctx->user_fctx; + result_tuples = (int64_t*) funcctx->user_fctx; if (funcctx->call_cntr < funcctx->max_calls) { HeapTuple tuple; @@ -212,14 +142,6 @@ PGDLLEXPORT Datum articulationPoints(PG_FUNCTION_ARGS) { Datum *values; bool* nulls; - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT node BIGINT - ***********************************************************************/ values = palloc(2 * sizeof(Datum)); nulls = palloc(2 * sizeof(bool)); @@ -230,23 +152,13 @@ PGDLLEXPORT Datum articulationPoints(PG_FUNCTION_ARGS) { nulls[i] = false; } - // postgres starts counting from 1 values[0] = Int32GetDatum(funcctx->call_cntr + 1); - values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); - /**********************************************************************/ + 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 { - /**********************************************************************/ - /* MODIFY AS NEEDED */ - - PGR_DBG("Clean up code"); - - /**********************************************************************/ - SRF_RETURN_DONE(funcctx); } } - diff --git a/src/components/articulationPoints_driver.cpp b/src/components/articulationPoints_driver.cpp index eb03192c81..e9cb9a9a83 100644 --- a/src/components/articulationPoints_driver.cpp +++ b/src/components/articulationPoints_driver.cpp @@ -37,32 +37,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" - - - - - -/************************************************************ - TEXT, - BIGINT, - BIGINT, - ***********************************************************/ - -template < class G > -static -std::vector -pgr_articulationPoints( - G &graph) { - Pgr_components< G > fn_components; - return fn_components.articulationPoints(graph); -} +#include "cpp_common/pgr_base_graph.hpp" void do_pgr_articulationPoints( pgr_edge_t *data_edges, size_t total_edges, - pgr_components_rt **return_tuples, + int64_t **return_tuples, size_t *return_count, char ** log_msg, char ** notice_msg, @@ -80,13 +62,10 @@ do_pgr_articulationPoints( graphType gType = UNDIRECTED; - std::vector results; - log << "Working with Undirected Graph\n"; - pgrouting::ComponentsUndiGraph undigraph(gType); + pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); - results = pgr_articulationPoints( - undigraph); + auto results(pgrouting::algorithms::articulationPoints(undigraph)); auto count = results.size(); @@ -99,9 +78,12 @@ do_pgr_articulationPoints( } (*return_tuples) = pgr_alloc(count, (*return_tuples)); - for (size_t i = 0; i < count; i++) { - *((*return_tuples) + i) = results[i]; + size_t i = 0; + for (const auto vertex : results) { + *((*return_tuples) + i) = vertex; + ++i; } + (*return_count) = count; pgassert(*err_msg == NULL); diff --git a/src/components/biconnectedComponents.c b/src/components/biconnectedComponents.c index 3baadb8369..be5555196a 100644 --- a/src/components/biconnectedComponents.c +++ b/src/components/biconnectedComponents.c @@ -28,70 +28,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -/** @file biconnectedComponents.c - * @brief Connecting code with postgres. - * - * This file is fully documented for understanding - * how the postgres connectinon works - * - * TODO Remove unnecessary comments before submiting the function. - * some comments are in form of PGR_DBG message - */ - -/** - * postgres_connection.h - * - * - should always be first in the C code - */ +/** @file biconnectedComponents.c */ + #include #include "c_common/postgres_connection.h" -/* for macro PGR_DBG */ #include "c_common/debug_macro.h" -/* for pgr_global_report */ #include "c_common/e_report.h" -/* for time_msg & clock */ #include "c_common/time_msg.h" -/* for functions to get edges information */ #include "c_common/edges_input.h" -#include "drivers/components/biconnectedComponents_driver.h" // the link to the C++ code of the function +#include "drivers/components/biconnectedComponents_driver.h" PGDLLEXPORT Datum biconnectedComponents(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(biconnectedComponents); -/******************************************************************************/ -/* MODIFY AS NEEDED */ static void process( char* edges_sql, pgr_components_rt **result_tuples, size_t *result_count) { - /* - * https://www.postgresql.org/docs/current/static/spi-spi-connect.html - */ pgr_SPI_connect(); (*result_tuples) = NULL; (*result_count) = 0; - PGR_DBG("Load data"); pgr_edge_t *edges = NULL; size_t total_edges = 0; pgr_get_edges(edges_sql, &edges, &total_edges); - PGR_DBG("Total %ld edges in query:", total_edges); if (total_edges == 0) { - PGR_DBG("No edges found"); pgr_SPI_finish(); return; } - PGR_DBG("Starting processing"); clock_t start_t = clock(); char *log_msg = NULL; char *notice_msg = NULL; @@ -99,14 +73,6 @@ process( do_pgr_biconnectedComponents( edges, total_edges, -#if 0 - /* - * handling arrays example - */ - - start_vidsArr, size_start_vidsArr, - end_vidsArr, size_end_vidsArr, -#endif result_tuples, result_count, @@ -115,7 +81,6 @@ process( &err_msg); time_msg(" processing pgr_biconnectedComponents", start_t, clock()); - PGR_DBG("Returning %ld tuples", *result_count); if (err_msg) { if (*result_tuples) pfree(*result_tuples); @@ -126,31 +91,16 @@ process( if (log_msg) pfree(log_msg); if (notice_msg) pfree(notice_msg); if (err_msg) pfree(err_msg); -#if 0 - /* - * handling arrays example - */ - - if (end_vidsArr) pfree(end_vidsArr); - if (start_vidsArr) pfree(start_vidsArr); -#endif pgr_SPI_finish(); } -/* */ -/******************************************************************************/ PGDLLEXPORT Datum biconnectedComponents(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - /**************************************************************************/ - /* MODIFY AS NEEDED */ - /* */ pgr_components_rt *result_tuples = NULL; size_t result_count = 0; - /* */ - /**************************************************************************/ if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; @@ -158,31 +108,11 @@ PGDLLEXPORT Datum biconnectedComponents(PG_FUNCTION_ARGS) { oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - TEXT, - BIGINT, - BIGINT, - **********************************************************************/ - - - PGR_DBG("Calling process"); process( text_to_cstring(PG_GETARG_TEXT_P(0)), -#if 0 - /* - * handling arrays example - */ - - PG_GETARG_ARRAYTYPE_P(1), - PG_GETARG_ARRAYTYPE_P(2), -#endif &result_tuples, &result_count); - /* */ - /**********************************************************************/ #if PGSQL_VERSION > 94 funcctx->max_calls = (uint32_t)result_count; @@ -212,42 +142,23 @@ PGDLLEXPORT Datum biconnectedComponents(PG_FUNCTION_ARGS) { Datum *values; bool* nulls; - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT node BIGINT - ***********************************************************************/ - - values = palloc(6 * sizeof(Datum)); - nulls = palloc(6 * sizeof(bool)); - + size_t numb = 3; + values = palloc(numb * sizeof(Datum)); + nulls = palloc(numb * sizeof(bool)); size_t i; - for (i = 0; i < 6; ++i) { + for (i = 0; i < numb; ++i) { nulls[i] = false; } - // postgres starts counting from 1 - values[0] = Int32GetDatum(funcctx->call_cntr + 1); + values[0] = Int64GetDatum(funcctx->call_cntr + 1); values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].component); - values[2] = Int32GetDatum(result_tuples[funcctx->call_cntr].n_seq); - values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); - /**********************************************************************/ + values[2] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, result); } else { - /**********************************************************************/ - /* MODIFY AS NEEDED */ - - PGR_DBG("Clean up code"); - - /**********************************************************************/ - SRF_RETURN_DONE(funcctx); } } diff --git a/src/components/biconnectedComponents_driver.cpp b/src/components/biconnectedComponents_driver.cpp index f3cf8ab8dd..1541759b8f 100644 --- a/src/components/biconnectedComponents_driver.cpp +++ b/src/components/biconnectedComponents_driver.cpp @@ -38,24 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" - - - - -/************************************************************ - TEXT, - BIGINT, - BIGINT, - ***********************************************************/ - -template < class G > -static -std::vector -pgr_biconnectedComponents( - G &graph) { - Pgr_components< G > fn_components; - return fn_components.biconnectedComponents(graph); -} +#include "cpp_common/pgr_base_graph.hpp" void @@ -78,15 +61,12 @@ do_pgr_biconnectedComponents( pgassert(*return_count == 0); pgassert(total_edges != 0); - graphType gType = DIRECTED; - - std::vector results; + graphType gType = UNDIRECTED; log << "Working with Undirected Graph\n"; - pgrouting::ComponentsUndiGraph undigraph(gType); + pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); - results = pgr_biconnectedComponents( - undigraph); + auto results(pgrouting::algorithms::biconnectedComponents(undigraph)); auto count = results.size(); diff --git a/src/components/bridges.c b/src/components/bridges.c index 8a21288ad5..0cbdfc68a2 100644 --- a/src/components/bridges.c +++ b/src/components/bridges.c @@ -28,70 +28,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -/** @file bridges.c - * @brief Connecting code with postgres. - * - * This file is fully documented for understanding - * how the postgres connectinon works - * - * TODO Remove unnecessary comments before submiting the function. - * some comments are in form of PGR_DBG message - */ - -/** - * postgres_connection.h - * - * - should always be first in the C code - */ +/** @file bridges.c */ + #include #include "c_common/postgres_connection.h" -/* for macro PGR_DBG */ #include "c_common/debug_macro.h" -/* for pgr_global_report */ #include "c_common/e_report.h" -/* for time_msg & clock */ #include "c_common/time_msg.h" -/* for functions to get edges information */ #include "c_common/edges_input.h" -#include "drivers/components/bridges_driver.h" // the link to the C++ code of the function +#include "drivers/components/bridges_driver.h" PGDLLEXPORT Datum bridges(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(bridges); -/******************************************************************************/ -/* MODIFY AS NEEDED */ static void process( char* edges_sql, - pgr_components_rt **result_tuples, + int64_t **result_tuples, size_t *result_count) { - /* - * https://www.postgresql.org/docs/current/static/spi-spi-connect.html - */ pgr_SPI_connect(); (*result_tuples) = NULL; (*result_count) = 0; - PGR_DBG("Load data"); pgr_edge_t *edges = NULL; size_t total_edges = 0; pgr_get_edges(edges_sql, &edges, &total_edges); - PGR_DBG("Total %ld edges in query:", total_edges); if (total_edges == 0) { - PGR_DBG("No edges found"); pgr_SPI_finish(); return; } - PGR_DBG("Starting processing"); clock_t start_t = clock(); char *log_msg = NULL; char *notice_msg = NULL; @@ -99,14 +73,6 @@ process( do_pgr_bridges( edges, total_edges, -#if 0 - /* - * handling arrays example - */ - - start_vidsArr, size_start_vidsArr, - end_vidsArr, size_end_vidsArr, -#endif result_tuples, result_count, @@ -115,7 +81,6 @@ process( &err_msg); time_msg(" processing pgr_bridges", start_t, clock()); - PGR_DBG("Returning %ld tuples", *result_count); if (err_msg) { if (*result_tuples) pfree(*result_tuples); @@ -126,63 +91,27 @@ process( if (log_msg) pfree(log_msg); if (notice_msg) pfree(notice_msg); if (err_msg) pfree(err_msg); -#if 0 - /* - * handling arrays example - */ - - if (end_vidsArr) pfree(end_vidsArr); - if (start_vidsArr) pfree(start_vidsArr); -#endif pgr_SPI_finish(); } -/* */ -/******************************************************************************/ PGDLLEXPORT Datum bridges(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - /**************************************************************************/ - /* MODIFY AS NEEDED */ - /* */ - pgr_components_rt *result_tuples = NULL; + 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); - - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - TEXT, - BIGINT, - BIGINT, - **********************************************************************/ - - - PGR_DBG("Calling process"); process( text_to_cstring(PG_GETARG_TEXT_P(0)), -#if 0 - /* - * handling arrays example - */ - - PG_GETARG_ARRAYTYPE_P(1), - PG_GETARG_ARRAYTYPE_P(2), -#endif &result_tuples, &result_count); - /* */ - /**********************************************************************/ #if PGSQL_VERSION > 94 funcctx->max_calls = (uint32_t)result_count; @@ -204,7 +133,7 @@ PGDLLEXPORT Datum bridges(PG_FUNCTION_ARGS) { funcctx = SRF_PERCALL_SETUP(); tuple_desc = funcctx->tuple_desc; - result_tuples = (pgr_components_rt*) funcctx->user_fctx; + result_tuples = (int64_t*) funcctx->user_fctx; if (funcctx->call_cntr < funcctx->max_calls) { HeapTuple tuple; @@ -212,14 +141,6 @@ PGDLLEXPORT Datum bridges(PG_FUNCTION_ARGS) { Datum *values; bool* nulls; - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT node BIGINT - ***********************************************************************/ values = palloc(2 * sizeof(Datum)); nulls = palloc(2 * sizeof(bool)); @@ -230,22 +151,13 @@ PGDLLEXPORT Datum bridges(PG_FUNCTION_ARGS) { nulls[i] = false; } - // postgres starts counting from 1 values[0] = Int32GetDatum(funcctx->call_cntr + 1); - values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); - /*********************************************************************/ + 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 { - /**********************************************************************/ - /* MODIFY AS NEEDED */ - - PGR_DBG("Clean up code"); - - /**********************************************************************/ - SRF_RETURN_DONE(funcctx); } } diff --git a/src/components/bridges_driver.cpp b/src/components/bridges_driver.cpp index 88dcba128d..8847cd5a47 100644 --- a/src/components/bridges_driver.cpp +++ b/src/components/bridges_driver.cpp @@ -37,32 +37,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" - - - - - -/************************************************************ - TEXT, - BIGINT, - BIGINT, - ***********************************************************/ - -template < class G > -static -std::vector -pgr_bridges( - G &graph) { - Pgr_components< G > fn_components; - return fn_components.bridges(graph); -} +#include "cpp_common/pgr_base_graph.hpp" void do_pgr_bridges( pgr_edge_t *data_edges, size_t total_edges, - pgr_components_rt **return_tuples, + int64_t **return_tuples, size_t *return_count, char ** log_msg, char ** notice_msg, @@ -80,13 +62,11 @@ do_pgr_bridges( graphType gType = UNDIRECTED; - std::vector results; log << "Working with Undirected Graph\n"; - pgrouting::ComponentsUndiGraph undigraph(gType); + pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); - results = pgr_bridges( - undigraph); + auto results = pgrouting::algorithms::bridges(undigraph); auto count = results.size(); @@ -99,8 +79,10 @@ do_pgr_bridges( } (*return_tuples) = pgr_alloc(count, (*return_tuples)); - for (size_t i = 0; i < count; i++) { - *((*return_tuples) + i) = results[i]; + size_t i = 0; + for (const auto edge : results) { + *((*return_tuples) + i) = edge; + ++i; } (*return_count) = count; diff --git a/src/components/componentsResult.cpp b/src/components/componentsResult.cpp new file mode 100644 index 0000000000..521a2c511b --- /dev/null +++ b/src/components/componentsResult.cpp @@ -0,0 +1,60 @@ +/*PGR-GNU***************************************************************** + +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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 "components/componentsResult.h" + +#include +#include + +namespace pgrouting { +namespace algorithms { + +namespace detail { + +std::vector +componentsResult( + std::vector< std::vector< int64_t > > &components) { + // sort identifier + for (auto &component : components) { + std::sort(component.begin(), component.end()); + } + sort(components.begin(), components.end()); + + // generate results + std::vector< pgr_components_rt > results; + for (const auto component : components) { + auto component_id = component[0]; + for (const auto element : component) { + results.push_back({component_id, element}); + } + } + return results; +} + +} // namespace detail + +} // namespace algorithms +} // namespace pgrouting diff --git a/src/components/connectedComponents.c b/src/components/connectedComponents.c index 5876fb073b..b8bf69ba35 100644 --- a/src/components/connectedComponents.c +++ b/src/components/connectedComponents.c @@ -28,70 +28,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -/** @file connectedComponents.c - * @brief Connecting code with postgres. - * - * This file is fully documented for understanding - * how the postgres connectinon works - * - * TODO Remove unnecessary comments before submiting the function. - * some comments are in form of PGR_DBG message - */ - -/** - * postgres_connection.h - * - * - should always be first in the C code - */ +/** @file connectedComponents.c */ + #include #include "c_common/postgres_connection.h" -/* for macro PGR_DBG */ #include "c_common/debug_macro.h" -/* for pgr_global_report */ #include "c_common/e_report.h" -/* for time_msg & clock */ #include "c_common/time_msg.h" -/* for functions to get edges information */ #include "c_common/edges_input.h" -#include "drivers/components/connectedComponents_driver.h" // the link to the C++ code of the function +#include "drivers/components/connectedComponents_driver.h" PGDLLEXPORT Datum connectedComponents(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(connectedComponents); -/******************************************************************************/ -/* MODIFY AS NEEDED */ static void process( char* edges_sql, pgr_components_rt **result_tuples, size_t *result_count) { - /* - * https://www.postgresql.org/docs/current/static/spi-spi-connect.html - */ pgr_SPI_connect(); (*result_tuples) = NULL; (*result_count) = 0; - PGR_DBG("Load data"); pgr_edge_t *edges = NULL; size_t total_edges = 0; pgr_get_edges(edges_sql, &edges, &total_edges); - PGR_DBG("Total %ld edges in query:", total_edges); if (total_edges == 0) { - PGR_DBG("No edges found"); pgr_SPI_finish(); return; } - PGR_DBG("Starting processing"); clock_t start_t = clock(); char *log_msg = NULL; char *notice_msg = NULL; @@ -99,14 +73,6 @@ process( do_pgr_connectedComponents( edges, total_edges, -#if 0 - /* - * handling arrays example - */ - - start_vidsArr, size_start_vidsArr, - end_vidsArr, size_end_vidsArr, -#endif result_tuples, result_count, @@ -115,7 +81,6 @@ process( &err_msg); time_msg(" processing pgr_connectedComponents", start_t, clock()); - PGR_DBG("Returning %ld tuples", *result_count); if (err_msg) { if (*result_tuples) pfree(*result_tuples); @@ -126,31 +91,16 @@ process( if (log_msg) pfree(log_msg); if (notice_msg) pfree(notice_msg); if (err_msg) pfree(err_msg); -#if 0 - /* - * handling arrays example - */ - - if (end_vidsArr) pfree(end_vidsArr); - if (start_vidsArr) pfree(start_vidsArr); -#endif pgr_SPI_finish(); } -/* */ -/******************************************************************************/ PGDLLEXPORT Datum connectedComponents(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - /**************************************************************************/ - /* MODIFY AS NEEDED */ - /* */ pgr_components_rt *result_tuples = NULL; size_t result_count = 0; - /* */ - /**************************************************************************/ if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; @@ -158,31 +108,11 @@ PGDLLEXPORT Datum connectedComponents(PG_FUNCTION_ARGS) { oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - TEXT, - BIGINT, - BIGINT, - **********************************************************************/ - - - PGR_DBG("Calling process"); process( text_to_cstring(PG_GETARG_TEXT_P(0)), -#if 0 - /* - * handling arrays example - */ - - PG_GETARG_ARRAYTYPE_P(1), - PG_GETARG_ARRAYTYPE_P(2), -#endif &result_tuples, &result_count); - /* */ - /**********************************************************************/ #if PGSQL_VERSION > 94 funcctx->max_calls = (uint32_t)result_count; @@ -212,42 +142,24 @@ PGDLLEXPORT Datum connectedComponents(PG_FUNCTION_ARGS) { Datum *values; bool* nulls; - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT node BIGINT - ***********************************************************************/ - - values = palloc(6 * sizeof(Datum)); - nulls = palloc(6 * sizeof(bool)); + size_t numb = 3; + values = palloc(numb * sizeof(Datum)); + nulls = palloc(numb * sizeof(bool)); size_t i; - for (i = 0; i < 6; ++i) { + for (i = 0; i < numb; ++i) { nulls[i] = false; } - // postgres starts counting from 1 - values[0] = Int32GetDatum(funcctx->call_cntr + 1); + values[0] = Int64GetDatum(funcctx->call_cntr + 1); values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].component); - values[2] = Int32GetDatum(result_tuples[funcctx->call_cntr].n_seq); - values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); - /**********************************************************************/ + values[2] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, result); } else { - /**********************************************************************/ - /* MODIFY AS NEEDED */ - - PGR_DBG("Clean up code"); - - /**********************************************************************/ - SRF_RETURN_DONE(funcctx); } } diff --git a/src/components/connectedComponents_driver.cpp b/src/components/connectedComponents_driver.cpp index 9b8188588d..f0032b92f7 100644 --- a/src/components/connectedComponents_driver.cpp +++ b/src/components/connectedComponents_driver.cpp @@ -33,31 +33,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include -#include "components/pgr_components.hpp" #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" +#include "cpp_common/pgr_base_graph.hpp" +#include "components/pgr_components.hpp" -/************************************************************ - TEXT, - BIGINT, - BIGINT, - ***********************************************************/ - -template < class G > -static -std::vector -pgr_connectedComponents( - G &graph) { - Pgr_components< G > fn_components; - return fn_components.connectedComponents(graph); -} - - void do_pgr_connectedComponents( pgr_edge_t *data_edges, @@ -80,13 +65,10 @@ do_pgr_connectedComponents( graphType gType = UNDIRECTED; - std::vector results; - log << "Working with Undirected Graph\n"; - pgrouting::ComponentsUndiGraph undigraph(gType); + pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); - results = pgr_connectedComponents( - undigraph); + auto results(pgrouting::algorithms::pgr_connectedComponents(undigraph)); auto count = results.size(); diff --git a/src/components/pgr_components.cpp b/src/components/pgr_components.cpp new file mode 100644 index 0000000000..8b9da7c0b9 --- /dev/null +++ b/src/components/pgr_components.cpp @@ -0,0 +1,246 @@ +/*PGR-GNU***************************************************************** + +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Copyright (c) 2017 Maoguang Wang +Mail: xjtumg1007@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 "components/pgr_components.hpp" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "cpp_common/identifiers.hpp" + +namespace pgrouting { +namespace algorithms { + +std::vector +pgr_connectedComponents(pgrouting::UndirectedGraph &graph) { + // perform the algorithm + std::vector< int > components(num_vertices(graph.graph)); + size_t num_comps; + try { + num_comps = boost::connected_components(graph.graph, &components[0]); + } catch (...) { + throw; + } + + // get the results + std::vector< std::vector< int64_t > > results(num_comps); + for (auto vd : boost::make_iterator_range(vertices(graph.graph))) { + results[components[vd]].push_back(graph[vd].id); + } + + return detail::componentsResult(results); +} + +//! Strongly Connected Components Vertex Version +std::vector +strongComponents( + pgrouting::DirectedGraph &graph) { + // perform the algorithm + std::vector< int > components(num_vertices(graph.graph)); + size_t num_comps; + try { + num_comps = boost::strong_components( + graph.graph, + boost::make_iterator_property_map(components.begin(), + get(boost::vertex_index, graph.graph))); + } catch (...) { + throw; + } + + // get the results + std::vector< std::vector< int64_t > > results(num_comps); + for (auto vd : boost::make_iterator_range(vertices(graph.graph))) { + results[components[vd]].push_back(graph[vd].id); + } + + return detail::componentsResult(results); +} + + + +//! Biconnected Components +std::vector +biconnectedComponents( + pgrouting::UndirectedGraph &graph) { + using G = pgrouting::UndirectedGraph; + using E = G::E; + using Edge_map = std::map< E, size_t >; + + // perform the algorithm + Edge_map bicmp_map; + boost::associative_property_map bimap(bicmp_map); + size_t num_comps; + try { + num_comps = biconnected_components(graph.graph, bimap); + } catch (...) { + throw; + } + + std::vector< std::vector< int64_t > > results(num_comps); + for (auto ed : boost::make_iterator_range(edges(graph.graph))) { + results[bimap[ed]].push_back(graph[ed].id); + } + + return detail::componentsResult(results); +} + +Identifiers +articulationPoints( + pgrouting::UndirectedGraph &graph) { + using G = pgrouting::UndirectedGraph; + using V = G::V; + + // perform the algorithm + std::vector art_points; + try { + boost::articulation_points(graph.graph, std::back_inserter(art_points)); + } catch (...) { + throw; + } + + // get the results + Identifiers results; + for (const auto v : art_points) { + results += graph[v].id; + } + + return results; +} + +/** Bridges + * Bridges are closely related to the concept of articulation vertices, + * vertices that belong to every path between some pair of other vertices. + * + * The two endpoints of a bridge are articulation vertices unless + * they have a degree of 1, although it may also be possible for a non-bridge + * edge to have two articulation vertices as endpoints. + * + * Analogously to bridgeless graphs being 2-edge-connected, + * graphs without articulation vertices are 2-vertex-connected. + */ +Identifiers +bridges(pgrouting::UndirectedGraph &graph) { + using G = pgrouting::UndirectedGraph; + using V = G::V; + using EO_i = G::EO_i; + + Identifiers bridge_edges; + Identifiers processed_edges; + std::vector results; + std::vector components(num_vertices(graph.graph)); + size_t ini_comps; + try { + ini_comps = boost::connected_components(graph.graph, &components[0]); + } catch (...) { + throw; + } + + std::vector art_points; + try { + boost::articulation_points(graph.graph, std::back_inserter(art_points)); + } catch (...) { + throw; + } + + for (auto v : boost::make_iterator_range(vertices(graph.graph))) { + if (graph.out_degree(v) == 1) { + art_points.push_back(v); + } + } + + for (const auto u : art_points) { + for (const auto v : art_points) { + /* + * skip when the vertices are the same and do half the work + */ + if (u < v) continue; + auto p = boost::edge(u, v, graph.graph); + + /* + * skip when there is no edge (u, v) on the graph + */ + if (!p.second) continue; + auto edge = p.first; + auto id = graph[edge].id; + + /* + * Skip when the edge has already being processed + */ + if (processed_edges.has(id)) continue; + + /* + * Processing edge + */ + processed_edges += id; + + + /* + * At least one edge between articulation points u & v + */ + int parallel_count = 0; + EO_i ei, ei_end; + boost::tie(ei, ei_end) = out_edges(u, graph.graph); + + for ( ; ei != ei_end; ++ei) { + if (target(*ei, graph.graph) == v) ++parallel_count; + }; + + if (parallel_count == 1) { + // TODO filter graph instead of removing edges + size_t now_comps; + try { + boost::remove_edge(edge, graph.graph); + + now_comps = boost::connected_components(graph.graph, &components[0]); + + boost::add_edge(boost::source(edge, graph.graph), + boost::target(edge, graph.graph), + graph.graph); + } catch (...) { + throw; + } + + if (now_comps > ini_comps) { + bridge_edges += id; + } + + } + } + } + + return bridge_edges; +} + +} // namespace algorithms +} // namespace pgrouting diff --git a/src/components/strongComponents.c b/src/components/strongComponents.c index 34f32f4875..3a9792af31 100644 --- a/src/components/strongComponents.c +++ b/src/components/strongComponents.c @@ -28,70 +28,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -/** @file strongComponents.c - * @brief Connecting code with postgres. - * - * This file is fully documented for understanding - * how the postgres connectinon works - * - * TODO Remove unnecessary comments before submiting the function. - * some comments are in form of PGR_DBG message - */ - -/** - * postgres_connection.h - * - * - should always be first in the C code - */ +/** @file strongComponents.c */ + #include #include "c_common/postgres_connection.h" -/* for macro PGR_DBG */ #include "c_common/debug_macro.h" -/* for pgr_global_report */ #include "c_common/e_report.h" -/* for time_msg & clock */ #include "c_common/time_msg.h" -/* for functions to get edges information */ #include "c_common/edges_input.h" -#include "drivers/components/strongComponents_driver.h" // the link to the C++ code of the function +#include "drivers/components/strongComponents_driver.h" PGDLLEXPORT Datum strongComponents(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(strongComponents); -/******************************************************************************/ -/* MODIFY AS NEEDED */ static void process( char* edges_sql, pgr_components_rt **result_tuples, size_t *result_count) { - /* - * https://www.postgresql.org/docs/current/static/spi-spi-connect.html - */ pgr_SPI_connect(); (*result_tuples) = NULL; (*result_count) = 0; - PGR_DBG("Load data"); pgr_edge_t *edges = NULL; size_t total_edges = 0; pgr_get_edges(edges_sql, &edges, &total_edges); - PGR_DBG("Total %ld edges in query:", total_edges); if (total_edges == 0) { - PGR_DBG("No edges found"); pgr_SPI_finish(); return; } - PGR_DBG("Starting processing"); clock_t start_t = clock(); char *log_msg = NULL; char *notice_msg = NULL; @@ -99,14 +73,6 @@ process( do_pgr_strongComponents( edges, total_edges, -#if 0 - /* - * handling arrays example - */ - - start_vidsArr, size_start_vidsArr, - end_vidsArr, size_end_vidsArr, -#endif result_tuples, result_count, @@ -115,7 +81,6 @@ process( &err_msg); time_msg(" processing pgr_strongComponents", start_t, clock()); - PGR_DBG("Returning %ld tuples", *result_count); if (err_msg) { if (*result_tuples) pfree(*result_tuples); @@ -126,31 +91,16 @@ process( if (log_msg) pfree(log_msg); if (notice_msg) pfree(notice_msg); if (err_msg) pfree(err_msg); -#if 0 - /* - * handling arrays example - */ - - if (end_vidsArr) pfree(end_vidsArr); - if (start_vidsArr) pfree(start_vidsArr); -#endif pgr_SPI_finish(); } -/* */ -/******************************************************************************/ PGDLLEXPORT Datum strongComponents(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - /**************************************************************************/ - /* MODIFY AS NEEDED */ - /* */ pgr_components_rt *result_tuples = NULL; size_t result_count = 0; - /* */ - /**************************************************************************/ if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; @@ -158,31 +108,11 @@ PGDLLEXPORT Datum strongComponents(PG_FUNCTION_ARGS) { oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - TEXT, - BIGINT, - BIGINT, - **********************************************************************/ - - - PGR_DBG("Calling process"); process( text_to_cstring(PG_GETARG_TEXT_P(0)), -#if 0 - /* - * handling arrays example - */ - - PG_GETARG_ARRAYTYPE_P(1), - PG_GETARG_ARRAYTYPE_P(2), -#endif &result_tuples, &result_count); - /* */ - /**********************************************************************/ #if PGSQL_VERSION > 94 funcctx->max_calls = (uint32_t)result_count; @@ -212,42 +142,23 @@ PGDLLEXPORT Datum strongComponents(PG_FUNCTION_ARGS) { Datum *values; bool* nulls; - /**********************************************************************/ - /* MODIFY AS NEEDED */ - /* - OUT seq INTEGER, - OUT component BIGINT, - OUT n_seq INTEGER, - OUT node BIGINT - ***********************************************************************/ - - values = palloc(6 * sizeof(Datum)); - nulls = palloc(6 * sizeof(bool)); - + size_t numb = 3; + values = palloc(numb * sizeof(Datum)); + nulls = palloc(numb * sizeof(bool)); size_t i; - for (i = 0; i < 6; ++i) { + for (i = 0; i < numb; ++i) { nulls[i] = false; } - // postgres starts counting from 1 - values[0] = Int32GetDatum(funcctx->call_cntr + 1); + values[0] = Int64GetDatum(funcctx->call_cntr + 1); values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].component); - values[2] = Int32GetDatum(result_tuples[funcctx->call_cntr].n_seq); - values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); - /**********************************************************************/ + values[2] = Int64GetDatum(result_tuples[funcctx->call_cntr].identifier); tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, result); } else { - /**********************************************************************/ - /* MODIFY AS NEEDED */ - - PGR_DBG("Clean up code"); - - /**********************************************************************/ - SRF_RETURN_DONE(funcctx); } } diff --git a/src/components/strongComponents_driver.cpp b/src/components/strongComponents_driver.cpp index 9ea2b66ac6..95c42926f1 100644 --- a/src/components/strongComponents_driver.cpp +++ b/src/components/strongComponents_driver.cpp @@ -33,29 +33,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include -#include "components/pgr_components.hpp" #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" +#include "cpp_common/pgr_base_graph.hpp" - - - - -/************************************************************ - TEXT, - BIGINT, - BIGINT, - ***********************************************************/ - -template < class G > -static -std::vector -pgr_strongComponents( - G &graph) { - Pgr_components< G > fn_components; - return fn_components.strongComponents(graph); -} +#include "components/pgr_components.hpp" void @@ -80,13 +63,9 @@ do_pgr_strongComponents( graphType gType = DIRECTED; - std::vector results; - - log << "Working with Directed Graph\n"; pgrouting::DirectedGraph digraph(gType); digraph.insert_edges(data_edges, total_edges); - results = pgr_strongComponents( - digraph); + auto results(pgrouting::algorithms::strongComponents(digraph)); auto count = results.size(); @@ -94,7 +73,7 @@ do_pgr_strongComponents( (*return_tuples) = NULL; (*return_count) = 0; notice << - "No paths found between start_vid and end_vid vertices"; + "No components found"; return; } diff --git a/src/topological_sort/CMakeLists.txt b/src/topological_sort/CMakeLists.txt new file mode 100644 index 0000000000..0f273c8b85 --- /dev/null +++ b/src/topological_sort/CMakeLists.txt @@ -0,0 +1,4 @@ +ADD_LIBRARY(topological_sort OBJECT + topological_sort.c + + topological_sort_driver.cpp) diff --git a/src/topological_sort/topological_sort.c b/src/topological_sort/topological_sort.c new file mode 100644 index 0000000000..fa13e3045b --- /dev/null +++ b/src/topological_sort/topological_sort.c @@ -0,0 +1,175 @@ +/*PGR-GNU***************************************************************** + +File: many_to_many_dijkstra.c + +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2019 Hang Wu +mail: nike0good@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 "utils/array.h" + + +#include "c_common/debug_macro.h" +#include "c_common/e_report.h" +#include "c_common/time_msg.h" +#include "c_common/edges_input.h" +#include "c_common/arrays_input.h" +#include "drivers/topological_sort/topological_sort_driver.h" +#if 0 +PG_MODULE_MAGIC; +#endif +PGDLLEXPORT Datum topological_sort(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(topological_sort); + +static +void +process( + char* edges_sql, + pgr_topological_sort_t **result_tuples, + size_t *result_count) { + pgr_SPI_connect(); + + pgr_edge_t *edges = NULL; + size_t total_edges = 0; + pgr_get_edges(edges_sql, &edges, &total_edges); + + PGR_DBG("Starting timer"); + clock_t start_t = clock(); + char* log_msg = NULL; + char* notice_msg = NULL; + char* err_msg = NULL; + do_pgr_topological_sort( + edges, total_edges, + + result_tuples, + result_count, + + &log_msg, + ¬ice_msg, + &err_msg); + + time_msg("processing pgr_topological_sort", start_t, clock()); + + + if (err_msg && (*result_tuples)) { + pfree(*result_tuples); + (*result_tuples) = NULL; + (*result_count) = 0; + } + + pgr_global_report(log_msg, notice_msg, err_msg); + + if (log_msg) pfree(log_msg); + if (notice_msg) pfree(notice_msg); + if (err_msg) pfree(err_msg); + if (edges) pfree(edges); + pgr_SPI_finish(); +} + +PGDLLEXPORT Datum +topological_sort(PG_FUNCTION_ARGS) { + FuncCallContext *funcctx; + TupleDesc tuple_desc; + + /**********************************************************************/ + pgr_topological_sort_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_topological_sort( + // sql TEXT, + + process( + text_to_cstring(PG_GETARG_TEXT_P(0)), + &result_tuples, + &result_count); + + /**********************************************************************/ + +#if PGSQL_VERSION > 95 + funcctx->max_calls = result_count; +#else + funcctx->max_calls = (uint32_t)result_count; +#endif + + 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 = (pgr_topological_sort_t*) funcctx->user_fctx; + + if (funcctx->call_cntr < funcctx->max_calls) { + HeapTuple tuple; + Datum result; + Datum *values; + bool* nulls; + size_t call_cntr = funcctx->call_cntr; + + /**********************************************************************/ + // OUT seq INTEGER, + // OUT sorted_v INTEGER) + + size_t numb = 2; + values = palloc(numb * sizeof(Datum)); + nulls = palloc(numb * sizeof(bool)); + + size_t i; + for (i = 0; i < numb; ++i) { + nulls[i] = false; + } + + values[0] = Int32GetDatum(call_cntr + 1); + values[1] = Int32GetDatum(result_tuples[call_cntr].sorted_v); + /**********************************************************************/ + + 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/topological_sort/topological_sort_driver.cpp b/src/topological_sort/topological_sort_driver.cpp new file mode 100644 index 0000000000..7dc1a9b927 --- /dev/null +++ b/src/topological_sort/topological_sort_driver.cpp @@ -0,0 +1,141 @@ +/*PGR-GNU***************************************************************** +File: topological_sort_driver.cpp + +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2019 Hang Wu +mail: nike0good@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/topological_sort/topological_sort_driver.h" + +#include +#include +#include +#include +#include + +#if 0 +#include "topological_sort/pgr_topological_sort.hpp" +#endif +//TODO(nike0good) : Remove below headers once pgr_topological_sort.hpp is implemented. +#include "cpp_common/basePath_SSEC.hpp" +#include "cpp_common/pgr_base_graph.hpp" +//TODO(nike0good) : Complete file once pgr_topological_sort.hpp is implemented. + +#include "cpp_common/pgr_alloc.hpp" +#include "cpp_common/pgr_assert.h" + +template < class G > +static +std::vector +pgr_topological_sort( + G &graph) { +#if 0 + Pgr_topological_sort< G > fn_topological_sort; + return fn_topological_sort.topological_sort(graph); +#endif + std::vector vv; + return vv; +} + + + +// CREATE OR REPLACE FUNCTION pgr_topological_sort( +// sql text, +void +do_pgr_topological_sort( + pgr_edge_t *data_edges, + size_t total_edges, + + + pgr_topological_sort_t **return_tuples, + size_t *return_count, + char ** log_msg, + char ** notice_msg, + char ** err_msg) { + std::ostringstream log; + std::ostringstream err; + std::ostringstream notice; + + try { + pgassert(total_edges != 0); + pgassert(!(*log_msg)); + pgassert(!(*notice_msg)); + pgassert(!(*err_msg)); + pgassert(!(*return_tuples)); + pgassert(*return_count == 0); + + graphType gType = DIRECTED; + + std::vector results; + + log << "Working with Directed Graph\n"; + pgrouting::DirectedGraph digraph(gType); + digraph.insert_edges(data_edges, total_edges); + results = pgr_topological_sort( + digraph); + + auto count = results.size(); + + if (count == 0) { + (*return_tuples) = NULL; + (*return_count) = 0; + notice << + "No vertices"; + 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 = log.str().empty()? + *log_msg : + pgr_msg(log.str().c_str()); + *notice_msg = notice.str().empty()? + *notice_msg : + pgr_msg(notice.str().c_str()); + } catch (AssertFailedException &except) { + (*return_tuples) = pgr_free(*return_tuples); + (*return_count) = 0; + err << except.what(); + *err_msg = pgr_msg(err.str().c_str()); + *log_msg = pgr_msg(log.str().c_str()); + } catch (std::exception &except) { + (*return_tuples) = pgr_free(*return_tuples); + (*return_count) = 0; + err << except.what(); + *err_msg = pgr_msg(err.str().c_str()); + *log_msg = pgr_msg(log.str().c_str()); + } catch(...) { + (*return_tuples) = pgr_free(*return_tuples); + (*return_count) = 0; + err << "Caught unknown exception!"; + *err_msg = pgr_msg(err.str().c_str()); + *log_msg = pgr_msg(log.str().c_str()); + } +} diff --git a/test/components/doc-pgr_articulationPoints.result b/test/components/doc-pgr_articulationPoints.result index 1e8a60f785..ed43a5b439 100644 --- a/test/components/doc-pgr_articulationPoints.result +++ b/test/components/doc-pgr_articulationPoints.result @@ -6,24 +6,24 @@ SET SELECT * FROM pgr_articulationPoints( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | node ------+------ - 1 | 2 - 2 | 5 - 3 | 8 - 4 | 10 + node +------ + 2 + 5 + 8 + 10 (4 rows) -- q2 SELECT * FROM pgr_articulationPoints( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | node ------+------ - 1 | 2 - 2 | 5 - 3 | 8 - 4 | 10 + node +------ + 2 + 5 + 8 + 10 (4 rows) ROLLBACK; diff --git a/test/components/doc-pgr_biconnectedComponents.result b/test/components/doc-pgr_biconnectedComponents.result index 183b2e7179..73b2dcc9e4 100644 --- a/test/components/doc-pgr_biconnectedComponents.result +++ b/test/components/doc-pgr_biconnectedComponents.result @@ -6,52 +6,52 @@ SET SELECT * FROM pgr_biconnectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | edge ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 2 | 1 | 2 - 3 | 2 | 2 | 3 - 4 | 2 | 3 | 4 - 5 | 2 | 4 | 5 - 6 | 2 | 5 | 8 - 7 | 2 | 6 | 9 - 8 | 2 | 7 | 10 - 9 | 2 | 8 | 11 - 10 | 2 | 9 | 12 - 11 | 2 | 10 | 13 - 12 | 2 | 11 | 15 - 13 | 2 | 12 | 16 - 14 | 6 | 1 | 6 - 15 | 7 | 1 | 7 - 16 | 14 | 1 | 14 - 17 | 17 | 1 | 17 - 18 | 18 | 1 | 18 + seq | component | edge +-----+-----------+------ + 1 | 1 | 1 + 2 | 2 | 2 + 3 | 2 | 3 + 4 | 2 | 4 + 5 | 2 | 5 + 6 | 2 | 8 + 7 | 2 | 9 + 8 | 2 | 10 + 9 | 2 | 11 + 10 | 2 | 12 + 11 | 2 | 13 + 12 | 2 | 15 + 13 | 2 | 16 + 14 | 6 | 6 + 15 | 7 | 7 + 16 | 14 | 14 + 17 | 17 | 17 + 18 | 18 | 18 (18 rows) -- q2 SELECT * FROM pgr_biconnectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | edge ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 2 | 1 | 2 - 3 | 2 | 2 | 3 - 4 | 2 | 3 | 4 - 5 | 2 | 4 | 5 - 6 | 2 | 5 | 8 - 7 | 2 | 6 | 9 - 8 | 2 | 7 | 10 - 9 | 2 | 8 | 11 - 10 | 2 | 9 | 12 - 11 | 2 | 10 | 13 - 12 | 2 | 11 | 15 - 13 | 2 | 12 | 16 - 14 | 6 | 1 | 6 - 15 | 7 | 1 | 7 - 16 | 14 | 1 | 14 - 17 | 17 | 1 | 17 - 18 | 18 | 1 | 18 + seq | component | edge +-----+-----------+------ + 1 | 1 | 1 + 2 | 2 | 2 + 3 | 2 | 3 + 4 | 2 | 4 + 5 | 2 | 5 + 6 | 2 | 8 + 7 | 2 | 9 + 8 | 2 | 10 + 9 | 2 | 11 + 10 | 2 | 12 + 11 | 2 | 13 + 12 | 2 | 15 + 13 | 2 | 16 + 14 | 6 | 6 + 15 | 7 | 7 + 16 | 14 | 14 + 17 | 17 | 17 + 18 | 18 | 18 (18 rows) ROLLBACK; diff --git a/test/components/doc-pgr_bridges.result b/test/components/doc-pgr_bridges.result index fd7b907b8a..6e5ce6ec7b 100644 --- a/test/components/doc-pgr_bridges.result +++ b/test/components/doc-pgr_bridges.result @@ -6,28 +6,28 @@ SET SELECT * FROM pgr_bridges( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | edge ------+------ - 1 | 1 - 2 | 6 - 3 | 7 - 4 | 14 - 5 | 17 - 6 | 18 + edge +------ + 1 + 6 + 7 + 14 + 17 + 18 (6 rows) -- q2 SELECT * FROM pgr_bridges( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | edge ------+------ - 1 | 1 - 2 | 6 - 3 | 7 - 4 | 14 - 5 | 17 - 6 | 18 + edge +------ + 1 + 6 + 7 + 14 + 17 + 18 (6 rows) ROLLBACK; diff --git a/test/components/doc-pgr_connectedComponents.result b/test/components/doc-pgr_connectedComponents.result index 3636e0a7f5..d17c8afff3 100644 --- a/test/components/doc-pgr_connectedComponents.result +++ b/test/components/doc-pgr_connectedComponents.result @@ -6,50 +6,50 @@ SET SELECT * FROM pgr_connectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) -- q2 SELECT * FROM pgr_connectedComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) ROLLBACK; diff --git a/test/components/doc-pgr_strongComponents.result b/test/components/doc-pgr_strongComponents.result index a78b576613..1a6a230d50 100644 --- a/test/components/doc-pgr_strongComponents.result +++ b/test/components/doc-pgr_strongComponents.result @@ -6,50 +6,50 @@ SET SELECT * FROM pgr_strongComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) -- q2 SELECT * FROM pgr_strongComponents( 'SELECT id, source, target, cost, reverse_cost FROM edge_table' ); - seq | component | n_seq | node ------+-----------+-------+------ - 1 | 1 | 1 | 1 - 2 | 1 | 2 | 2 - 3 | 1 | 3 | 3 - 4 | 1 | 4 | 4 - 5 | 1 | 5 | 5 - 6 | 1 | 6 | 6 - 7 | 1 | 7 | 7 - 8 | 1 | 8 | 8 - 9 | 1 | 9 | 9 - 10 | 1 | 10 | 10 - 11 | 1 | 11 | 11 - 12 | 1 | 12 | 12 - 13 | 1 | 13 | 13 - 14 | 14 | 1 | 14 - 15 | 14 | 2 | 15 - 16 | 16 | 1 | 16 - 17 | 16 | 2 | 17 + seq | component | node +-----+-----------+------ + 1 | 1 | 1 + 2 | 1 | 2 + 3 | 1 | 3 + 4 | 1 | 4 + 5 | 1 | 5 + 6 | 1 | 6 + 7 | 1 | 7 + 8 | 1 | 8 + 9 | 1 | 9 + 10 | 1 | 10 + 11 | 1 | 11 + 12 | 1 | 12 + 13 | 1 | 13 + 14 | 14 | 14 + 15 | 14 | 15 + 16 | 16 | 16 + 17 | 16 | 17 (17 rows) ROLLBACK;