2
/****************************************************************************
6
* AUTHOR(S): Antony Awaida - IESL - M.I.T.
7
* James Westervelt - CERL
8
* Pierre de Mouveaux <pmx audiovu com>
9
* Eric G. Miller <egm2 jps net>
11
* min heap by Markus Metz
13
* PURPOSE: Outputs a raster map layer showing the cumulative cost
14
* of moving between different geographic locations on an
15
* input raster map layer whose cell category values
18
* COPYRIGHT: (C) 2006-2009 by the GRASS Development Team
20
* This program is free software under the GNU General Public
21
* License (>=v2). Read the file COPYING that comes with GRASS
24
***************************************************************************/
26
/* These routines manage the list of grid-cell candidates for
27
* visiting to calculate distances to surrounding cells.
28
* A min-heap approach is used. Components are
29
* sorted first by distance then by the order in which they were added.
32
* inserts a new row-col with its distance value into the heap
35
* deletes a row-col entry in the heap
38
* retrieves the entry with the smallest distance value
43
#include <grass/gis.h>
44
#include <grass/glocale.h>
47
#define GET_PARENT(c) (((c) - 2) / 3 + 1)
48
#define GET_CHILD(p) (((p) * 3) - 1)
50
static long next_point = 0;
51
static long heap_size = 0;
52
static long heap_alloced = 0;
53
static struct cost **heap_index, *free_point;
60
heap_index = (struct cost **) G_malloc(heap_alloced * sizeof(struct cost *));
79
* return 1 if a < b else 0 */
80
int cmp_costs(struct cost *a, struct cost *b)
82
if (a->min_cost < b->min_cost)
84
else if (a->min_cost == b->min_cost) {
92
long sift_up(long start, struct cost * child_pnt)
94
register long parent, child;
99
parent = GET_PARENT(child);
101
/* child is smaller */
102
if (cmp_costs(child_pnt, heap_index[parent])) {
103
/* push parent point down */
104
heap_index[child] = heap_index[parent];
108
/* no more sifting up, found new slot for child */
112
/* put point in new slot */
114
heap_index[child] = child_pnt;
120
struct cost *insert(double min_cost, int row, int col)
122
struct cost *new_cell;
125
new_cell = free_point;
129
new_cell = (struct cost *)(G_malloc(sizeof(struct cost)));
131
new_cell->min_cost = min_cost;
132
new_cell->age = next_point;
138
if (heap_size >= heap_alloced) {
139
heap_alloced += 1000;
140
heap_index = (struct cost **) G_realloc((void *)heap_index, heap_alloced * sizeof(struct cost *));
143
heap_index[heap_size] = new_cell;
144
sift_up(heap_size, new_cell);
149
struct cost *get_lowest(void)
151
struct cost *next_cell;
152
register long parent, child, childr, i;
157
next_cell = heap_index[1];
158
heap_index[0] = next_cell;
160
if (heap_size == 1) {
163
heap_index[1] = NULL;
168
/* start with root */
171
/* sift down: move hole back towards bottom of heap */
173
while ((child = GET_CHILD(parent)) <= heap_size) {
174
/* select smallest child */
175
if (child < heap_size) {
178
while (childr < i && childr <= heap_size) {
179
/* get smallest child */
180
if (cmp_costs(heap_index[childr], heap_index[child])) {
188
heap_index[parent] = heap_index[child];
192
/* hole is in lowest layer, move to heap end */
193
if (parent < heap_size) {
194
heap_index[parent] = heap_index[heap_size];
196
/* sift up last swapped point, only necessary if hole moved to heap end */
197
sift_up(parent, heap_index[parent]);
200
/* the actual drop */
206
int delete(struct cost *delete_cell)
211
free_point = delete_cell;