eg_dijkstra_app.c

Go to the documentation of this file.
00001 /* EGlib "Efficient General Library" provides some basic structures and
00002  * algorithms commons in many optimization algorithms.
00003  *
00004  * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea.
00005  * 
00006  * This library is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation; either version 2.1 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful, but 
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00013  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this library; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00019  * */
00020 #include "eg_dijkstra_app.h"
00021 
00022 EGdijkstraEdgeData_t *EGnewDijkstraEdgeData (EGmemPool_t * mem)
00023 {
00024   EGdijkstraEdgeData_t *ed;
00025   ed =
00026     (EGdijkstraEdgeData_t *) EGmemPoolMalloc (mem,
00027                                               sizeof (EGdijkstraEdgeData_t));
00028   *ed = 0;
00029   return (ed);
00030 }
00031 
00032 EGdijkstraNodeData_t *EGnewDijkstraNodeData (EGmemPool_t * mem)
00033 {
00034   EGdijkstraNodeData_t *nd;
00035   nd =
00036     (EGdijkstraNodeData_t *) EGmemPoolMalloc (mem,
00037                                               sizeof (EGdijkstraNodeData_t));
00038   nd->dist = EG_DIJKSTRA_COST_MAX;
00039   nd->ndist = UINT_MAX;
00040   nd->marker = UINT_MAX;
00041   nd->father = 0;
00042   nd->hc = 0;
00043   return nd;
00044 }
00045 
00046 void EGfreeDijkstraEdgeDataMP (void *v,
00047                                EGmemPool_t * mem)
00048 {
00049   if (v)
00050     EGmemPoolFree (v, sizeof (EGdijkstraCost_t), mem);
00051   return;
00052 }
00053 
00054 void EGfreeDijkstraNodeDataMP (void *v,
00055                                EGmemPool_t * mem)
00056 {
00057   if (v)
00058     EGmemPoolFree (v, sizeof (EGdijkstraNodeData_t), mem);
00059   return;
00060 }
00061 
00062 EGdGraph_t *EGnewDijkstraDGraph (EGmemPool_t * mem,
00063                                  unsigned int nnodes,
00064                                  unsigned int nedges,
00065                                  unsigned int *edges,
00066                                  EGdijkstraCost_t * weight)
00067 {
00068 
00069   unsigned int i;
00070   EGdGraphNode_t **lnode;
00071   EGdGraphEdge_t **ledge;
00072   EGdGraph_t *G;
00073 
00074   G = EGnewDGraph (mem);
00075   lnode =
00076     (EGdGraphNode_t **) EGmemPoolMalloc (mem,
00077                                          sizeof (EGdGraphNode_t *) * nnodes);
00078   ledge =
00079     (EGdGraphEdge_t **) EGmemPoolMalloc (mem,
00080                                          sizeof (EGdGraphEdge_t *) * 2 *
00081                                          nedges);
00082 
00083   for (i = 0; i < nnodes; i++)
00084   {
00085     lnode[i] = EGdGraphAddNode (G, 0);
00086     lnode[i]->data = EGnewDijkstraNodeData (mem);
00087   }
00088 
00089   for (i = 0; i < nedges; i++)
00090   {
00091     ledge[2 * i] =
00092       EGdGraphAddEdge (G, 0, lnode[edges[2 * i]], lnode[edges[2 * i + 1]]);
00093     ledge[2 * i]->data =
00094       (EGdijkstraCost_t *) EGmemPoolMalloc (mem, sizeof (EGdijkstraCost_t));
00095     *((EGdijkstraEdgeData_t *) (ledge[2 * i]->data)) = weight[i];
00096 
00097     ledge[2 * i + 1] =
00098       EGdGraphAddEdge (G, 0, lnode[edges[2 * i + 1]], lnode[edges[2 * i]]);
00099     ledge[2 * i + 1]->data =
00100       (EGdijkstraCost_t *) EGmemPoolMalloc (mem, sizeof (EGdijkstraCost_t));
00101     *((EGdijkstraEdgeData_t *) (ledge[2 * i + 1]->data)) = weight[i];
00102 
00103   }
00104 
00105   EGmemPoolFree (lnode, sizeof (EGdGraphNode_t *) * nnodes, mem);
00106   EGmemPoolFree (ledge, sizeof (EGdGraphEdge_t *) * nedges, mem);
00107 
00108   return (G);
00109 
00110 }
00111 
00112 EGdGraph_t *EGnewDijkstraDGraph_simple (EGmemPool_t * mem,
00113                                         unsigned int nnodes,
00114                                         unsigned int nedges,
00115                                         unsigned int *edges,
00116                                         EGdijkstraCost_t * weight)
00117 {
00118 
00119   unsigned int i;
00120   EGdGraphNode_t **lnode;
00121   EGdGraphEdge_t *edge;
00122   EGdGraph_t *G;
00123 
00124   G = EGnewDGraph (mem);
00125   lnode =
00126     (EGdGraphNode_t **) EGmemPoolMalloc (mem,
00127                                          sizeof (EGdGraphNode_t *) * nnodes);
00128 
00129   for (i = 0; i < nnodes; i++)
00130   {
00131     lnode[i] = EGdGraphAddNode (G, 0);
00132     lnode[i]->data = EGnewDijkstraNodeData (mem);
00133   }
00134 
00135   for (i = 0; i < nedges; i++)
00136   {
00137     edge = EGdGraphAddEdge (G, 0, lnode[edges[2 * i + 1]], lnode[edges[2 * i]]);
00138     edge->data =
00139       (EGdijkstraCost_t *) EGmemPoolMalloc (mem, sizeof (EGdijkstraCost_t));
00140     *((EGdijkstraEdgeData_t *) (edge->data)) = weight[i];
00141   }
00142 
00143   EGmemPoolFree (lnode, sizeof (EGdGraphNode_t *) * nnodes, mem);
00144 
00145   return (G);
00146 
00147 }
00148 
00149 void EGdijkstraClearDGraphMP (void *v,
00150                               EGmemPool_t * mem)
00151 {
00152   EGdGraphClearMP ((EGdGraph_t *) v, EGfreeDijkstraEdgeDataMP,
00153                    EGfreeDijkstraNodeDataMP, 0, mem, mem, 0);
00154   return;
00155 }
00156 
00157 int EGdijkstraShortestPath (EGdGraphNode_t * s,
00158                             EGdGraphNode_t * t,
00159                             EGdijkstraCost_t ubound,
00160                             EGdijkstraCost_t * dist,
00161                             EGdGraphEdge_t * prec,
00162                             EGdGraph_t * G)
00163 {
00164 
00165   unsigned int rval;
00166   size_t os[5];
00167   EGheap_t *my_heap;
00168 
00169   TEST (s == t, "s must be different than t");
00170   TEST (!dist, "dist is null");
00171   TEST (!prec, "prec is null");
00172   TEST (!G, "G is null");
00173 
00174   os[EG_DIJ_DIST] = offsetof (EGdijkstraNodeData_t, dist);
00175   os[EG_DIJ_NDIST] = offsetof (EGdijkstraNodeData_t, ndist);
00176   os[EG_DIJ_FATHER] = offsetof (EGdijkstraNodeData_t, father);
00177   os[EG_DIJ_MARKER] = offsetof (EGdijkstraNodeData_t, marker);
00178   os[EG_DIJ_HCONNECTOR] = offsetof (EGdijkstraNodeData_t, hc);
00179   os[EG_DIJ_ELENGTH] = 0;
00180 
00181   my_heap = EGnewHeap (G->mem, 3, G->nodes->size);
00182 
00183   //EGdGraphDisplay(G, 0, EGdijkstraDisplayNode, EGdijkstraDisplayEdge, stderr);
00184 
00185   rval = EGpartialDijkstra (s, t, ubound, os, my_heap, G);
00186   CHECKRVAL (rval);
00187 
00188   EGfreeHeap (my_heap, G->mem);
00189 
00190   //if (t) fprintf(stderr, "Solution: d(s,t) = %lf\n", EGdijkstraGetDist(t, os));
00191   //EGdGraphDisplay(G, 0, EGdijkstraDisplayNode, EGdijkstraDisplayEdge, stderr);
00192   return 0;
00193 
00194 }
00195 
00196 void EGdijkstraDisplayNode (void *v,
00197                             FILE * file)
00198 {
00199 
00200   EGdijkstraNodeData_t *nd;
00201 
00202   nd = (EGdijkstraNodeData_t *) v;
00203 
00204   fprintf (file, "d=%lf, nd=%u, m=%u, f=%p, hc=%p",
00205            EGdijkstraCostToLf (nd->dist), (unsigned int) (nd->ndist),
00206            (unsigned int) (nd->marker), (void *) nd->father, (void *) nd->hc);
00207 
00208   return;
00209 
00210 }
00211 
00212 void EGdijkstraDisplayEdge (void *v,
00213                             FILE * file)
00214 {
00215 
00216   EGdijkstraEdgeData_t *ed;
00217 
00218   ed = (EGdijkstraEdgeData_t *) v;
00219 
00220   fprintf (file, "%lf", EGdijkstraCostToLf (*ed));
00221 
00222   return;
00223 
00224 }
00225 
00226 EGdGraph_t *EGdijkstraLoadGraph (FILE * file,
00227                                  EGmemPool_t * mem)
00228 {
00229 
00230   unsigned int i;
00231   unsigned int *edges;
00232   double w;
00233   EGdijkstraCost_t *weight;
00234   unsigned int nnodes,
00235     nedges;
00236 
00237   EGdGraph_t *dg;
00238 
00239   fscanf (file, "%u %u", &nnodes, &nedges);
00240   edges = EGmemPoolSMalloc (mem, unsigned int,
00241                             2 * nedges);
00242   weight = EGmemPoolSMalloc (mem, EGdijkstraCost_t, nedges);
00243 
00244   for (i = 0; i < nedges; i++)
00245   {
00246     fscanf (file, "%u %u %lf", &edges[2 * i], &edges[2 * i + 1], &w);
00247     weight[i] = EGdijkstraToCost (w);
00248     ADVTESTL (1, edges[2 * i] > (nnodes - 1), 0,
00249               "Edge %u (head) out of bounds", i);
00250     ADVTESTL (1, edges[2 * i + 1] > (nnodes - 1), 0,
00251               "Edge %u (tail) out of bounds", i);
00252   }
00253 
00254   dg = EGnewDijkstraDGraph_simple (mem, nnodes, nedges, edges, weight);
00255 
00256   EGmemPoolSFree (edges, unsigned int,
00257                   2 * nedges,
00258                   mem);
00259   EGmemPoolSFree (weight, EGdijkstraCost_t, nedges, mem);
00260 
00261   return dg;
00262 
00263 }
00264 
00265 /* assumes that *path is not allocated */
00266 int EGdijkstraGetOptimalPath (EGdGraph_t * G,
00267                               EGdGraphNode_t * t,
00268                               size_t * os,
00269                               unsigned int *npath,
00270                               EGdGraphEdge_t *** path,
00271                               EGmemPool_t * mem)
00272 {
00273 
00274   if (EGdijkstraGetNdist (t, os) == 0)
00275   {
00276     *path = 0;
00277     *npath = 0;
00278     return 0;
00279   }
00280 
00281   EGdGraphNode_t *node;
00282 
00283   *npath = EGdijkstraGetNdist (t, os);
00284   *path = EGmemPoolSMalloc (mem, EGdGraphEdge_t *, *npath);
00285 
00286   node = t;
00287 
00288   while (EGdijkstraGetNdist (node, os) != 0)
00289   {
00290     (*path)[EGdijkstraGetNdist (node, os) - 1] = EGdijkstraGetFather (node, os);
00291     node = (EGdijkstraGetFather (node, os))->tail;
00292   }
00293 
00294   return 0;
00295 
00296 }

Generated on Mon Jan 30 08:48:52 2006 for EGlib by  doxygen 1.4.5