00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00184
00185 rval = EGpartialDijkstra (s, t, ubound, os, my_heap, G);
00186 CHECKRVAL (rval);
00187
00188 EGfreeHeap (my_heap, G->mem);
00189
00190
00191
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
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 }