[GRASS-SVN] r39683 - grass/trunk/raster/r.cost

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Nov 5 11:02:23 EST 2009


Author: mmetz
Date: 2009-11-05 11:02:22 -0500 (Thu, 05 Nov 2009)
New Revision: 39683

Added:
   grass/trunk/raster/r.cost/heap.c
Removed:
   grass/trunk/raster/r.cost/btree.c
   grass/trunk/raster/r.cost/local_proto.h
   grass/trunk/raster/r.cost/memory.c
   grass/trunk/raster/r.cost/memory.h
Modified:
   grass/trunk/raster/r.cost/cost.h
   grass/trunk/raster/r.cost/main.c
   grass/trunk/raster/r.cost/stash.h
Log:
faster, less memory

Deleted: grass/trunk/raster/r.cost/btree.c
===================================================================
--- grass/trunk/raster/r.cost/btree.c	2009-11-05 07:40:20 UTC (rev 39682)
+++ grass/trunk/raster/r.cost/btree.c	2009-11-05 16:02:22 UTC (rev 39683)
@@ -1,445 +0,0 @@
-
-/****************************************************************************
- *
- * MODULE:       r.cost
- *
- * AUTHOR(S):    Antony Awaida - IESL - M.I.T.
- *               James Westervelt - CERL
- *               Pierre de Mouveaux <pmx audiovu com>
- *               Eric G. Miller <egm2 jps net>
- *
- * PURPOSE:      Outputs a raster map layer showing the cumulative cost
- *               of moving between different geographic locations on an
- *               input raster map layer whose cell category values
- *               represent cost.
- *
- * COPYRIGHT:    (C) 2006-2009 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.
- *
- ***************************************************************************/
-
-/* These routines manage the list of grid-cell candidates for 
- * visiting to calculate distances to surrounding cells.
- * A binary tree (btree) approach is used.  Components are
- * sorted by distance.
- *
- * insert ()
- *   inserts a new row-col with its distance value into the btree
- *
- * delete()
- *   deletes (if possible) a row-col entry in the tree
- *
- * get_lowest()
- *   retrieves the entry with the smallest distance value
- */
-
-
-#include <grass/gis.h>
-#include "local_proto.h"
-#include "memory.h"
-#include <stdlib.h>
-#include <grass/glocale.h>
-
-static struct cost *start_cell = NULL;
-
-/*  static int show(struct cost *); */
-static int do_quit(double, int, int);
-
-struct cost *insert(double min_cost, int row, int col)
-{
-    struct cost *new_cell, *next_cell;
-
-    /*      new_cell = (struct cost *)(G_malloc(sizeof(struct cost))); */
-    new_cell = get();
-    if (new_cell == NULL) {
-	G_message(_("NULL value computed (row %d, col %d)"),
-		  row, col);
-    }
-    new_cell->min_cost = min_cost;
-    new_cell->row = row;
-    new_cell->col = col;
-    new_cell->above = NULL;
-    new_cell->higher = NULL;
-    new_cell->lower = NULL;
-    new_cell->nexttie = NULL;
-    new_cell->previoustie = NULL;
-
-    if (start_cell == NULL) {
-	start_cell = new_cell;
-	return (new_cell);
-    }
-
-    for (next_cell = start_cell;;) {
-	if (min_cost < next_cell->min_cost) {
-	    if (next_cell->lower != NULL) {
-		next_cell = next_cell->lower;
-		continue;
-	    }
-	    new_cell->above = next_cell;
-	    next_cell->lower = new_cell;
-	    return (new_cell);
-	}
-	if (min_cost > next_cell->min_cost) {
-	    if (next_cell->higher != NULL) {
-		next_cell = next_cell->higher;
-		continue;
-	    }
-	    new_cell->above = next_cell;
-	    next_cell->higher = new_cell;
-	    return (new_cell);
-	}
-
-	/* If we find a value that is exactly equal to new value */
-	new_cell->nexttie = next_cell->nexttie;
-	next_cell->nexttie = new_cell;
-	new_cell->previoustie = next_cell;
-	if (new_cell->nexttie != NULL)
-	    new_cell->nexttie->previoustie = new_cell;
-
-	return (new_cell);
-    }
-}
-
-
-struct cost *find(double min_cost, int row, int col)
-{
-    struct cost *next_cell;
-    struct cost *next_tie_cell;
-
-    for (next_cell = start_cell;;) {
-	if (min_cost <= next_cell->min_cost) {
-	    for (next_tie_cell = next_cell;
-		 next_tie_cell != NULL;
-		 next_tie_cell = next_tie_cell->nexttie)
-		if (next_tie_cell->row == row && next_tie_cell->col == col)
-		    return (next_tie_cell);
-	    /*
-	       if (next_cell->row == row && next_cell->col == col)
-	       return(next_cell) ;
-	     */
-
-	    if (next_cell->lower != NULL) {
-		next_cell = next_cell->lower;
-		continue;
-	    }
-	    G_debug(2, "1 ");
-	    return NULL;
-	    do_quit(min_cost, row, col); /* ??? */
-	}
-	else {
-	    if (next_cell->higher != NULL) {
-		next_cell = next_cell->higher;
-		continue;
-	    }
-	    G_debug(2, "2 ");
-	    return NULL;
-	    do_quit(min_cost, row, col); /* ??? */
-	}
-    }
-}
-
-static int do_quit(double min_cost, int row, int col)
-{
-    G_warning(_("Unable to find row %d, col %d: %f"),
-	      row, col, min_cost);
-    show_all();
-    exit(EXIT_FAILURE);
-}
-
-struct cost *get_lowest(void)
-{
-    struct cost *next_cell;
-
-    if (start_cell == NULL)
-	return (NULL);
-
-    for (next_cell = start_cell;
-	 next_cell->lower != NULL; next_cell = next_cell->lower) ;
-
-    /* Grab my first tie instead of me */
-    if (next_cell->nexttie != NULL)
-	next_cell = next_cell->nexttie;
-
-    if (next_cell->row == -1) {
-	/*
-	   fprintf(stderr, "Deleting %d\n", next_cell) ;
-	   show_all() ;
-	 */
-	delete(next_cell);
-	/*
-	   fprintf(stderr, "Deleted %d\n", next_cell) ;
-	   show_all() ;
-	 */
-	return (get_lowest());
-    }
-
-    return (next_cell);
-}
-
-int delete(struct cost *delete_cell)
-{
-    if (delete_cell == NULL) {
-	G_warning(_("Illegal delete request"));
-	return 0;
-    }
-
-    /* Simple remove if I'm a one of the "ties" */
-    if (delete_cell->previoustie != NULL) {
-	delete_cell->previoustie->nexttie = delete_cell->nexttie;
-	if (delete_cell->nexttie != NULL)
-	    delete_cell->nexttie->previoustie = delete_cell->previoustie;
-	give(delete_cell);
-	return 0;
-    }
-    /* If I have a list of ties, link replace me with the first
-       in that list  */
-    if (delete_cell->nexttie != NULL) {
-	delete_cell->nexttie->above = delete_cell->above;
-	if (delete_cell->above != NULL) {
-	    if (delete_cell->above->lower == delete_cell)
-		delete_cell->above->lower = delete_cell->nexttie;
-	    else
-		delete_cell->above->higher = delete_cell->nexttie;
-	}
-
-	delete_cell->nexttie->lower = delete_cell->lower;
-	if (delete_cell->lower != NULL)
-	    delete_cell->lower->above = delete_cell->nexttie;
-
-	delete_cell->nexttie->higher = delete_cell->higher;
-	if (delete_cell->higher != NULL)
-	    delete_cell->higher->above = delete_cell->nexttie;
-	if (start_cell == delete_cell)
-	    start_cell = delete_cell->nexttie;
-	delete_cell->nexttie->previoustie = NULL;
-
-	give(delete_cell);
-	return (0);
-    }
-    /*
-       \      \      \      \   
-       1  X   4  X   7  X   10 X  
-       N N    / N    N \    / \ 
-
-       /      /      /      / 
-       2  X   5  X   8  X   11 X  
-       N N    / N    N \    / \
-
-       N      N      N      N  
-       3  X   6  X   9  X   12 X  
-       N N    / N    N \    / \
-     */
-    if (delete_cell->higher == NULL) {	/* 123456       */
-	if (delete_cell->lower == NULL) {	/* 123          */
-	    if (delete_cell->above == NULL) {	/*   3          */
-		start_cell = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	    if (delete_cell->above->higher == delete_cell) {	/* 1            */
-		delete_cell->above->higher = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	    else {		/*  2           */
-		delete_cell->above->lower = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	}
-	else {			/*    456       */
-
-	    if (delete_cell->above == NULL) {	/*      6       */
-		start_cell = delete_cell->lower;
-		delete_cell->lower->above = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	    if (delete_cell->above->higher == delete_cell) {	/*    4         */
-		delete_cell->above->higher = delete_cell->lower;
-		delete_cell->lower->above = delete_cell->above;
-		give(delete_cell);
-		return 0;
-	    }
-	    else {		/*     5        */
-		delete_cell->above->lower = delete_cell->lower;
-		delete_cell->lower->above = delete_cell->above;
-		give(delete_cell);
-		return 0;
-	    }
-	}
-    }
-    if (delete_cell->lower == NULL) {	/*       789    */
-	if (delete_cell->above == NULL) {	/*         9    */
-	    start_cell = delete_cell->higher;
-	    delete_cell->higher->above = NULL;
-	    give(delete_cell);
-	    return 0;
-	}
-	if (delete_cell->above->higher == delete_cell) {	/*       7      */
-	    delete_cell->above->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-	else {			/*        8     */
-	    delete_cell->above->lower = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-    }
-    /*
-     * At this point we are left with 10,11,12 which can be expanded
-     *    \   
-     *  10 X         X          X   
-     *    / \       / \        / \  
-     *          A  O   -   B  -   O     C ALL OTHERS
-     *      /     / N            N \
-     *  11 X  
-     *    / \
-     *
-     *     N  
-     *  12 X  
-     *    / \
-     */
-
-    if (delete_cell->lower->higher == NULL) {	/* A */
-	if (delete_cell == start_cell) {	/* 12A */
-	    delete_cell->lower->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->lower;
-	    start_cell = delete_cell->lower;
-	    delete_cell->lower->above = NULL;
-	    give(delete_cell);
-	    return 0;
-	}
-	if (delete_cell->above->higher == delete_cell) {	/* 10A */
-	    delete_cell->lower->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->lower;
-	    delete_cell->above->higher = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-	else {			/* 11A */
-	    delete_cell->lower->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->lower;
-	    delete_cell->above->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-    }
-    if (delete_cell->higher->lower == NULL) {	/* A */
-	if (delete_cell == start_cell) {	/* 12B */
-	    delete_cell->higher->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->higher;
-	    start_cell = delete_cell->higher;
-	    delete_cell->higher->above = NULL;
-	    give(delete_cell);
-	    return 0;
-	}
-	if (delete_cell->above->lower == delete_cell) {	/* 11B */
-	    delete_cell->higher->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->higher;
-	    delete_cell->above->lower = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-	else {			/* 10B */
-	    delete_cell->higher->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->higher;
-	    delete_cell->above->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-    }
-    /* If we get this far, the node cannot be safely removed.  Just leave
-     * an internal mark noting that it is no longer good.
-     */
-    delete_cell->row = -1;
-    return 0;
-}
-
-int show_all(void)
-{
-    if (start_cell == NULL) {
-	G_debug(1, "Nothing to show");
-	return 1;
-    }
-    show(start_cell);
-
-    return 0;
-}
-
-int show(struct cost *next)
-{
-    struct cost *next_cell;
-
-    if (next == NULL)
-	return 0;
-    for (next_cell = next; next_cell != NULL; next_cell = next_cell->nexttie)
-	G_message("%p %d,%d,%f %p %p %p %p",
-		  next_cell,
-		  next_cell->row,
-		  next_cell->col,
-		  next_cell->min_cost,
-		  next_cell->nexttie,
-		  next_cell->lower, next_cell->higher, next_cell->above);
-    show(next->lower);
-    show(next->higher);
-
-    return 0;
-}
-
-int check_all(char *str)
-{
-    if (start_cell->above != NULL) {
-	G_fatal_error(_("Bad start cell"));
-    }
-    check(str, start_cell);
-
-    return 0;
-}
-
-int check(char *str, struct cost *start)
-{
-    if (start == NULL)
-	return 0;
-
-    if (start->lower != NULL) {
-	if (start->min_cost < start->lower->min_cost) {
-	    G_warning(_("%s %f-%f lower cost higher or equal"), str,
-		      start->min_cost, start->lower->min_cost);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-	if (start->lower->above != start) {
-	    G_warning(_("%s lower above pointer wrong"), str);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-    }
-    if (start->higher != NULL) {
-	if (start->min_cost >= start->higher->min_cost) {
-	    G_warning(_("%s %f-%f higher cost lower"), str,
-		      start->min_cost, start->higher->min_cost);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-	if (start->higher->above != start) {
-	    G_warning(_("%s higher above pointer wrong"), str);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-    }
-    check(str, start->lower);
-    check(str, start->higher);
-
-    return 0;
-}

Modified: grass/trunk/raster/r.cost/cost.h
===================================================================
--- grass/trunk/raster/r.cost/cost.h	2009-11-05 07:40:20 UTC (rev 39682)
+++ grass/trunk/raster/r.cost/cost.h	2009-11-05 16:02:22 UTC (rev 39683)
@@ -29,7 +29,6 @@
 /*      point structure containing various attributes of       */
 /*      a grid cell.                                           */
 /*                                                             */
-
 /***************************************************************/
 
 #ifndef __COST_H__
@@ -38,22 +37,16 @@
 struct cost
 {
     double min_cost;
+    unsigned int age;
     int row;
     int col;
-    struct cost *lower;
-    struct cost *higher;
-    struct cost *above;
-    struct cost *nexttie;
-    struct cost *previoustie;
 };
 
-/* btree.c */
+/* heap.c */
 struct cost *insert(double, int, int);
-struct cost *find(double, int, int);
 struct cost *get_lowest(void);
-int show(struct cost *);
-int show_all();
 int delete(struct cost *);
-int check(char *, struct cost *);
+int init_heap(void);
+int free_heap(void);
 
 #endif /* __COST_H__ */

Added: grass/trunk/raster/r.cost/heap.c
===================================================================
--- grass/trunk/raster/r.cost/heap.c	                        (rev 0)
+++ grass/trunk/raster/r.cost/heap.c	2009-11-05 16:02:22 UTC (rev 39683)
@@ -0,0 +1,219 @@
+
+/****************************************************************************
+ *
+ * MODULE:       r.cost
+ *
+ * AUTHOR(S):    Antony Awaida - IESL - M.I.T.
+ *               James Westervelt - CERL
+ *               Pierre de Mouveaux <pmx audiovu com>
+ *               Eric G. Miller <egm2 jps net>
+ *
+ *               min heap by Markus Metz
+ *
+ * PURPOSE:      Outputs a raster map layer showing the cumulative cost
+ *               of moving between different geographic locations on an
+ *               input raster map layer whose cell category values
+ *               represent cost.
+ *
+ * COPYRIGHT:    (C) 2006-2009 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.
+ *
+ ***************************************************************************/
+
+/* These routines manage the list of grid-cell candidates for 
+ * visiting to calculate distances to surrounding cells.
+ * A min-heap approach is used.  Components are
+ * sorted first by distance then by the order in which they were added.
+ *
+ * insert ()
+ *   inserts a new row-col with its distance value into the heap
+ *
+ * delete()
+ *   deletes a row-col entry in the heap
+ *
+ * get_lowest()
+ *   retrieves the entry with the smallest distance value
+ */
+
+
+#include <grass/gis.h>
+#include <stdlib.h>
+#include <grass/glocale.h>
+#include "cost.h"
+
+#define GET_PARENT(c) (int) (((c) - 2) / 3 + 1)
+#define GET_CHILD(p) (int) (((p) * 3) - 1)
+
+unsigned int next_point = 0;
+unsigned int heap_size = 0;
+unsigned int heap_alloced = 0;
+struct cost **heap_index, *free_point;
+
+
+int init_heap(void)
+{
+    next_point = 0;
+    heap_size = 0;
+    heap_alloced = 1000;
+    heap_index = (struct cost **) G_malloc(heap_alloced * sizeof(struct cost *));
+
+    free_point = NULL;
+    
+    return 0;
+}
+
+int free_heap(void)
+{
+    if (heap_alloced)
+	G_free(heap_index);
+
+    if (free_point)
+	G_free(free_point);
+
+    return 0;
+}
+
+/* compare two costs
+ * return 1 if a < b else 0 */
+int cmp_costs(struct cost *a, struct cost *b)
+{
+    if (a->min_cost < b->min_cost)
+	return 1;
+    else if (a->min_cost == b->min_cost) {
+	if (a->age < b->age)
+	    return 1;
+    }
+
+    return 0;
+}
+
+unsigned int sift_up(unsigned int start, struct cost * child_pnt)
+{
+    register unsigned int parent, child;
+    int r, c;
+
+    r = child_pnt->row;
+    c = child_pnt->col;
+    
+    child = start;
+
+    while (child > 1) {
+	parent = GET_PARENT(child);
+
+	/* child is smaller */
+	if (cmp_costs(child_pnt, heap_index[parent])) {
+	    /* push parent point down */
+	    heap_index[child] = heap_index[parent];
+	    child = parent;
+	}
+	else
+	    /* no more sifting up, found new slot for child */
+	    break;
+    }
+
+    /* put point in new slot */
+    if (child < start) {
+	heap_index[child] = child_pnt;
+    }
+
+    return child;
+}
+
+struct cost *insert(double min_cost, int row, int col)
+{
+    struct cost *new_cell;
+
+    if (free_point) {
+	new_cell = free_point;
+	free_point = NULL;
+    }
+    else
+	new_cell = (struct cost *)(G_malloc(sizeof(struct cost)));
+
+    new_cell->min_cost = min_cost;
+    new_cell->age = next_point;
+    new_cell->row = row;
+    new_cell->col = col;
+
+    next_point++;
+    heap_size++;
+    if (heap_size >= heap_alloced) {
+	heap_alloced += 1000;
+	heap_index = (struct cost **) G_realloc((void *)heap_index, heap_alloced * sizeof(struct cost *));
+    }
+
+    heap_index[heap_size] = new_cell;
+    sift_up(heap_size, new_cell);
+
+    return (new_cell);
+}
+
+struct cost *get_lowest(void)
+{
+    struct cost *next_cell;
+    register unsigned int parent, child, childr, i;
+
+    if (heap_size == 0)
+	return NULL;
+	
+    next_cell = heap_index[1];
+    heap_index[0] = next_cell;
+
+    if (heap_size == 1) {
+	heap_size--;
+
+	heap_index[1] = NULL;
+
+	return next_cell;
+    }
+
+    /* start with root */
+    parent = 1;
+
+    /* sift down: move hole back towards bottom of heap */
+
+    while ((child = GET_CHILD(parent)) <= heap_size) {
+	/* select smallest child */
+	if (child < heap_size) {
+	    childr = child + 1;
+	    i = child + 3;
+	    while (childr < i && childr <= heap_size) {
+		/* get smallest child */
+		if (cmp_costs(heap_index[childr], heap_index[child])) {
+		    child = childr;
+		}
+		childr++;
+	    }
+	}
+
+	/* move hole down */
+	heap_index[parent] = heap_index[child];
+	parent = child;
+    }
+
+    /* hole is in lowest layer, move to heap end */
+    if (parent < heap_size) {
+	heap_index[parent] = heap_index[heap_size];
+
+	/* sift up last swapped point, only necessary if hole moved to heap end */
+	sift_up(parent, heap_index[parent]);
+    }
+
+    /* the actual drop */
+    heap_size--;
+
+    return next_cell;
+}
+
+int delete(struct cost *delete_cell)
+{
+    if (free_point)
+	G_free(delete_cell);
+    else
+	free_point = delete_cell;
+
+    return 0;
+}

Deleted: grass/trunk/raster/r.cost/local_proto.h
===================================================================
--- grass/trunk/raster/r.cost/local_proto.h	2009-11-05 07:40:20 UTC (rev 39682)
+++ grass/trunk/raster/r.cost/local_proto.h	2009-11-05 16:02:22 UTC (rev 39683)
@@ -1,34 +0,0 @@
-
-/****************************************************************************
- *
- * MODULE:       r.cost
- *
- * AUTHOR(S):    Antony Awaida - IESL - M.I.T.
- *               James Westervelt - CERL
- *               Pierre de Mouveaux <pmx audiovu com>
- *               Eric G. Miller <egm2 jps net>
- *
- * PURPOSE:      Outputs a raster map layer showing the cumulative cost
- *               of moving between different geographic locations on an
- *               input raster map layer whose cell category values
- *               represent cost.
- *
- * COPYRIGHT:    (C) 2006 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.
- *
- ***************************************************************************/
-
-#ifndef __LOCAL_PROTO_H__
-#define __LOCAL_PROTO_H__
-
-/* btree.c */
-int show_all(void);
-
-/* int check_all(char *); */
-/* main.c */
-/* int time_to_stop(int, int); */
-
-#endif /* __LOCAL_PROTO_H__ */

Modified: grass/trunk/raster/r.cost/main.c
===================================================================
--- grass/trunk/raster/r.cost/main.c	2009-11-05 07:40:20 UTC (rev 39682)
+++ grass/trunk/raster/r.cost/main.c	2009-11-05 16:02:22 UTC (rev 39683)
@@ -10,13 +10,15 @@
  *
  *               Updated for calculation errors and directional surface generation
  *                 Colin Nielsen <colin.nielsen gmail com>
+ *               Use min heap instead of btree (faster, less memory)
+ *                 Markus Metz
  *
  * PURPOSE:      Outputs a raster map layer showing the cumulative cost 
  *               of moving between different geographic locations on an 
  *               input raster map layer whose cell category values 
  *               represent cost.
  *
- * COPYRIGHT:    (C) 2006-2008 by the GRASS Development Team
+ * COPYRIGHT:    (C) 2006-2009 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
@@ -51,7 +53,7 @@
  * if "output" doesn't exist, but is expected (this is bad design).
  */
 
-#define SEGCOLSIZE 	256
+#define SEGCOLSIZE 	64
 
 #include <stdlib.h>
 #include <unistd.h>
@@ -66,7 +68,6 @@
 #include <grass/segment.h>
 #include "cost.h"
 #include "stash.h"
-#include "local_proto.h"
 #include <grass/glocale.h>
 
 struct Cell_head window;
@@ -524,10 +525,11 @@
 	}
     }
     /*   Scan the start_points layer searching for starting points.
-     *   Create a btree of starting points ordered by increasing costs.
+     *   Create a heap of starting points ordered by increasing costs.
      */
+    init_heap();
+    
     if (opt7->answer) {
-#if 1
 	struct Map_info *fp;
 	struct start_pt *new_start_pt;
 	Site *site = NULL;	/* pointer to Site */
@@ -574,11 +576,9 @@
 
 	if (!got_one)
 	    G_fatal_error(_("No start points"));
-#endif
     }
 
     if (opt8->answer) {
-#if 1
 	struct Map_info *fp;
 	struct start_pt *new_start_pt;
 	Site *site = NULL;	/* pointer to Site */
@@ -621,7 +621,6 @@
 
 	G_site_free_struct(site);
 	G_sites_close(fp);
-#endif
     }
 
     if (opt9->answer) {
@@ -703,10 +702,10 @@
 	/*              printf("--------+++++----------\n"); */
     }
 
-    /*  Loop through the btree and perform at each cell the following:
+    /*  Loop through the heap and perform at each cell the following:
      *   1) If an adjacent cell has not already been assigned a value compute
      *      the min cost and assign it.
-     *   2) Insert the adjacent cell in the btree.
+     *   2) Insert the adjacent cell in the heap.
      *   3) Free the memory allocated to the present cell.
      */
 
@@ -746,6 +745,8 @@
 	 *         12    11
 	 */
 	for (neighbor = 1; neighbor <= total_reviewed; neighbor++) {
+	    row = -1;
+	    col = -1;
 	    switch (neighbor) {
 	    case 1:
 		row = pres_cell->row;
@@ -753,6 +754,7 @@
 		cur_dir = 180.0;
 		break;
 	    case 2:
+		row = pres_cell->row;
 		col = pres_cell->col + 1;
 		cur_dir = 0.0;
 		break;
@@ -763,6 +765,7 @@
 		break;
 	    case 4:
 		row = pres_cell->row + 1;
+		col = pres_cell->col;
 		cur_dir = 270.0;
 		break;
 	    case 5:
@@ -771,14 +774,17 @@
 		cur_dir = 135.0;
 		break;
 	    case 6:
+		row = pres_cell->row - 1;
 		col = pres_cell->col + 1;
 		cur_dir = 45.0;
 		break;
 	    case 7:
 		row = pres_cell->row + 1;
+		col = pres_cell->col + 1;
 		cur_dir = 315.0;
 		break;
 	    case 8:
+		row = pres_cell->row + 1;
 		col = pres_cell->col - 1;
 		cur_dir = 225.0;
 		break;
@@ -788,14 +794,17 @@
 		cur_dir = 112.5;
 		break;
 	    case 10:
+		row = pres_cell->row - 2;
 		col = pres_cell->col + 1;
 		cur_dir = 67.5;
 		break;
 	    case 11:
 		row = pres_cell->row + 2;
+		col = pres_cell->col + 1;
 		cur_dir = 292.5;
 		break;
 	    case 12:
+		row = pres_cell->row + 2;
 		col = pres_cell->col - 1;
 		cur_dir = 247.5;
 		break;
@@ -805,14 +814,17 @@
 		cur_dir = 157.5;
 		break;
 	    case 14:
+		row = pres_cell->row - 1;
 		col = pres_cell->col + 2;
 		cur_dir = 22.5;
 		break;
 	    case 15:
 		row = pres_cell->row + 1;
+		col = pres_cell->col + 2;
 		cur_dir = 337.5;
 		break;
 	    case 16:
+		row = pres_cell->row + 1;
 		col = pres_cell->col - 2;
 		cur_dir = 202.5;
 		break;
@@ -964,17 +976,20 @@
 	    break;
 
 	ct = pres_cell;
+
 	delete(pres_cell);
 
 	pres_cell = get_lowest();
-	if (pres_cell == NULL) {
-	    G_message(_("No data"));
-	    goto OUT;
+
+	if (ct == pres_cell) {
+	    G_warning(_("Error, ct == pres_cell"));
 	}
-	if (ct == pres_cell)
-	    G_warning(_("Error, ct == pres_cell"));
     }
-  OUT:
+    G_percent(1, 1, 1);
+
+    /* free heap */
+    free_heap();
+    
     /*  Open cumulative cost layer for writing   */
 
     cum_fd = Rast_open_new(cum_cost_layer, data_type);

Deleted: grass/trunk/raster/r.cost/memory.c
===================================================================
--- grass/trunk/raster/r.cost/memory.c	2009-11-05 07:40:20 UTC (rev 39682)
+++ grass/trunk/raster/r.cost/memory.c	2009-11-05 16:02:22 UTC (rev 39683)
@@ -1,134 +0,0 @@
-
-/****************************************************************************
- *
- * MODULE:       r.cost
- *
- * AUTHOR(S):    Antony Awaida - IESL - M.I.T.
- *               James Westervelt - CERL
- *               Pierre de Mouveaux <pmx audiovu com>
- *               Eric G. Miller <egm2 jps net>
- *
- * PURPOSE:      Outputs a raster map layer showing the cumulative cost
- *               of moving between different geographic locations on an
- *               input raster map layer whose cell category values
- *               represent cost.
- *
- * COPYRIGHT:    (C) 2006 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 <string.h>
-#include <errno.h>
-#include <grass/gis.h>
-#include "memory.h"
-
-#define NUM_IN_BLOCK	1024*8
-
-
-struct cost *first_free = NULL;
-struct cost *first = NULL;
-struct cost *last = NULL;
-
-
-int allocate()
-{
-    struct cost *data, *p1, *p2;
-    int i;
-
-    /*      fprintf(stderr,"allocate()\n"); */
-
-    data = (struct cost *)G_malloc(NUM_IN_BLOCK * sizeof(struct cost));
-
-    if (data == NULL) {
-	/* G_warning( */
-	fprintf(stderr, "allocat(): error %s\n", strerror(errno));
-	return 0;
-    }
-
-    if (last != NULL) {
-	last->lower = data;
-	data->higher = last;
-    }
-
-
-    p1 = p2 = data;
-    p2++;
-
-    for (i = 1; i < NUM_IN_BLOCK - 1; i++, p1++, p2++) {
-	p1->lower = p2;
-	p2->higher = p1;
-	p1->above = NULL;
-    }
-    p2->higher = p1;
-    p2->above = NULL;
-    p2->lower = NULL;
-    last = p2;
-
-    if (first == NULL) {
-	first_free = data;
-	first = data;
-    }
-    else {
-	first_free->lower = data;
-    }
-
-    return 1;
-}
-
-int release()
-{
-    struct cost *p = first;
-    struct cost *next;
-
-    if (p == NULL)
-	return 1;
-
-    do {
-	next = (p + NUM_IN_BLOCK)->lower;
-	G_free(p);
-	p = next;
-    } while (next != NULL);
-
-    first = last = first_free = NULL;
-
-    return 0;
-}
-
-struct cost *get()
-{
-    struct cost *p;
-
-    if (first_free == NULL) {
-	if (allocate() < 0) {
-	    /* exit(1); */
-	}
-    }
-
-    p = first_free;
-    first_free = p->lower;
-    if (first_free->lower == NULL) {
-	if (allocate() < 0) {
-	    /* exit(1); */
-	}
-    }
-    return p;
-}
-
-int give(struct cost *p)
-{
-    if (p == NULL)
-	return 0;
-
-    p->lower = first_free;
-    first_free->above = p;
-    first_free = p;
-    p->above = NULL;		/* not used in this chain - (pmx) */
-
-    return 1;
-}

Deleted: grass/trunk/raster/r.cost/memory.h
===================================================================
--- grass/trunk/raster/r.cost/memory.h	2009-11-05 07:40:20 UTC (rev 39682)
+++ grass/trunk/raster/r.cost/memory.h	2009-11-05 16:02:22 UTC (rev 39683)
@@ -1,34 +0,0 @@
-
-/****************************************************************************
- *
- * MODULE:       r.cost
- *
- * AUTHOR(S):    Antony Awaida - IESL - M.I.T.
- *               James Westervelt - CERL
- *               Pierre de Mouveaux <pmx audiovu com>
- *               Eric G. Miller <egm2 jps net>
- *
- * PURPOSE:      Outputs a raster map layer showing the cumulative cost
- *               of moving between different geographic locations on an
- *               input raster map layer whose cell category values
- *               represent cost.
- *
- * COPYRIGHT:    (C) 2006 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.
- *
- ***************************************************************************/
-
-#ifndef  __R_COST_MEMORY__
-#define  __R_COST_MEMORY__
-
-#include "cost.h"
-
-int allocate();
-int release();
-struct cost *get();
-int give(struct cost *p);
-
-#endif /* __R_COST_MEMORY__ */

Modified: grass/trunk/raster/r.cost/stash.h
===================================================================
--- grass/trunk/raster/r.cost/stash.h	2009-11-05 07:40:20 UTC (rev 39682)
+++ grass/trunk/raster/r.cost/stash.h	2009-11-05 16:02:22 UTC (rev 39683)
@@ -13,7 +13,7 @@
  *               input raster map layer whose cell category values
  *               represent cost.
  *
- * COPYRIGHT:    (C) 2006 by the GRASS Development Team
+ * COPYRIGHT:    (C) 2006-2009 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



More information about the grass-commit mailing list