[GRASS-SVN] r37576 - in grass-addons/vector/net.analyze: . netalib
v.net.allpairs v.net.bridge v.net.components v.net.flow
v.net.spanningtree
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu May 28 15:22:23 EDT 2009
Author: wolf
Date: 2009-05-28 15:22:23 -0400 (Thu, 28 May 2009)
New Revision: 37576
Added:
grass-addons/vector/net.analyze/Netalib.make
grass-addons/vector/net.analyze/netalib/allpairs.c
grass-addons/vector/net.analyze/netalib/articulation_point.c
grass-addons/vector/net.analyze/netalib/bridge.c
grass-addons/vector/net.analyze/netalib/components.c
grass-addons/vector/net.analyze/netalib/flow.c
grass-addons/vector/net.analyze/netalib/spanningtree.c
grass-addons/vector/net.analyze/netalib/utils.c
Removed:
grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c
grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c
grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c
grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c
grass-addons/vector/net.analyze/v.net.components/neta_comonents.c
grass-addons/vector/net.analyze/v.net.flow/neta_flow.c
grass-addons/vector/net.analyze/v.net.flow/neta_utils.c
grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c
Modified:
grass-addons/vector/net.analyze/netalib/Makefile
grass-addons/vector/net.analyze/v.net.allpairs/Makefile
grass-addons/vector/net.analyze/v.net.bridge/Makefile
grass-addons/vector/net.analyze/v.net.components/Makefile
grass-addons/vector/net.analyze/v.net.flow/Makefile
grass-addons/vector/net.analyze/v.net.spanningtree/Makefile
Log:
Fixed the makefiles so that netalib is built and used
Added: grass-addons/vector/net.analyze/Netalib.make
===================================================================
--- grass-addons/vector/net.analyze/Netalib.make (rev 0)
+++ grass-addons/vector/net.analyze/Netalib.make 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,4 @@
+# These belong maybe in Grass.make?
+NETA_LIBNAME = grass_neta
+NETALIB = -l$(NETA_LIBNAME)
+NETADEP = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(NETA_LIBNAME)$(LIB_SUFFIX)
Modified: grass-addons/vector/net.analyze/netalib/Makefile
===================================================================
--- grass-addons/vector/net.analyze/netalib/Makefile 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/netalib/Makefile 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,5 +1,7 @@
MODULE_TOPDIR = ../../..
+include ../Netalib.make
+
EXTRA_LIBS = $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
DEPENDENCIES= $(VECTDEP) $(DBMIDEP) $(GISDEP)
EXTRA_INC = $(VECT_INC)
Copied: grass-addons/vector/net.analyze/netalib/allpairs.c (from rev 37571, grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c)
===================================================================
--- grass-addons/vector/net.analyze/netalib/allpairs.c (rev 0)
+++ grass-addons/vector/net.analyze/netalib/allpairs.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,87 @@
+
+/****************************************************************
+ *
+ * MODULE: netalib
+ *
+ * AUTHOR(S): Daniel Bundala
+ *
+ * PURPOSE: Computes the legngth of the shortest path between
+ * all pairs of nodes in the network
+ *
+ * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/*
+ * Upon the completion, dist stores the directed distance between every pair (i,j)
+ * or -1 if the nodes are unreachable. It must be an array of dimension [nodes+1]*[nodes+1]
+ * TODO: use only O(W*W) memory where W is the number of nodes present in the graph
+ */
+int neta_allpairs(dglGraph_s * graph, dglInt32_t ** dist)
+{
+ int nnodes, i, j, k, indices;
+ dglEdgesetTraverser_s et;
+ dglNodeTraverser_s nt;
+ dglInt32_t *node;
+ nnodes = dglGet_NodeCount(graph);
+ dglInt32_t *node_indices;
+ node_indices = (dglInt32_t *) G_calloc(nnodes, sizeof(dglInt32_t));
+ if (!node_indices) {
+ G_fatal_error(_("Out of memory"));
+ return -1;
+ }
+ G_message(_("Computing all pairs shortest paths..."));
+ G_percent_reset();
+ for (i = 0; i <= nnodes; i++)
+ for (j = 0; j <= nnodes; j++)
+ dist[i][j] = -1;
+ dglNode_T_Initialize(&nt, graph);
+ indices = 0;
+ for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
+ dglInt32_t node_id = dglNodeGet_Id(graph, node);
+ node_indices[indices++] = node_id;
+ dglInt32_t *edge;
+ dglEdgeset_T_Initialize(&et, graph, dglNodeGet_OutEdgeset(graph, node));
+ for (edge = dglEdgeset_T_First(&et); edge;
+ edge = dglEdgeset_T_Next(&et))
+ if (dglEdgeGet_Id(graph, edge) < 0) /*ignore backward edges */
+ dist[node_id][dglNodeGet_Id
+ (graph, dglEdgeGet_Tail(graph, edge))] =
+ dglEdgeGet_Cost(graph, edge);
+ dglEdgeset_T_Release(&et);
+ }
+ dglNode_T_Release(&nt);
+ for (k = 0; k < indices; k++) {
+ dglInt32_t k_index = node_indices[k];
+ G_percent(k + 1, indices, 1);
+ for (i = 0; i < indices; i++) {
+ dglInt32_t i_index = node_indices[i];
+ if (dist[i_index][k_index] == -1)
+ continue; /*no reason to proceed along infinite path */
+ for (j = 0; j < indices; j++) {
+ dglInt32_t j_index = node_indices[j];
+ if (dist[k_index][j_index] != -1 &&
+ (dist[i_index][k_index] + dist[k_index][j_index] <
+ dist[i_index][j_index] || dist[i_index][j_index] == -1)) {
+ dist[i_index][j_index] =
+ dist[i_index][k_index] + dist[k_index][j_index];
+ }
+ }
+ }
+ }
+
+ G_free(node_indices);
+ return 0;
+}
Property changes on: grass-addons/vector/net.analyze/netalib/allpairs.c
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mergeinfo
+
Copied: grass-addons/vector/net.analyze/netalib/articulation_point.c (from rev 37571, grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c)
===================================================================
--- grass-addons/vector/net.analyze/netalib/articulation_point.c (rev 0)
+++ grass-addons/vector/net.analyze/netalib/articulation_point.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,139 @@
+
+/****************************************************************
+ *
+ * MODULE: netalib
+ *
+ * AUTHOR(S): Daniel Bundala
+ *
+ * PURPOSE: Computes strongly and weakly connected components
+ *
+ * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/* return the number of articulation points in the graph.
+ */
+int neta_articulation_points(dglGraph_s * graph,
+ struct ilist *articulation_list)
+{
+ int nnodes;
+ int points = 0;
+
+ dglEdgesetTraverser_s *current; /*edge to be processed when the node is visited */
+ int *tin, *min_tin; /*time in, and smallest tin over all successors. 0 if not yet visited */
+ dglInt32_t **parent; /*parents of the nodes */
+ dglInt32_t **stack; /*stack of nodes */
+ dglInt32_t **current_edge; /*current edge for each node */
+ int *mark; /*marked articulation points */
+ dglNodeTraverser_s nt;
+ dglInt32_t *current_node;
+ int stack_size;
+ int i, time;
+ nnodes = dglGet_NodeCount(graph);
+ current =
+ (dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
+ sizeof(dglEdgesetTraverser_s));
+ tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+ min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+ parent = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+ stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+ current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+ mark = (int *)G_calloc(nnodes + 1, sizeof(int));
+ if (!tin || !min_tin || !parent || !stack || !current || !mark) {
+ G_fatal_error(_("Out of memory"));
+ return -1;
+ }
+
+ for (i = 1; i <= nnodes; i++) {
+ dglEdgeset_T_Initialize(¤t[i], graph,
+ dglNodeGet_OutEdgeset(graph,
+ dglGetNode(graph, i)));
+ current_edge[i] = dglEdgeset_T_First(¤t[i]);
+ tin[i] = mark[i] = 0;
+ }
+
+ dglNode_T_Initialize(&nt, graph);
+
+ time = 0;
+ for (current_node = dglNode_T_First(&nt); current_node;
+ current_node = dglNode_T_Next(&nt)) {
+ dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
+ if (tin[current_id] == 0) {
+ int children = 0; /*number of subtrees rooted at the root/current_node */
+ stack[0] = current_node;
+ stack_size = 1;
+ parent[current_id] = NULL;
+ while (stack_size) {
+ dglInt32_t *node = stack[stack_size - 1];
+ dglInt32_t node_id = dglNodeGet_Id(graph, node);
+ if (tin[node_id] == 0) /*vertex visited for the first time */
+ min_tin[node_id] = tin[node_id] = ++time;
+ else { /*return from the recursion */
+ dglInt32_t to = dglNodeGet_Id(graph,
+ dglEdgeGet_Tail(graph,
+ current_edge
+ [node_id]));
+ if (min_tin[to] >= tin[node_id]) /*no path from the subtree above the current node */
+ mark[node_id] = 1; /*so the current node must be an articulation point */
+
+ if (min_tin[to] < min_tin[node_id])
+ min_tin[node_id] = min_tin[to];
+ current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id]); /*proceed to the next edge */
+ }
+ for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id])) { //try next edges
+ dglInt32_t *to =
+ dglEdgeGet_Tail(graph, current_edge[node_id]);
+ if (to == parent[node_id])
+ continue; /*skip parrent */
+ int to_id = dglNodeGet_Id(graph, to);
+ if (tin[to_id]) { /*back edge, cannot be a bridge/articualtion point */
+ if (tin[to_id] < min_tin[node_id])
+ min_tin[node_id] = tin[to_id];
+ }
+ else { /*forward edge */
+ if (node_id == current_id)
+ children++; /*if root, increase number of children */
+ parent[to_id] = node;
+ stack[stack_size++] = to;
+ break;
+ }
+ }
+ if (!current_edge[node_id])
+ stack_size--; /*current node completely processed */
+ }
+ if (children > 1)
+ mark[current_id] = 1; /*if the root has more than 1 subtrees rooted at it, then it is an
+ * articulation point */
+ }
+ }
+
+ for (i = 1; i <= nnodes; i++)
+ if (mark[i]) {
+ points++;
+ Vect_list_append(articulation_list, i);
+ }
+
+ dglNode_T_Release(&nt);
+ for (i = 1; i <= nnodes; i++)
+ dglEdgeset_T_Release(¤t[i]);
+
+ G_free(current);
+ G_free(tin);
+ G_free(min_tin);
+ G_free(parent);
+ G_free(stack);
+ G_free(current_edge);
+ return points;
+}
Property changes on: grass-addons/vector/net.analyze/netalib/articulation_point.c
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mergeinfo
+
Copied: grass-addons/vector/net.analyze/netalib/bridge.c (from rev 37571, grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c)
===================================================================
--- grass-addons/vector/net.analyze/netalib/bridge.c (rev 0)
+++ grass-addons/vector/net.analyze/netalib/bridge.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,128 @@
+
+/****************************************************************
+ *
+ * MODULE: netalib
+ *
+ * AUTHOR(S): Daniel Bundala
+ *
+ * PURPOSE: Computes strongly and weakly connected components
+ *
+ * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/* return the number of bridges in the graph.
+ * bridge is an array containing the indices of the bridges
+ */
+int neta_compute_bridges(dglGraph_s * graph, struct ilist *bridge_list)
+{
+ int nnodes;
+ int bridges = 0;
+
+ dglEdgesetTraverser_s *current; /*edge to be processed when the node is visited */
+ int *tin, *min_tin; /*time in, and smallest tin over all successors. 0 if not yet visited */
+ dglInt32_t *parent; /*edge from parent to the node */
+ dglInt32_t **stack; /*stack of nodes */
+ dglInt32_t **current_edge; /*current edge for each node */
+ dglNodeTraverser_s nt;
+ dglInt32_t *current_node;
+ int stack_size;
+ int i, time;
+ nnodes = dglGet_NodeCount(graph);
+ current =
+ (dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
+ sizeof(dglEdgesetTraverser_s));
+ tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+ min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+ parent = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+ stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+ current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+ if (!tin || !min_tin || !parent || !stack || !current) {
+ G_fatal_error(_("Out of memory"));
+ return -1;
+ }
+
+ for (i = 1; i <= nnodes; i++) {
+ dglEdgeset_T_Initialize(¤t[i], graph,
+ dglNodeGet_OutEdgeset(graph,
+ dglGetNode(graph, i)));
+ current_edge[i] = dglEdgeset_T_First(¤t[i]);
+ tin[i] = 0;
+ }
+
+ dglNode_T_Initialize(&nt, graph);
+
+ time = 0;
+ for (current_node = dglNode_T_First(&nt); current_node;
+ current_node = dglNode_T_Next(&nt)) {
+ dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
+ if (tin[current_id] == 0) {
+ stack[0] = current_node;
+ stack_size = 1;
+ parent[current_id] = 0;
+ while (stack_size) {
+ dglInt32_t *node = stack[stack_size - 1];
+ dglInt32_t node_id = dglNodeGet_Id(graph, node);
+ if (tin[node_id] == 0) /*vertex visited for the first time */
+ min_tin[node_id] = tin[node_id] = ++time;
+ else { /*return from the recursion */
+ dglInt32_t to = dglNodeGet_Id(graph,
+ dglEdgeGet_Tail(graph,
+ current_edge
+ [node_id]));
+ if (min_tin[to] > tin[node_id]) { /*no path from the subtree above the current node */
+ Vect_list_append(bridge_list, dglEdgeGet_Id(graph, current_edge[node_id])); /*so it must be a bridge */
+ bridges++;
+ }
+ if (min_tin[to] < min_tin[node_id])
+ min_tin[node_id] = min_tin[to];
+ current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id]); /*proceed to the next edge */
+ }
+ for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id])) { //try next edges
+ dglInt32_t *to =
+ dglEdgeGet_Tail(graph, current_edge[node_id]);
+ dglInt32_t edge_id =
+ dglEdgeGet_Id(graph, current_edge[node_id]);
+ if (abs(edge_id) == parent[node_id])
+ continue; /*skip edge we used to travel to this node */
+ int to_id = dglNodeGet_Id(graph, to);
+ if (tin[to_id]) { /*back edge, cannot be a bridge/articualtion point */
+ if (tin[to_id] < min_tin[node_id])
+ min_tin[node_id] = tin[to_id];
+ }
+ else { /*forward edge */
+ parent[to_id] = abs(edge_id);
+ stack[stack_size++] = to;
+ break;
+ }
+ }
+ if (!current_edge[node_id])
+ stack_size--; /*current node completely processed */
+ }
+ }
+ }
+
+ dglNode_T_Release(&nt);
+ for (i = 1; i <= nnodes; i++)
+ dglEdgeset_T_Release(¤t[i]);
+
+ G_free(current);
+ G_free(tin);
+ G_free(min_tin);
+ G_free(parent);
+ G_free(stack);
+ G_free(current_edge);
+ return bridges;
+}
Property changes on: grass-addons/vector/net.analyze/netalib/bridge.c
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mergeinfo
+
Copied: grass-addons/vector/net.analyze/netalib/components.c (from rev 37571, grass-addons/vector/net.analyze/v.net.components/neta_comonents.c)
===================================================================
--- grass-addons/vector/net.analyze/netalib/components.c (rev 0)
+++ grass-addons/vector/net.analyze/netalib/components.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,175 @@
+
+/****************************************************************
+ *
+ * MODULE: v.net.components
+ *
+ * AUTHOR(S): Daniel Bundala
+ *
+ * PURPOSE: Computes strongly and weakly connected components
+ *
+ * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+int neta_weakly_connected_components(dglGraph_s * graph, int *component)
+{
+ int nnodes;
+ dglInt32_t *stack;
+ int *visited;
+ int stack_size, components;
+ dglInt32_t *cur_node;
+ dglNodeTraverser_s nt;
+
+ components = 0;
+ nnodes = dglGet_NodeCount(graph);
+ stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+ visited = (int *)G_calloc(nnodes + 1, sizeof(int));
+ if (!stack || !visited) {
+ G_fatal_error(_("Out of memory"));
+ return -1;
+ }
+
+ dglNode_T_Initialize(&nt, graph);
+
+ for (cur_node = dglNode_T_First(&nt); cur_node;
+ cur_node = dglNode_T_Next(&nt)) {
+ dglInt32_t node_id = dglNodeGet_Id(graph, cur_node);
+ if (!visited[node_id]) {
+ visited[node_id] = 1;
+ stack[0] = node_id;
+ stack_size = 1;
+ component[node_id] = ++components;
+ while (stack_size) {
+ dglInt32_t *node, *edgeset, *edge;
+ dglEdgesetTraverser_s et;
+ node = dglGetNode(graph, stack[--stack_size]);
+ edgeset = dglNodeGet_OutEdgeset(graph, node);
+ dglEdgeset_T_Initialize(&et, graph, edgeset);
+ for (edge = dglEdgeset_T_First(&et); edge;
+ edge = dglEdgeset_T_Next(&et)) {
+ dglInt32_t to;
+ to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+ if (!visited[to]) {
+ visited[to] = 1;
+ component[to] = components;
+ stack[stack_size++] = to;
+ }
+ }
+ dglEdgeset_T_Release(&et);
+ }
+ }
+ }
+ dglNode_T_Release(&nt);
+ G_free(visited);
+ return components;
+}
+
+int neta_strongly_connected_components(dglGraph_s * graph, int *component)
+{
+ int nnodes;
+ dglInt32_t *stack, *order;
+ int *visited, *processed;
+ int stack_size, order_size, components;
+ dglInt32_t *node;
+ dglNodeTraverser_s nt;
+
+ components = 0;
+ nnodes = dglGet_NodeCount(graph);
+ stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+ order = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+ visited = (int *)G_calloc(nnodes + 1, sizeof(int));
+ processed = (int *)G_calloc(nnodes + 1, sizeof(int));
+ if (!stack || !visited || !order || !processed) {
+ G_fatal_error(_("Out of memory"));
+ return -1;
+ }
+
+ order_size = 0;
+ dglNode_T_Initialize(&nt, graph);
+
+ for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
+ dglInt32_t node_id = dglNodeGet_Id(graph, node);
+ component[node_id] = 0;
+ if (!visited[node_id]) {
+ visited[node_id] = 1;
+ stack[0] = node_id;
+ stack_size = 1;
+ while (stack_size) {
+ dglInt32_t *node, *edgeset, *edge;
+ dglEdgesetTraverser_s et;
+ dglInt32_t cur_node_id = stack[stack_size - 1];
+ if (processed[cur_node_id]) {
+ stack_size--;
+ order[order_size++] = cur_node_id;
+ continue;
+ }
+ processed[cur_node_id] = 1;
+ node = dglGetNode(graph, cur_node_id);
+ edgeset = dglNodeGet_OutEdgeset(graph, node);
+ dglEdgeset_T_Initialize(&et, graph, edgeset);
+ for (edge = dglEdgeset_T_First(&et); edge;
+ edge = dglEdgeset_T_Next(&et)) {
+ dglInt32_t to;
+ if (dglEdgeGet_Id(graph, edge) < 0)
+ continue; /*ignore backward edges */
+ to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+ if (!visited[to]) {
+ visited[to] = 1;
+ stack[stack_size++] = to;
+ }
+ }
+ dglEdgeset_T_Release(&et);
+ }
+ }
+ }
+
+ dglNode_T_Release(&nt);
+
+ while (order_size) {
+ dglInt32_t node_id = order[--order_size];
+ if (component[node_id])
+ continue;
+ components++;
+ component[node_id] = components;
+ stack[0] = node_id;
+ stack_size = 1;
+ while (stack_size) {
+ dglInt32_t *node, *edgeset, *edge;
+ dglEdgesetTraverser_s et;
+ dglInt32_t cur_node_id = stack[--stack_size];
+ node = dglGetNode(graph, cur_node_id);
+ edgeset = dglNodeGet_OutEdgeset(graph, node);
+ dglEdgeset_T_Initialize(&et, graph, edgeset);
+ for (edge = dglEdgeset_T_First(&et); edge;
+ edge = dglEdgeset_T_Next(&et)) {
+ dglInt32_t to;
+ if (dglEdgeGet_Id(graph, edge) > 0)
+ continue; /*ignore forward edges */
+ to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+ if (!component[to]) {
+ component[to] = components;
+ stack[stack_size++] = to;
+ }
+ }
+ dglEdgeset_T_Release(&et);
+ }
+ }
+
+ G_free(stack);
+ G_free(visited);
+ G_free(order);
+ G_free(processed);
+ return components;
+}
Property changes on: grass-addons/vector/net.analyze/netalib/components.c
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mergeinfo
+
Copied: grass-addons/vector/net.analyze/netalib/flow.c (from rev 37571, grass-addons/vector/net.analyze/v.net.flow/neta_flow.c)
===================================================================
--- grass-addons/vector/net.analyze/netalib/flow.c (rev 0)
+++ grass-addons/vector/net.analyze/netalib/flow.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,123 @@
+
+/****************************************************************
+ *
+ * MODULE: netalib
+ *
+ * AUTHOR(S): Daniel Bundala
+ *
+ * PURPOSE: Computes the legngth of the shortest path between
+ * all pairs of nodes in the network
+ *
+ * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+dglInt32_t sign(dglInt32_t x)
+{
+ if (x >= 0)
+ return 1;
+ return -1;
+}
+
+/*
+ * returns max flow from source to sink. Array flow stores flow for
+ * each edge. Negative flow corresponds to a flow in opposite direction
+ * The function assumes that the edge costs correspond to edge capacities.
+ */
+int neta_flow(dglGraph_s * graph, int source, int sink, int *flow)
+{
+ int nnodes, nlines, i;
+ dglEdgesetTraverser_s et;
+ dglInt32_t *queue;
+ dglInt32_t **prev;
+ int begin, end, total_flow;
+
+ nnodes = dglGet_NodeCount(graph);
+ nlines = dglGet_EdgeCount(graph) / 2; /*each line corresponds to two edges. One in each direction */
+ queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
+ prev = (dglInt32_t **) G_calloc(nnodes + 3, sizeof(dglInt32_t *));
+ if (!queue || !prev) {
+ G_fatal_error(_("Out of memory"));
+ return -1;
+ }
+ for (i = 0; i <= nlines; i++)
+ flow[i] = 0;
+ total_flow = 0;
+ while (1) {
+ dglInt32_t node, edge_id, min_residue;
+ int found = 0;
+ begin = 0;
+ end = 1;
+ queue[0] = source;
+ for (i = 1; i <= nnodes; i++) {
+ prev[i] = NULL;
+ }
+ while (begin != end && !found) {
+ dglInt32_t vertex = queue[begin++];
+ dglInt32_t *edge, *node = dglGetNode(graph, vertex);
+ dglEdgeset_T_Initialize(&et, graph,
+ dglNodeGet_OutEdgeset(graph, node));
+ for (edge = dglEdgeset_T_First(&et); edge;
+ edge = dglEdgeset_T_Next(&et)) {
+ dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
+ dglInt32_t id = dglEdgeGet_Id(graph, edge);
+ dglInt32_t to =
+ dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+ if (to != source && prev[to] == NULL &&
+ cap > sign(id) * flow[abs(id)]) {
+ prev[to] = edge;
+ if (to == sink) {
+ found = 1;
+ break;
+ }
+ queue[end++] = to;
+ }
+ }
+ dglEdgeset_T_Release(&et);
+ }
+ if (!found)
+ break; /*no augmenting path */
+ /*find minimum residual capacity along the augmenting path */
+ node = sink;
+ edge_id = dglEdgeGet_Id(graph, prev[node]);
+ min_residue =
+ dglEdgeGet_Cost(graph,
+ prev[node]) - sign(edge_id) * flow[abs(edge_id)];
+ while (node != source) {
+ dglInt32_t residue;
+ edge_id = dglEdgeGet_Id(graph, prev[node]);
+ residue =
+ dglEdgeGet_Cost(graph,
+ prev[node]) -
+ sign(edge_id) * flow[abs(edge_id)];
+ if (residue < min_residue)
+ min_residue = residue;
+ node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
+ }
+ total_flow += min_residue;
+ /*update flow along the augmenting path */
+ node = sink;
+ while (node != source) {
+ edge_id = dglEdgeGet_Id(graph, prev[node]);
+ flow[abs(edge_id)] += sign(edge_id) * min_residue;
+ node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
+ }
+ }
+
+ G_free(queue);
+ G_free(prev);
+
+ return total_flow;
+}
Property changes on: grass-addons/vector/net.analyze/netalib/flow.c
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mergeinfo
+
Copied: grass-addons/vector/net.analyze/netalib/spanningtree.c (from rev 37571, grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c)
===================================================================
--- grass-addons/vector/net.analyze/netalib/spanningtree.c (rev 0)
+++ grass-addons/vector/net.analyze/netalib/spanningtree.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,133 @@
+
+/****************************************************************
+ *
+ * MODULE: netalib
+ *
+ * AUTHOR(S): Daniel Bundala
+ *
+ * PURPOSE: Computes minimum spanning tree in the network
+ *
+ * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+struct union_find
+{
+ int *parent;
+};
+
+int uf_initialize(struct union_find *uf, int size)
+{
+ int i;
+ uf->parent = (int *)G_calloc(size, sizeof(int));
+ if (!uf->parent)
+ return 0;
+ for (i = 0; i < size; i++)
+ uf->parent[i] = i;
+ return 1;
+}
+
+void uf_release(struct union_find *uf)
+{
+ G_free(uf->parent);
+}
+
+int uf_find(struct union_find *uf, int v)
+{
+ int cur = v, tmp;
+ while (uf->parent[cur] != cur)
+ cur = uf->parent[cur];
+ while (uf->parent[v] != v) {
+ tmp = uf->parent[v];
+ uf->parent[v] = cur;
+ v = tmp;
+ }
+ return cur;
+}
+
+/*TODO: union by rank */
+void uf_union(struct union_find *uf, int u, int v)
+{
+ int parent_u = uf_find(uf, u);
+ int parent_v = uf_find(uf, v);
+ if (parent_u != parent_v)
+ uf->parent[parent_u] = parent_v;
+}
+
+typedef struct
+{
+ dglInt32_t cost;
+ dglInt32_t *edge;
+} edge_cost_pair;
+
+int cmp_edge(const void *pa, const void *pb)
+{
+ return ((edge_cost_pair *) pa)->cost - ((edge_cost_pair *) pb)->cost;
+}
+
+/* return the number of edges in the spanning forest */
+int neta_spanning_tree(dglGraph_s * graph, struct ilist *tree_list)
+{
+ int nnodes, edges, nedges, i, index;
+ edge_cost_pair *perm; /*permutaion of edges in ascending order */
+ struct union_find uf;
+ dglEdgesetTraverser_s et;
+ nnodes = dglGet_NodeCount(graph);
+ nedges = dglGet_EdgeCount(graph);
+ perm = (edge_cost_pair *) G_calloc(nedges, sizeof(edge_cost_pair));
+ if (!perm || !uf_initialize(&uf, nnodes + 1)) {
+ G_fatal_error(_("Out of memory"));
+ return -1;
+ }
+ /*for some obscure reasons, dglGetEdge always returns NULL. Therefore this complicated enumeration of the edges... */
+ index = 0;
+ G_message(_("Computing minimum spanning tree..."));
+ G_percent_reset();
+ for (i = 1; i <= nnodes; i++) {
+ G_percent(i, nnodes + nedges, 1);
+ dglInt32_t *edge;
+ dglEdgeset_T_Initialize(&et, graph,
+ dglNodeGet_OutEdgeset(graph,
+ dglGetNode(graph,
+ (dglInt32_t)
+ i)));
+ for (edge = dglEdgeset_T_First(&et); edge;
+ edge = dglEdgeset_T_Next(&et))
+ if (dglEdgeGet_Id(graph, edge) > 0) {
+ perm[index].edge = edge;
+ perm[index].cost = dglEdgeGet_Cost(graph, edge);
+ index++;
+ }
+
+ dglEdgeset_T_Release(&et);
+ }
+ edges = 0;
+ qsort((void *)perm, index, sizeof(edge_cost_pair), cmp_edge);
+ for (i = 0; i < index; i++) {
+ G_percent(i + nnodes, nnodes + nedges, 1);
+ dglInt32_t head =
+ dglNodeGet_Id(graph, dglEdgeGet_Head(graph, perm[i].edge));
+ dglInt32_t tail =
+ dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, perm[i].edge));
+ if (uf_find(&uf, head) != uf_find(&uf, tail)) {
+ uf_union(&uf, head, tail);
+ edges++;
+ Vect_list_append(tree_list, dglEdgeGet_Id(graph, perm[i].edge));
+ }
+ }
+ G_free(perm);
+ uf_release(&uf);
+ return edges;
+}
Property changes on: grass-addons/vector/net.analyze/netalib/spanningtree.c
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mergeinfo
+
Copied: grass-addons/vector/net.analyze/netalib/utils.c (from rev 37571, grass-addons/vector/net.analyze/v.net.flow/neta_utils.c)
===================================================================
--- grass-addons/vector/net.analyze/netalib/utils.c (rev 0)
+++ grass-addons/vector/net.analyze/netalib/utils.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -0,0 +1,39 @@
+
+/****************************************************************
+ *
+ * MODULE: netalib
+ *
+ * AUTHOR(S): Daniel Bundala
+ *
+ * PURPOSE: netalib utility functions
+ *
+ * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dbmi.h>
+#include <grass/neta.h>
+
+
+void neta_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
+ struct line_cats *Cats)
+{
+ static struct line_pnts *Points;
+ double x, y, z;
+ Points = Vect_new_line_struct();
+ Vect_get_node_coor(In, node, &x, &y, &z);
+ Vect_reset_line(Points);
+ Vect_append_point(Points, x, y, z);
+ Vect_write_line(Out, GV_POINT, Points, Cats);
+ Vect_destroy_line_struct(Points);
+}
Property changes on: grass-addons/vector/net.analyze/netalib/utils.c
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mergeinfo
+
Modified: grass-addons/vector/net.analyze/v.net.allpairs/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.allpairs/Makefile 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.allpairs/Makefile 2009-05-28 19:22:23 UTC (rev 37576)
@@ -2,6 +2,8 @@
PGM=v.net.allpairs
+include ../Netalib.make
+
LIBES = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
EXTRA_INC = $(VECT_INC)
Deleted: grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,87 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: netalib
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: Computes the legngth of the shortest path between
- * all pairs of nodes in the network
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-/*
- * Upon the completion, dist stores the directed distance between every pair (i,j)
- * or -1 if the nodes are unreachable. It must be an array of dimension [nodes+1]*[nodes+1]
- * TODO: use only O(W*W) memory where W is the number of nodes present in the graph
- */
-int neta_allpairs(dglGraph_s * graph, dglInt32_t ** dist)
-{
- int nnodes, i, j, k, indices;
- dglEdgesetTraverser_s et;
- dglNodeTraverser_s nt;
- dglInt32_t *node;
- nnodes = dglGet_NodeCount(graph);
- dglInt32_t *node_indices;
- node_indices = (dglInt32_t *) G_calloc(nnodes, sizeof(dglInt32_t));
- if (!node_indices) {
- G_fatal_error(_("Out of memory"));
- return -1;
- }
- G_message(_("Computing all pairs shortest paths..."));
- G_percent_reset();
- for (i = 0; i <= nnodes; i++)
- for (j = 0; j <= nnodes; j++)
- dist[i][j] = -1;
- dglNode_T_Initialize(&nt, graph);
- indices = 0;
- for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
- dglInt32_t node_id = dglNodeGet_Id(graph, node);
- node_indices[indices++] = node_id;
- dglInt32_t *edge;
- dglEdgeset_T_Initialize(&et, graph, dglNodeGet_OutEdgeset(graph, node));
- for (edge = dglEdgeset_T_First(&et); edge;
- edge = dglEdgeset_T_Next(&et))
- if (dglEdgeGet_Id(graph, edge) < 0) /*ignore backward edges */
- dist[node_id][dglNodeGet_Id
- (graph, dglEdgeGet_Tail(graph, edge))] =
- dglEdgeGet_Cost(graph, edge);
- dglEdgeset_T_Release(&et);
- }
- dglNode_T_Release(&nt);
- for (k = 0; k < indices; k++) {
- dglInt32_t k_index = node_indices[k];
- G_percent(k + 1, indices, 1);
- for (i = 0; i < indices; i++) {
- dglInt32_t i_index = node_indices[i];
- if (dist[i_index][k_index] == -1)
- continue; /*no reason to proceed along infinite path */
- for (j = 0; j < indices; j++) {
- dglInt32_t j_index = node_indices[j];
- if (dist[k_index][j_index] != -1 &&
- (dist[i_index][k_index] + dist[k_index][j_index] <
- dist[i_index][j_index] || dist[i_index][j_index] == -1)) {
- dist[i_index][j_index] =
- dist[i_index][k_index] + dist[k_index][j_index];
- }
- }
- }
- }
-
- G_free(node_indices);
- return 0;
-}
Deleted: grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,39 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: netalib
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: netalib utility functions
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dbmi.h>
-#include <grass/neta.h>
-
-
-void neta_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
- struct line_cats *Cats)
-{
- static struct line_pnts *Points;
- double x, y, z;
- Points = Vect_new_line_struct();
- Vect_get_node_coor(In, node, &x, &y, &z);
- Vect_reset_line(Points);
- Vect_append_point(Points, x, y, z);
- Vect_write_line(Out, GV_POINT, Points, Cats);
- Vect_destroy_line_struct(Points);
-}
Modified: grass-addons/vector/net.analyze/v.net.bridge/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/Makefile 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.bridge/Makefile 2009-05-28 19:22:23 UTC (rev 37576)
@@ -2,6 +2,8 @@
PGM=v.net.bridge
+include ../Netalib.make
+
LIBES = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
EXTRA_INC = $(VECT_INC)
Deleted: grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,139 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: netalib
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: Computes strongly and weakly connected components
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-/* return the number of articulation points in the graph.
- */
-int neta_articulation_points(dglGraph_s * graph,
- struct ilist *articulation_list)
-{
- int nnodes;
- int points = 0;
-
- dglEdgesetTraverser_s *current; /*edge to be processed when the node is visited */
- int *tin, *min_tin; /*time in, and smallest tin over all successors. 0 if not yet visited */
- dglInt32_t **parent; /*parents of the nodes */
- dglInt32_t **stack; /*stack of nodes */
- dglInt32_t **current_edge; /*current edge for each node */
- int *mark; /*marked articulation points */
- dglNodeTraverser_s nt;
- dglInt32_t *current_node;
- int stack_size;
- int i, time;
- nnodes = dglGet_NodeCount(graph);
- current =
- (dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
- sizeof(dglEdgesetTraverser_s));
- tin = (int *)G_calloc(nnodes + 1, sizeof(int));
- min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
- parent = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
- stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
- current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
- mark = (int *)G_calloc(nnodes + 1, sizeof(int));
- if (!tin || !min_tin || !parent || !stack || !current || !mark) {
- G_fatal_error(_("Out of memory"));
- return -1;
- }
-
- for (i = 1; i <= nnodes; i++) {
- dglEdgeset_T_Initialize(¤t[i], graph,
- dglNodeGet_OutEdgeset(graph,
- dglGetNode(graph, i)));
- current_edge[i] = dglEdgeset_T_First(¤t[i]);
- tin[i] = mark[i] = 0;
- }
-
- dglNode_T_Initialize(&nt, graph);
-
- time = 0;
- for (current_node = dglNode_T_First(&nt); current_node;
- current_node = dglNode_T_Next(&nt)) {
- dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
- if (tin[current_id] == 0) {
- int children = 0; /*number of subtrees rooted at the root/current_node */
- stack[0] = current_node;
- stack_size = 1;
- parent[current_id] = NULL;
- while (stack_size) {
- dglInt32_t *node = stack[stack_size - 1];
- dglInt32_t node_id = dglNodeGet_Id(graph, node);
- if (tin[node_id] == 0) /*vertex visited for the first time */
- min_tin[node_id] = tin[node_id] = ++time;
- else { /*return from the recursion */
- dglInt32_t to = dglNodeGet_Id(graph,
- dglEdgeGet_Tail(graph,
- current_edge
- [node_id]));
- if (min_tin[to] >= tin[node_id]) /*no path from the subtree above the current node */
- mark[node_id] = 1; /*so the current node must be an articulation point */
-
- if (min_tin[to] < min_tin[node_id])
- min_tin[node_id] = min_tin[to];
- current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id]); /*proceed to the next edge */
- }
- for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id])) { //try next edges
- dglInt32_t *to =
- dglEdgeGet_Tail(graph, current_edge[node_id]);
- if (to == parent[node_id])
- continue; /*skip parrent */
- int to_id = dglNodeGet_Id(graph, to);
- if (tin[to_id]) { /*back edge, cannot be a bridge/articualtion point */
- if (tin[to_id] < min_tin[node_id])
- min_tin[node_id] = tin[to_id];
- }
- else { /*forward edge */
- if (node_id == current_id)
- children++; /*if root, increase number of children */
- parent[to_id] = node;
- stack[stack_size++] = to;
- break;
- }
- }
- if (!current_edge[node_id])
- stack_size--; /*current node completely processed */
- }
- if (children > 1)
- mark[current_id] = 1; /*if the root has more than 1 subtrees rooted at it, then it is an
- * articulation point */
- }
- }
-
- for (i = 1; i <= nnodes; i++)
- if (mark[i]) {
- points++;
- Vect_list_append(articulation_list, i);
- }
-
- dglNode_T_Release(&nt);
- for (i = 1; i <= nnodes; i++)
- dglEdgeset_T_Release(¤t[i]);
-
- G_free(current);
- G_free(tin);
- G_free(min_tin);
- G_free(parent);
- G_free(stack);
- G_free(current_edge);
- return points;
-}
Deleted: grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,128 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: netalib
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: Computes strongly and weakly connected components
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-/* return the number of bridges in the graph.
- * bridge is an array containing the indices of the bridges
- */
-int neta_compute_bridges(dglGraph_s * graph, struct ilist *bridge_list)
-{
- int nnodes;
- int bridges = 0;
-
- dglEdgesetTraverser_s *current; /*edge to be processed when the node is visited */
- int *tin, *min_tin; /*time in, and smallest tin over all successors. 0 if not yet visited */
- dglInt32_t *parent; /*edge from parent to the node */
- dglInt32_t **stack; /*stack of nodes */
- dglInt32_t **current_edge; /*current edge for each node */
- dglNodeTraverser_s nt;
- dglInt32_t *current_node;
- int stack_size;
- int i, time;
- nnodes = dglGet_NodeCount(graph);
- current =
- (dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
- sizeof(dglEdgesetTraverser_s));
- tin = (int *)G_calloc(nnodes + 1, sizeof(int));
- min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
- parent = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
- stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
- current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
- if (!tin || !min_tin || !parent || !stack || !current) {
- G_fatal_error(_("Out of memory"));
- return -1;
- }
-
- for (i = 1; i <= nnodes; i++) {
- dglEdgeset_T_Initialize(¤t[i], graph,
- dglNodeGet_OutEdgeset(graph,
- dglGetNode(graph, i)));
- current_edge[i] = dglEdgeset_T_First(¤t[i]);
- tin[i] = 0;
- }
-
- dglNode_T_Initialize(&nt, graph);
-
- time = 0;
- for (current_node = dglNode_T_First(&nt); current_node;
- current_node = dglNode_T_Next(&nt)) {
- dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
- if (tin[current_id] == 0) {
- stack[0] = current_node;
- stack_size = 1;
- parent[current_id] = 0;
- while (stack_size) {
- dglInt32_t *node = stack[stack_size - 1];
- dglInt32_t node_id = dglNodeGet_Id(graph, node);
- if (tin[node_id] == 0) /*vertex visited for the first time */
- min_tin[node_id] = tin[node_id] = ++time;
- else { /*return from the recursion */
- dglInt32_t to = dglNodeGet_Id(graph,
- dglEdgeGet_Tail(graph,
- current_edge
- [node_id]));
- if (min_tin[to] > tin[node_id]) { /*no path from the subtree above the current node */
- Vect_list_append(bridge_list, dglEdgeGet_Id(graph, current_edge[node_id])); /*so it must be a bridge */
- bridges++;
- }
- if (min_tin[to] < min_tin[node_id])
- min_tin[node_id] = min_tin[to];
- current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id]); /*proceed to the next edge */
- }
- for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(¤t[node_id])) { //try next edges
- dglInt32_t *to =
- dglEdgeGet_Tail(graph, current_edge[node_id]);
- dglInt32_t edge_id =
- dglEdgeGet_Id(graph, current_edge[node_id]);
- if (abs(edge_id) == parent[node_id])
- continue; /*skip edge we used to travel to this node */
- int to_id = dglNodeGet_Id(graph, to);
- if (tin[to_id]) { /*back edge, cannot be a bridge/articualtion point */
- if (tin[to_id] < min_tin[node_id])
- min_tin[node_id] = tin[to_id];
- }
- else { /*forward edge */
- parent[to_id] = abs(edge_id);
- stack[stack_size++] = to;
- break;
- }
- }
- if (!current_edge[node_id])
- stack_size--; /*current node completely processed */
- }
- }
- }
-
- dglNode_T_Release(&nt);
- for (i = 1; i <= nnodes; i++)
- dglEdgeset_T_Release(¤t[i]);
-
- G_free(current);
- G_free(tin);
- G_free(min_tin);
- G_free(parent);
- G_free(stack);
- G_free(current_edge);
- return bridges;
-}
Modified: grass-addons/vector/net.analyze/v.net.components/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.components/Makefile 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.components/Makefile 2009-05-28 19:22:23 UTC (rev 37576)
@@ -3,6 +3,8 @@
PGM=v.net.components
+include ../Netalib.make
+
LIBES = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
EXTRA_INC = $(VECT_INC)
Deleted: grass-addons/vector/net.analyze/v.net.components/neta_comonents.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.components/neta_comonents.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.components/neta_comonents.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,175 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: v.net.components
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: Computes strongly and weakly connected components
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-int neta_weakly_connected_components(dglGraph_s * graph, int *component)
-{
- int nnodes;
- dglInt32_t *stack;
- int *visited;
- int stack_size, components;
- dglInt32_t *cur_node;
- dglNodeTraverser_s nt;
-
- components = 0;
- nnodes = dglGet_NodeCount(graph);
- stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
- visited = (int *)G_calloc(nnodes + 1, sizeof(int));
- if (!stack || !visited) {
- G_fatal_error(_("Out of memory"));
- return -1;
- }
-
- dglNode_T_Initialize(&nt, graph);
-
- for (cur_node = dglNode_T_First(&nt); cur_node;
- cur_node = dglNode_T_Next(&nt)) {
- dglInt32_t node_id = dglNodeGet_Id(graph, cur_node);
- if (!visited[node_id]) {
- visited[node_id] = 1;
- stack[0] = node_id;
- stack_size = 1;
- component[node_id] = ++components;
- while (stack_size) {
- dglInt32_t *node, *edgeset, *edge;
- dglEdgesetTraverser_s et;
- node = dglGetNode(graph, stack[--stack_size]);
- edgeset = dglNodeGet_OutEdgeset(graph, node);
- dglEdgeset_T_Initialize(&et, graph, edgeset);
- for (edge = dglEdgeset_T_First(&et); edge;
- edge = dglEdgeset_T_Next(&et)) {
- dglInt32_t to;
- to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
- if (!visited[to]) {
- visited[to] = 1;
- component[to] = components;
- stack[stack_size++] = to;
- }
- }
- dglEdgeset_T_Release(&et);
- }
- }
- }
- dglNode_T_Release(&nt);
- G_free(visited);
- return components;
-}
-
-int neta_strongly_connected_components(dglGraph_s * graph, int *component)
-{
- int nnodes;
- dglInt32_t *stack, *order;
- int *visited, *processed;
- int stack_size, order_size, components;
- dglInt32_t *node;
- dglNodeTraverser_s nt;
-
- components = 0;
- nnodes = dglGet_NodeCount(graph);
- stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
- order = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
- visited = (int *)G_calloc(nnodes + 1, sizeof(int));
- processed = (int *)G_calloc(nnodes + 1, sizeof(int));
- if (!stack || !visited || !order || !processed) {
- G_fatal_error(_("Out of memory"));
- return -1;
- }
-
- order_size = 0;
- dglNode_T_Initialize(&nt, graph);
-
- for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
- dglInt32_t node_id = dglNodeGet_Id(graph, node);
- component[node_id] = 0;
- if (!visited[node_id]) {
- visited[node_id] = 1;
- stack[0] = node_id;
- stack_size = 1;
- while (stack_size) {
- dglInt32_t *node, *edgeset, *edge;
- dglEdgesetTraverser_s et;
- dglInt32_t cur_node_id = stack[stack_size - 1];
- if (processed[cur_node_id]) {
- stack_size--;
- order[order_size++] = cur_node_id;
- continue;
- }
- processed[cur_node_id] = 1;
- node = dglGetNode(graph, cur_node_id);
- edgeset = dglNodeGet_OutEdgeset(graph, node);
- dglEdgeset_T_Initialize(&et, graph, edgeset);
- for (edge = dglEdgeset_T_First(&et); edge;
- edge = dglEdgeset_T_Next(&et)) {
- dglInt32_t to;
- if (dglEdgeGet_Id(graph, edge) < 0)
- continue; /*ignore backward edges */
- to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
- if (!visited[to]) {
- visited[to] = 1;
- stack[stack_size++] = to;
- }
- }
- dglEdgeset_T_Release(&et);
- }
- }
- }
-
- dglNode_T_Release(&nt);
-
- while (order_size) {
- dglInt32_t node_id = order[--order_size];
- if (component[node_id])
- continue;
- components++;
- component[node_id] = components;
- stack[0] = node_id;
- stack_size = 1;
- while (stack_size) {
- dglInt32_t *node, *edgeset, *edge;
- dglEdgesetTraverser_s et;
- dglInt32_t cur_node_id = stack[--stack_size];
- node = dglGetNode(graph, cur_node_id);
- edgeset = dglNodeGet_OutEdgeset(graph, node);
- dglEdgeset_T_Initialize(&et, graph, edgeset);
- for (edge = dglEdgeset_T_First(&et); edge;
- edge = dglEdgeset_T_Next(&et)) {
- dglInt32_t to;
- if (dglEdgeGet_Id(graph, edge) > 0)
- continue; /*ignore forward edges */
- to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
- if (!component[to]) {
- component[to] = components;
- stack[stack_size++] = to;
- }
- }
- dglEdgeset_T_Release(&et);
- }
- }
-
- G_free(stack);
- G_free(visited);
- G_free(order);
- G_free(processed);
- return components;
-}
Modified: grass-addons/vector/net.analyze/v.net.flow/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.flow/Makefile 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.flow/Makefile 2009-05-28 19:22:23 UTC (rev 37576)
@@ -2,6 +2,8 @@
PGM=v.net.flow
+include ../Netalib.make
+
LIBES = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
EXTRA_INC = $(VECT_INC)
Deleted: grass-addons/vector/net.analyze/v.net.flow/neta_flow.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.flow/neta_flow.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.flow/neta_flow.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,123 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: netalib
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: Computes the legngth of the shortest path between
- * all pairs of nodes in the network
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-dglInt32_t sign(dglInt32_t x)
-{
- if (x >= 0)
- return 1;
- return -1;
-}
-
-/*
- * returns max flow from source to sink. Array flow stores flow for
- * each edge. Negative flow corresponds to a flow in opposite direction
- * The function assumes that the edge costs correspond to edge capacities.
- */
-int neta_flow(dglGraph_s * graph, int source, int sink, int *flow)
-{
- int nnodes, nlines, i;
- dglEdgesetTraverser_s et;
- dglInt32_t *queue;
- dglInt32_t **prev;
- int begin, end, total_flow;
-
- nnodes = dglGet_NodeCount(graph);
- nlines = dglGet_EdgeCount(graph) / 2; /*each line corresponds to two edges. One in each direction */
- queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
- prev = (dglInt32_t **) G_calloc(nnodes + 3, sizeof(dglInt32_t *));
- if (!queue || !prev) {
- G_fatal_error(_("Out of memory"));
- return -1;
- }
- for (i = 0; i <= nlines; i++)
- flow[i] = 0;
- total_flow = 0;
- while (1) {
- dglInt32_t node, edge_id, min_residue;
- int found = 0;
- begin = 0;
- end = 1;
- queue[0] = source;
- for (i = 1; i <= nnodes; i++) {
- prev[i] = NULL;
- }
- while (begin != end && !found) {
- dglInt32_t vertex = queue[begin++];
- dglInt32_t *edge, *node = dglGetNode(graph, vertex);
- dglEdgeset_T_Initialize(&et, graph,
- dglNodeGet_OutEdgeset(graph, node));
- for (edge = dglEdgeset_T_First(&et); edge;
- edge = dglEdgeset_T_Next(&et)) {
- dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
- dglInt32_t id = dglEdgeGet_Id(graph, edge);
- dglInt32_t to =
- dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
- if (to != source && prev[to] == NULL &&
- cap > sign(id) * flow[abs(id)]) {
- prev[to] = edge;
- if (to == sink) {
- found = 1;
- break;
- }
- queue[end++] = to;
- }
- }
- dglEdgeset_T_Release(&et);
- }
- if (!found)
- break; /*no augmenting path */
- /*find minimum residual capacity along the augmenting path */
- node = sink;
- edge_id = dglEdgeGet_Id(graph, prev[node]);
- min_residue =
- dglEdgeGet_Cost(graph,
- prev[node]) - sign(edge_id) * flow[abs(edge_id)];
- while (node != source) {
- dglInt32_t residue;
- edge_id = dglEdgeGet_Id(graph, prev[node]);
- residue =
- dglEdgeGet_Cost(graph,
- prev[node]) -
- sign(edge_id) * flow[abs(edge_id)];
- if (residue < min_residue)
- min_residue = residue;
- node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
- }
- total_flow += min_residue;
- /*update flow along the augmenting path */
- node = sink;
- while (node != source) {
- edge_id = dglEdgeGet_Id(graph, prev[node]);
- flow[abs(edge_id)] += sign(edge_id) * min_residue;
- node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
- }
- }
-
- G_free(queue);
- G_free(prev);
-
- return total_flow;
-}
Deleted: grass-addons/vector/net.analyze/v.net.flow/neta_utils.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.flow/neta_utils.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.flow/neta_utils.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,39 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: netalib
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: netalib utility functions
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dbmi.h>
-#include <grass/neta.h>
-
-
-void neta_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
- struct line_cats *Cats)
-{
- static struct line_pnts *Points;
- double x, y, z;
- Points = Vect_new_line_struct();
- Vect_get_node_coor(In, node, &x, &y, &z);
- Vect_reset_line(Points);
- Vect_append_point(Points, x, y, z);
- Vect_write_line(Out, GV_POINT, Points, Cats);
- Vect_destroy_line_struct(Points);
-}
Modified: grass-addons/vector/net.analyze/v.net.spanningtree/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.spanningtree/Makefile 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.spanningtree/Makefile 2009-05-28 19:22:23 UTC (rev 37576)
@@ -2,6 +2,8 @@
PGM=v.net.spanningtree
+include ../Netalib.make
+
LIBES = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
EXTRA_INC = $(VECT_INC)
Deleted: grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c 2009-05-28 18:53:46 UTC (rev 37575)
+++ grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c 2009-05-28 19:22:23 UTC (rev 37576)
@@ -1,133 +0,0 @@
-
-/****************************************************************
- *
- * MODULE: netalib
- *
- * AUTHOR(S): Daniel Bundala
- *
- * PURPOSE: Computes minimum spanning tree in the network
- *
- * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-struct union_find
-{
- int *parent;
-};
-
-int uf_initialize(struct union_find *uf, int size)
-{
- int i;
- uf->parent = (int *)G_calloc(size, sizeof(int));
- if (!uf->parent)
- return 0;
- for (i = 0; i < size; i++)
- uf->parent[i] = i;
- return 1;
-}
-
-void uf_release(struct union_find *uf)
-{
- G_free(uf->parent);
-}
-
-int uf_find(struct union_find *uf, int v)
-{
- int cur = v, tmp;
- while (uf->parent[cur] != cur)
- cur = uf->parent[cur];
- while (uf->parent[v] != v) {
- tmp = uf->parent[v];
- uf->parent[v] = cur;
- v = tmp;
- }
- return cur;
-}
-
-/*TODO: union by rank */
-void uf_union(struct union_find *uf, int u, int v)
-{
- int parent_u = uf_find(uf, u);
- int parent_v = uf_find(uf, v);
- if (parent_u != parent_v)
- uf->parent[parent_u] = parent_v;
-}
-
-typedef struct
-{
- dglInt32_t cost;
- dglInt32_t *edge;
-} edge_cost_pair;
-
-int cmp_edge(const void *pa, const void *pb)
-{
- return ((edge_cost_pair *) pa)->cost - ((edge_cost_pair *) pb)->cost;
-}
-
-/* return the number of edges in the spanning forest */
-int neta_spanning_tree(dglGraph_s * graph, struct ilist *tree_list)
-{
- int nnodes, edges, nedges, i, index;
- edge_cost_pair *perm; /*permutaion of edges in ascending order */
- struct union_find uf;
- dglEdgesetTraverser_s et;
- nnodes = dglGet_NodeCount(graph);
- nedges = dglGet_EdgeCount(graph);
- perm = (edge_cost_pair *) G_calloc(nedges, sizeof(edge_cost_pair));
- if (!perm || !uf_initialize(&uf, nnodes + 1)) {
- G_fatal_error(_("Out of memory"));
- return -1;
- }
- /*for some obscure reasons, dglGetEdge always returns NULL. Therefore this complicated enumeration of the edges... */
- index = 0;
- G_message(_("Computing minimum spanning tree..."));
- G_percent_reset();
- for (i = 1; i <= nnodes; i++) {
- G_percent(i, nnodes + nedges, 1);
- dglInt32_t *edge;
- dglEdgeset_T_Initialize(&et, graph,
- dglNodeGet_OutEdgeset(graph,
- dglGetNode(graph,
- (dglInt32_t)
- i)));
- for (edge = dglEdgeset_T_First(&et); edge;
- edge = dglEdgeset_T_Next(&et))
- if (dglEdgeGet_Id(graph, edge) > 0) {
- perm[index].edge = edge;
- perm[index].cost = dglEdgeGet_Cost(graph, edge);
- index++;
- }
-
- dglEdgeset_T_Release(&et);
- }
- edges = 0;
- qsort((void *)perm, index, sizeof(edge_cost_pair), cmp_edge);
- for (i = 0; i < index; i++) {
- G_percent(i + nnodes, nnodes + nedges, 1);
- dglInt32_t head =
- dglNodeGet_Id(graph, dglEdgeGet_Head(graph, perm[i].edge));
- dglInt32_t tail =
- dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, perm[i].edge));
- if (uf_find(&uf, head) != uf_find(&uf, tail)) {
- uf_union(&uf, head, tail);
- edges++;
- Vect_list_append(tree_list, dglEdgeGet_Id(graph, perm[i].edge));
- }
- }
- G_free(perm);
- uf_release(&uf);
- return edges;
-}
More information about the grass-commit
mailing list