Graphviz 12.0.1~dev.20240716.0800
Loading...
Searching...
No Matches
shortestpth.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <cgraph/alloc.h>
12#include <pathplan/vis.h>
13
14static COORD unseen = (double) INT_MAX;
15
16/* shortestPath:
17 * Given a VxV weighted adjacency matrix, compute the shortest
18 * path vector from root to target. The returned vector (dad) encodes the
19 * shorted path from target to the root. That path is given by
20 * i, dad[i], dad[dad[i]], ..., root
21 * We have dad[root] = -1.
22 *
23 * Based on Dijkstra's algorithm (Sedgewick, 2nd. ed., p. 466).
24 *
25 * This implementation only uses the lower left triangle of the
26 * adjacency matrix, i.e., the values a[i][j] where i >= j.
27 */
28static int *shortestPath(int root, int target, int V, array2 wadj)
29{
30 COORD *val;
31 int min;
32 int k, t;
33
34 /* allocate arrays */
35 int *dad = gv_calloc(V, sizeof(int));
36 COORD *vl = gv_calloc(V + 1, sizeof(COORD)); // One extra for sentinel
37 val = vl + 1;
38
39 /* initialize arrays */
40 for (k = 0; k < V; k++) {
41 dad[k] = -1;
42 val[k] = -unseen;
43 }
44 val[-1] = -(unseen + (COORD) 1); /* Set sentinel */
45 min = root;
46
47 /* use (min >= 0) to fill entire tree */
48 while (min != target) {
49 k = min;
50 val[k] *= -1;
51 min = -1;
52 if (val[k] == unseen)
53 val[k] = 0;
54
55 for (t = 0; t < V; t++) {
56 if (val[t] < 0) {
57 COORD newpri;
58 COORD wkt;
59
60 /* Use lower triangle */
61 if (k >= t)
62 wkt = wadj[k][t];
63 else
64 wkt = wadj[t][k];
65
66 newpri = -(val[k] + wkt);
67 if ((wkt != 0) && (val[t] < newpri)) {
68 val[t] = newpri;
69 dad[t] = k;
70 }
71 if (val[t] > val[min])
72 min = t;
73 }
74 }
75 }
76
77 free(vl);
78 return dad;
79}
80
81/* makePath:
82 * Given two points p and q in two polygons pp and qp of a vconfig_t conf,
83 * and the visibility vectors of p and q relative to conf,
84 * compute the shortest path from p to q.
85 * If dad is the returned array and V is the number of polygon vertices in
86 * conf, then the path is V(==q), dad[V], dad[dad[V]], ..., V+1(==p).
87 * NB: This is the only path that is guaranteed to be valid.
88 * We have dad[V+1] = -1.
89 *
90 */
91int *makePath(Ppoint_t p, int pp, COORD * pvis,
92 Ppoint_t q, int qp, COORD * qvis, vconfig_t * conf)
93{
94 int V = conf->N;
95
96 if (directVis(p, pp, q, qp, conf)) {
97 int *dad = gv_calloc(V + 2, sizeof(int));
98 dad[V] = V + 1;
99 dad[V + 1] = -1;
100 return dad;
101 } else {
102 array2 wadj = conf->vis;
103 wadj[V] = qvis;
104 wadj[V + 1] = pvis;
105 return (shortestPath(V + 1, V, V + 2, wadj));
106 }
107}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
#define V
Definition gdefs.h:5
void free(void *)
double COORD
Definition pathutil.h:31
int * makePath(Ppoint_t p, int pp, COORD *pvis, Ppoint_t q, int qp, COORD *qvis, vconfig_t *conf)
Definition shortestpth.c:91
static int * shortestPath(int root, int target, int V, array2 wadj)
Definition shortestpth.c:28
static COORD unseen
Definition shortestpth.c:14
int N
Definition vis.h:31
array2 vis
Definition vis.h:38
COORD ** array2
Definition vis.h:25
VIS_API bool directVis(Ppoint_t, int, Ppoint_t, int, vconfig_t *)
Definition visibility.c:304