GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
articulation_point.c
Go to the documentation of this file.
1/*!
2 \file vector/neta/articulation_point.c
3
4 \brief Network Analysis library - connected components
5
6 Computes network articulation points.
7
8 SPDX-FileCopyrightText: 2009-2010 Daniel Bundala
9 SPDX-FileCopyrightText: GRASS Development Team
10 SPDX-License-Identifier: GPL-2.0-or-later
11
12 \author Daniel Bundala (Google Summer of Code 2009)
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <grass/gis.h>
18#include <grass/vector.h>
19#include <grass/glocale.h>
20#include <grass/dgl/graph.h>
21
22/*!
23 \brief Get number of articulation points in the graph
24
25 \param graph input graph
26 \param[out] articulation_list list of articulation points
27
28 \return number of points
29 \return -1 on error
30 */
32{
33 int nnodes;
34 int points = 0;
35
37 *current; /*edge to be processed when the node is visited */
38 int *tin, *min_tin; /*time in, and smallest tin over all successors. 0 if
39 not yet visited */
40 dglInt32_t **parent; /*parents of the nodes */
41 dglInt32_t **stack; /*stack of nodes */
42 dglInt32_t **current_edge; /*current edge for each node */
43 int *mark; /*marked articulation points */
46 int stack_size;
47 int i, time;
48
50 current = (dglEdgesetTraverser_s *)G_calloc(nnodes + 1,
51 sizeof(dglEdgesetTraverser_s));
52 tin = (int *)G_calloc(nnodes + 1, sizeof(int));
53 min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
54 parent = (dglInt32_t **)G_calloc(nnodes + 1, sizeof(dglInt32_t *));
55 stack = (dglInt32_t **)G_calloc(nnodes + 1, sizeof(dglInt32_t *));
56 current_edge = (dglInt32_t **)G_calloc(nnodes + 1, sizeof(dglInt32_t *));
57 mark = (int *)G_calloc(nnodes + 1, sizeof(int));
58 if (!tin || !min_tin || !parent || !stack || !current || !mark) {
59 G_fatal_error(_("Out of memory"));
60 return -1;
61 }
62
63 for (i = 1; i <= nnodes; i++) {
65 &current[i], graph,
67 current_edge[i] = dglEdgeset_T_First(&current[i]);
68 tin[i] = mark[i] = 0;
69 }
70
72
73 time = 0;
77
78 if (tin[current_id] == 0) {
79 int children =
80 0; /*number of subtrees rooted at the root/current_node */
81
83 stack_size = 1;
84 parent[current_id] = NULL;
85 while (stack_size) {
86 dglInt32_t *node = stack[stack_size - 1];
88
89 if (tin[node_id] == 0) /*vertex visited for the first time */
91 else { /*return from the recursion */
94 if (min_tin[to] >=
95 tin[node_id]) /*no path from the subtree above the
96 current node */
97 mark[node_id] = 1; /*so the current node must be an
98 articulation point */
99
100 if (min_tin[to] < min_tin[node_id])
101 min_tin[node_id] = min_tin[to];
103 &current[node_id]); /*proceed to the next edge */
104 }
105 /*try next edges */
106 for (; current_edge[node_id];
108 dglEdgeset_T_Next(&current[node_id])) {
109 dglInt32_t *to =
111 if (to == parent[node_id])
112 continue; /*skip parent */
113 int to_id = dglNodeGet_Id(graph, to);
114
115 if (tin[to_id]) { /*back edge, cannot be a
116 bridge/articualtion point */
117 if (tin[to_id] < min_tin[node_id])
119 }
120 else { /*forward edge */
121 if (node_id == current_id)
122 children++; /*if root, increase number of children
123 */
124 parent[to_id] = node;
125 stack[stack_size++] = to;
126 break;
127 }
128 }
129 if (!current_edge[node_id])
130 stack_size--; /*current node completely processed */
131 }
132 if (children > 1)
134 1; /*if the root has more than 1 subtrees rooted at it, then
135 * it is an articulation point */
136 }
137 }
138
139 for (i = 1; i <= nnodes; i++)
140 if (mark[i]) {
141 points++;
143 }
144
146 for (i = 1; i <= nnodes; i++)
147 dglEdgeset_T_Release(&current[i]);
148
149 G_free(current);
150 G_free(tin);
152 G_free(parent);
153 G_free(stack);
155 G_free(mark);
156 return points;
157}
int NetA_articulation_points(dglGraph_s *graph, struct ilist *articulation_list)
Get number of articulation points in the graph.
#define NULL
Definition ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_calloc(m, n)
Definition defs/gis.h:137
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
#define _(str)
Definition glocale.h:10
List of integers.
Definition gis.h:712
long dglInt32_t
Definition type.h:24
dglInt32_t * dglNode_T_Next(dglNodeTraverser_s *pT)
dglInt32_t * dglNode_T_First(dglNodeTraverser_s *pT)
dglInt32_t * dglGetNode(dglGraph_s *pGraph, dglInt32_t nNodeId)
dglInt32_t * dglNodeGet_OutEdgeset(dglGraph_s *pGraph, dglInt32_t *pnNode)
int dglEdgeset_T_Initialize(dglEdgesetTraverser_s *pT, dglGraph_s *pGraph, dglInt32_t *pnEdgeset)
int dglNode_T_Initialize(dglNodeTraverser_s *pT, dglGraph_s *pGraph)
dglInt32_t * dglEdgeset_T_First(dglEdgesetTraverser_s *pT)
dglInt32_t * dglEdgeset_T_Next(dglEdgesetTraverser_s *pT)
int dglGet_NodeCount(dglGraph_s *pgraph)
void dglNode_T_Release(dglNodeTraverser_s *pT)
void dglEdgeset_T_Release(dglEdgesetTraverser_s *pT)
dglInt32_t * dglEdgeGet_Tail(dglGraph_s *pGraph, dglInt32_t *pnEdge)
dglInt32_t dglNodeGet_Id(dglGraph_s *pGraph, dglInt32_t *pnNode)