|
Graphviz
2.29.20120524.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 00015 #include "vis.h" 00016 00017 #ifdef DMALLOC 00018 #include "dmalloc.h" 00019 #endif 00020 00021 static COORD unseen = (double) INT_MAX; 00022 00023 /* shortestPath: 00024 * Given a VxV weighted adjacency matrix, compute the shortest 00025 * path vector from root to target. The returned vector (dad) encodes the 00026 * shorted path from target to the root. That path is given by 00027 * i, dad[i], dad[dad[i]], ..., root 00028 * We have dad[root] = -1. 00029 * 00030 * Based on Dijkstra's algorithm (Sedgewick, 2nd. ed., p. 466). 00031 * 00032 * This implementation only uses the lower left triangle of the 00033 * adjacency matrix, i.e., the values a[i][j] where i >= j. 00034 */ 00035 int *shortestPath(int root, int target, int V, array2 wadj) 00036 { 00037 int *dad; 00038 COORD *vl; 00039 COORD *val; 00040 int min; 00041 int k, t; 00042 00043 /* allocate arrays */ 00044 dad = (int *) malloc(V * sizeof(int)); 00045 vl = (COORD *) malloc((V + 1) * sizeof(COORD)); /* One extra for sentinel */ 00046 val = vl + 1; 00047 00048 /* initialize arrays */ 00049 for (k = 0; k < V; k++) { 00050 dad[k] = -1; 00051 val[k] = -unseen; 00052 } 00053 val[-1] = -(unseen + (COORD) 1); /* Set sentinel */ 00054 min = root; 00055 00056 /* use (min >= 0) to fill entire tree */ 00057 while (min != target) { 00058 k = min; 00059 val[k] *= -1; 00060 min = -1; 00061 if (val[k] == unseen) 00062 val[k] = 0; 00063 00064 for (t = 0; t < V; t++) { 00065 if (val[t] < 0) { 00066 COORD newpri; 00067 COORD wkt; 00068 00069 /* Use lower triangle */ 00070 if (k >= t) 00071 wkt = wadj[k][t]; 00072 else 00073 wkt = wadj[t][k]; 00074 00075 newpri = -(val[k] + wkt); 00076 if ((wkt != 0) && (val[t] < newpri)) { 00077 val[t] = newpri; 00078 dad[t] = k; 00079 } 00080 if (val[t] > val[min]) 00081 min = t; 00082 } 00083 } 00084 } 00085 00086 free(vl); 00087 return dad; 00088 } 00089 00090 /* makePath: 00091 * Given two points p and q in two polygons pp and qp of a vconfig_t conf, 00092 * and the visibility vectors of p and q relative to conf, 00093 * compute the shortest path from p to q. 00094 * If dad is the returned array and V is the number of polygon vertices in 00095 * conf, then the path is V(==q), dad[V], dad[dad[V]], ..., V+1(==p). 00096 * NB: This is the only path that is guaranteed to be valid. 00097 * We have dad[V+1] = -1. 00098 * 00099 */ 00100 int *makePath(Ppoint_t p, int pp, COORD * pvis, 00101 Ppoint_t q, int qp, COORD * qvis, vconfig_t * conf) 00102 { 00103 int V = conf->N; 00104 00105 if (directVis(p, pp, q, qp, conf)) { 00106 int *dad = (int *) malloc(sizeof(int) * (V + 2)); 00107 dad[V] = V + 1; 00108 dad[V + 1] = -1; 00109 return dad; 00110 } else { 00111 array2 wadj = conf->vis; 00112 wadj[V] = qvis; 00113 wadj[V + 1] = pvis; 00114 return (shortestPath(V + 1, V, V + 2, wadj)); 00115 } 00116 }
1.7.5