Graphviz 14.1.2~dev.20260123.1158
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 "config.h"
12
13#include <pathplan/vis.h>
14#include <util/alloc.h>
15
16static COORD unseen = INT_MAX;
17
18/* shortestPath:
19 * Given a VxV weighted adjacency matrix, compute the shortest
20 * path vector from root to target. The returned vector (dad) encodes the
21 * shorted path from target to the root. That path is given by
22 * i, dad[i], dad[dad[i]], ..., root
23 * We have dad[root] = -1.
24 *
25 * Based on Dijkstra's algorithm (Sedgewick, 2nd. ed., p. 466).
26 *
27 * This implementation only uses the lower left triangle of the
28 * adjacency matrix, i.e., the values a[i][j] where i >= j.
29 */
30static int *shortestPath(int root, int target, int V, array2 wadj)
31{
32 COORD *val;
33 int min;
34 int k, t;
35
36 /* allocate arrays */
37 int *dad = gv_calloc(V, sizeof(int));
38 COORD *vl = gv_calloc(V + 1, sizeof(COORD)); // One extra for sentinel
39 val = vl + 1;
40
41 /* initialize arrays */
42 for (k = 0; k < V; k++) {
43 dad[k] = -1;
44 val[k] = -unseen;
45 }
46 val[-1] = -(unseen + (COORD) 1); /* Set sentinel */
47 min = root;
48
49 /* use (min >= 0) to fill entire tree */
50 while (min != target) {
51 k = min;
52 val[k] *= -1;
53 min = -1;
54 if (val[k] == unseen)
55 val[k] = 0;
56
57 for (t = 0; t < V; t++) {
58 if (val[t] < 0) {
59 COORD newpri;
60 COORD wkt;
61
62 /* Use lower triangle */
63 if (k >= t)
64 wkt = wadj[k][t];
65 else
66 wkt = wadj[t][k];
67
68 newpri = -(val[k] + wkt);
69 if ((wkt != 0) && (val[t] < newpri)) {
70 val[t] = newpri;
71 dad[t] = k;
72 }
73 if (val[t] > val[min])
74 min = t;
75 }
76 }
77 }
78
79 free(vl);
80 return dad;
81}
82
83/* makePath:
84 * Given two points p and q in two polygons pp and qp of a vconfig_t conf,
85 * and the visibility vectors of p and q relative to conf,
86 * compute the shortest path from p to q.
87 * If dad is the returned array and V is the number of polygon vertices in
88 * conf, then the path is V(==q), dad[V], dad[dad[V]], ..., V+1(==p).
89 * NB: This is the only path that is guaranteed to be valid.
90 * We have dad[V+1] = -1.
91 *
92 */
93int *makePath(Ppoint_t p, int pp, COORD * pvis,
94 Ppoint_t q, int qp, COORD * qvis, vconfig_t * conf)
95{
96 int V = conf->N;
97
98 if (directVis(p, pp, q, qp, conf)) {
99 int *dad = gv_calloc(V + 2, sizeof(int));
100 dad[V] = V + 1;
101 dad[V + 1] = -1;
102 return dad;
103 } else {
104 array2 wadj = conf->vis;
105 wadj[V] = qvis;
106 wadj[V + 1] = pvis;
107 return (shortestPath(V + 1, V, V + 2, wadj));
108 }
109}
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:93
static int * shortestPath(int root, int target, int V, array2 wadj)
Definition shortestpth.c:30
static COORD unseen
Definition shortestpth.c:16
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:306