[GRASS-SVN] r67992 - grass/trunk/lib/vector/neta

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Mar 3 13:20:01 PST 2016


Author: mmetz
Date: 2016-03-03 13:20:01 -0800 (Thu, 03 Mar 2016)
New Revision: 67992

Modified:
   grass/trunk/lib/vector/neta/path.c
Log:
netalib, path.c: consider node costs, update documentation

Modified: grass/trunk/lib/vector/neta/path.c
===================================================================
--- grass/trunk/lib/vector/neta/path.c	2016-03-03 21:12:15 UTC (rev 67991)
+++ grass/trunk/lib/vector/neta/path.c	2016-03-03 21:20:01 UTC (rev 67992)
@@ -11,6 +11,7 @@
    (>=v2). Read the file COPYING that comes with GRASS for details.
 
    \author Daniel Bundala (Google Summer of Code 2009)
+   \author Markus Metz
  */
 
 #include <stdio.h>
@@ -24,14 +25,14 @@
 /*!
    \brief Computes shortest paths to every node from nodes in "from".
 
-   Array "dst" contains the length of the path or -1 if the node is not
+   Array "dst" contains the cost of the path or -1 if the node is not
    reachable. Prev contains edges from predecessor along the shortest
    path.
 
    \param graph input graph
    \param from list of 'from' positions
-   \param dst list of 'to' positions
-   \param[out] prev list of edges from predecessor along the shortest path
+   \param[out] dst array of costs to reach nodes
+   \param[out] prev array of edges from predecessor along the shortest path
 
    \return 0 on success
    \return -1 on failure
@@ -41,6 +42,8 @@
 {
     int i, nnodes;
     dglHeap_s heap;
+    int have_node_costs;
+    dglInt32_t ncost;
 
     nnodes = dglGet_NodeCount(graph);
     dglEdgesetTraverser_s et;
@@ -51,6 +54,9 @@
 	prev[i] = NULL;
     }
 
+    ncost = 0;
+    have_node_costs = dglGet_NodeAttrSize(graph);
+
     dglHeapInit(&heap);
 
     for (i = 0; i < from->n_values; i++) {
@@ -68,6 +74,8 @@
 	dglInt32_t v, dist;
 	dglHeapNode_s heap_node;
 	dglHeapData_u heap_data;
+	dglInt32_t *edge;
+	dglInt32_t *node;
 
 	if (!dglHeapExtractMin(&heap, &heap_node))
 	    break;
@@ -76,11 +84,20 @@
 	if (dst[v] < dist)
 	    continue;
 
-	dglInt32_t *edge;
+	node = dglGetNode(graph, v);
 
+	if (have_node_costs && prev[v]) {
+	    memcpy(&ncost, dglNodeGet_Attr(graph, node),
+		   sizeof(ncost));
+	    if (ncost > 0)
+		dist += ncost;
+	    /* do not go through closed nodes */
+	    if (ncost < 0)
+		continue;
+	}
+
 	dglEdgeset_T_Initialize(&et, graph,
-				dglNodeGet_OutEdgeset(graph,
-						      dglGetNode(graph, v)));
+				dglNodeGet_OutEdgeset(graph, node));
 
 	for (edge = dglEdgeset_T_First(&et); edge;
 	     edge = dglEdgeset_T_Next(&et)) {
@@ -107,14 +124,15 @@
 /*!
    \brief Computes shortest paths from every node to nodes in "to".
 
-   Array "dst" contains the length of the path or -1 if the node is not
+   Array "dst" contains the cost of the path or -1 if the node is not
    reachable. Nxt contains edges from successor along the shortest
-   path.
+   path. This method does reverse search starting with "to" nodes and 
+   going backward.
 
    \param graph input graph
-   \param from list of 'from' positions
-   \param dst list of 'to' positions
-   \param[out] nxt list of edges from successor along the shortest path
+   \param to list of 'to' positions
+   \param[out] dst array of costs to reach nodes
+   \param[out] nxt array of edges from successor along the shortest path
 
    \return 0 on success
    \return -1 on failure
@@ -125,6 +143,8 @@
     int i, nnodes;
     dglHeap_s heap;
     dglEdgesetTraverser_s et;
+    int have_node_costs;
+    dglInt32_t ncost;
 
     nnodes = dglGet_NodeCount(graph);
 
@@ -139,6 +159,9 @@
 	return -1;
     }
 
+    ncost = 0;
+    have_node_costs = dglGet_NodeAttrSize(graph);
+
     dglHeapInit(&heap);
 
     for (i = 0; i < to->n_values; i++) {
@@ -156,6 +179,8 @@
 	dglInt32_t v, dist;
 	dglHeapNode_s heap_node;
 	dglHeapData_u heap_data;
+	dglInt32_t *edge;
+	dglInt32_t *node;
 
 	if (!dglHeapExtractMin(&heap, &heap_node))
 	    break;
@@ -164,11 +189,20 @@
 	if (dst[v] < dist)
 	    continue;
 
-	dglInt32_t *edge;
+	node = dglGetNode(graph, v);
 
+	if (have_node_costs && nxt[v]) {
+	    memcpy(&ncost, dglNodeGet_Attr(graph, node),
+		   sizeof(ncost));
+	    if (ncost > 0)
+		dist += ncost;
+	    /* do not go through closed nodes */
+	    if (ncost < 0)
+		continue;
+	}
+
 	dglEdgeset_T_Initialize(&et, graph,
-				dglNodeGet_InEdgeset(graph,
-						      dglGetNode(graph, v)));
+				dglNodeGet_InEdgeset(graph, node));
 
 	for (edge = dglEdgeset_T_First(&et); edge;
 	     edge = dglEdgeset_T_Next(&et)) {
@@ -193,16 +227,18 @@
 }
 
 /*!
-   \brief Find a path (minimum number of edges) from 'from' to 'to' using only edges in 'edges'.
+   \brief Find a path (minimum number of edges) from 'from' to 'to' 
+   using only edges flagged as valid in 'edges'. Edge costs are not 
+   considered. Closed nodes are not traversed.
 
    Precisely, edge with id I is used if edges[abs(i)] == 1. List
-   stores the indices of lines on the path. Method return number of
-   edges or -1 if no path exist.
+   stores the indices of lines on the path. The method returns the 
+   number of edges or -1 if no path exists.
 
    \param graph input graph
    \param from 'from' position
    \param to 'to' position
-   \param edges list of available edges
+   \param edges array of edges indicating wether an edge should be used
    \param[out] list list of edges
 
    \return number of edges
@@ -215,6 +251,8 @@
     dglEdgesetTraverser_s et;
     char *vis;
     int begin, end, cur, nnodes;
+    int have_node_costs;
+    dglInt32_t ncost;
 
     nnodes = dglGet_NodeCount(graph);
     prev = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
@@ -226,6 +264,9 @@
     }
     Vect_reset_list(list);
 
+    ncost = 0;
+    have_node_costs = dglGet_NodeAttrSize(graph);
+
     begin = 0;
     end = 1;
     vis[from] = 'y';
@@ -233,22 +274,32 @@
     prev[from] = NULL;
     while (begin != end) {
 	dglInt32_t vertex = queue[begin++];
+	dglInt32_t *edge, *node;
 
 	if (vertex == to)
 	    break;
-	dglInt32_t *edge, *node = dglGetNode(graph, vertex);
 
+	/* do not go through closed nodes */
+	if (have_node_costs && prev[vertex]) {
+	    memcpy(&ncost, dglNodeGet_Attr(graph, dglEdgeGet_Tail(graph, edge)),
+		   sizeof(ncost));
+	    if (ncost < 0)
+		continue;
+	}
+
+	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 id = abs(dglEdgeGet_Id(graph, edge));
-	    dglInt32_t to =
+	    dglInt32_t edge_id = abs(dglEdgeGet_Id(graph, edge));
+	    dglInt32_t node_id =
 		dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-	    if (edges[id] && !vis[to]) {
-		vis[to] = 'y';
-		prev[to] = edge;
-		queue[end++] = to;
+	    if (edges[edge_id] && !vis[node_id]) {
+		vis[node_id] = 'y';
+		prev[node_id] = edge;
+		queue[end++] = node_id;
 	    }
 	}
 	dglEdgeset_T_Release(&et);



More information about the grass-commit mailing list