/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/pathplan/shortestpth.c

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

Generated on Mon Mar 31 19:03:28 2008 for Graphviz by  doxygen 1.5.1