GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
bridge.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/neta/bridge.c
3
4 \brief Network Analysis library - bridges
5
6 Computes number of bridges in the graph.
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 bridges in the graph.
24
25 Bridge is an array containing the indices of the bridges.
26
27 \param graph input graph
28 \param[out] bridge_list list of bridges
29
30 \return number of bridges, -1 on error
31 */
33{
34 int nnodes;
35 int bridges = 0;
36
38 *current; /*edge to be processed when the node is visited */
39 int *tin, *min_tin; /*time in, and smallest tin over all successors. 0 if
40 not yet visited */
41 dglInt32_t *parent; /*edge from parent to the node */
42 dglInt32_t **stack; /*stack of nodes */
43 dglInt32_t **current_edge; /*current edge for each node */
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 if (!tin || !min_tin || !parent || !stack || !current) {
58 G_fatal_error(_("Out of memory"));
59 return -1;
60 }
61
62 for (i = 1; i <= nnodes; i++) {
64 &current[i], graph,
66 current_edge[i] = dglEdgeset_T_First(&current[i]);
67 tin[i] = 0;
68 }
69
71
72 time = 0;
76
77 if (tin[current_id] == 0) {
79 stack_size = 1;
80 parent[current_id] = 0;
81 while (stack_size) {
82 dglInt32_t *node = stack[stack_size - 1];
84
85 if (tin[node_id] == 0) /*vertex visited for the first time */
87 else { /*return from the recursion */
90 if (min_tin[to] >
91 tin[node_id]) { /*no path from the subtree above the
92 current node */
96 graph, current_edge[node_id])); /*so it must be
97 a bridge */
98 bridges++;
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 for (; current_edge[node_id];
107 &current[node_id])) { /*try next edges */
108 dglInt32_t *to =
112 if (labs(edge_id) == parent[node_id])
113 continue; /*skip edge we used to travel to this node */
114 int to_id = dglNodeGet_Id(graph, to);
115
116 if (tin[to_id]) { /*back edge, cannot be a
117 bridge/articualtion point */
118 if (tin[to_id] < min_tin[node_id])
120 }
121 else { /*forward edge */
122 parent[to_id] = labs(edge_id);
123 stack[stack_size++] = to;
124 break;
125 }
126 }
127 if (!current_edge[node_id])
128 stack_size--; /*current node completely processed */
129 }
130 }
131 }
132
134 for (i = 1; i <= nnodes; i++)
135 dglEdgeset_T_Release(&current[i]);
136
137 G_free(current);
138 G_free(tin);
140 G_free(parent);
141 G_free(stack);
143 return bridges;
144}
int NetA_compute_bridges(dglGraph_s *graph, struct ilist *bridge_list)
Get number of bridges in the graph.
Definition bridge.c: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 dglEdgeGet_Id(dglGraph_s *pGraph, dglInt32_t *pnEdge)
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)