00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "eg_dijkstra.h"
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 int EGpartialDijkstra (EGdGraphNode_t * s,
00063 EGdGraphNode_t * t,
00064 EGdijkstraCost_t ubound,
00065 size_t * os,
00066 EGheap_t * my_heap,
00067 EGdGraph_t * G)
00068 {
00069 unsigned int tmarked = 0;
00070 EGdijkstraCost_t value = EGdijkstraToCost (0.0);
00071 EGdGraphEdge_t *e;
00072 EGdGraphNode_t *best_node;
00073 EGlistNode_t *node_it,
00074 *edge_it;
00075 EGheapConnector_t *h_c;
00076
00077 EGmemPool_t *mem;
00078
00079 mem = s->out_edges->mempool;
00080
00081 #if EG_DIJKSTRA_NEGATIVE_CHECK
00082 for (node_it = G->nodes->begin; node_it; node_it = node_it->next)
00083 {
00084 best_node = (EGdGraphNode_t *) (node_it->this);
00085 for (edge_it = best_node->out_edges->begin; edge_it;
00086 edge_it = edge_it->next)
00087 {
00088 e = (EGdGraphEdge_t *) (edge_it->this);
00089 if (EGdijkstraCostToLf (EGdijkstraGetEdgeLength (e, os)) < 0.0)
00090 {
00091 fprintf (stderr,
00092 "\n\nwarning: found negative weight edge in dijkstra of value %lf.\n",
00093 EGdijkstraCostToLf (EGdijkstraGetEdgeLength (e, os)));
00094 TEST (1, "negative edge");
00095 return 1;
00096 }
00097 }
00098
00099 }
00100 #endif
00101
00102
00103
00104
00105 if (t)
00106 EGdijkstraSetDist (t, os, EG_DIJKSTRA_COST_MAX);
00107 for (node_it = G->nodes->begin; node_it; node_it = node_it->next)
00108 {
00109 EGdijkstraSetHeapConnector (node_it->this, os, 0);
00110 EGdijkstraSetMarker (node_it->this, os, UINT_MAX);
00111 }
00112
00113
00114
00115
00116
00117 EGheapClear (my_heap, mem);
00118 h_c = EGheapInsert (my_heap, s, 0, mem);
00119
00120
00121 EGdijkstraSetDist (s, os, EGdijkstraToCost (0.0));
00122
00123
00124 EGdijkstraSetNdist (s, os, 0);
00125
00126
00127 EGdijkstraSetFather (s, os, 0);
00128
00129
00130 EGdijkstraSetHeapConnector (s, os, h_c);
00131
00132 while (my_heap->size != 0)
00133 {
00134
00135
00136
00137
00138 h_c = EGheapGetMin (my_heap);
00139 best_node = (EGdGraphNode_t *) (h_c->this);
00140 EGheapDeleteMin (my_heap, mem);
00141 EGdijkstraSetMarker (best_node, os, tmarked);
00142 tmarked += 1;
00143 EGdijkstraSetHeapConnector (best_node, os, 0);
00144
00145
00146
00147
00148
00149 if (t
00150 &&
00151 EGdijkstraCostIsLess (EGdijkstraCostSub
00152 (EGdijkstraGetDist (t, os),
00153 EGdijkstraGetDist (best_node, os)),
00154 EG_DIJKSTRA_OPTERROR))
00155 break;
00156
00157 if (EGdijkstraCostIsLess (ubound, EGdijkstraGetDist (best_node, os)))
00158 return 0;
00159
00160
00161
00162
00163 for (edge_it = best_node->out_edges->begin; edge_it;
00164 edge_it = edge_it->next)
00165 {
00166
00167 e = (EGdGraphEdge_t *) (edge_it->this);
00168 TESTL (5, EGdijkstraCostToLf (EGdijkstraGetEdgeLength (e, os)) < 0,
00169 "Negative edge");
00170 value =
00171 EGdijkstraCostAdd (EGdijkstraGetDist (best_node, os),
00172 EGdijkstraGetEdgeLength (e, os));
00173
00174
00175
00176
00177 if (EGdijkstraGetMarker (e->head, os) == UINT_MAX)
00178 {
00179 EGdijkstraSetFather (e->head, os, e);
00180 EGdijkstraSetNdist (e->head, os,
00181 EGdijkstraGetNdist (best_node, os) + 1);
00182 EGdijkstraSetDist (e->head, os, value);
00183 h_c = EGheapInsert (my_heap, e->head, value, mem);
00184 EGdijkstraSetHeapConnector (e->head, os, h_c);
00185 EGdijkstraSetMarker (e->head, os, UINT_MAX - 1);
00186 }
00187
00188
00189
00190
00191
00192 else
00193 if (EGdijkstraCostIsLess
00194 (EGdijkstraCostAdd (value, EG_DIJKSTRA_EPSILON),
00195 EGdijkstraGetDist (e->head, os)))
00196 {
00197
00198 EGdijkstraSetFather (e->head, os, e);
00199 EGdijkstraSetNdist (e->head, os,
00200 EGdijkstraGetNdist (best_node, os) + 1);
00201 EGdijkstraSetDist (e->head, os, value);
00202 EGheapDecreaseVal (my_heap, EGdijkstraGetHeapConnector (e->head, os),
00203 value);
00204 }
00205
00206 }
00207
00208 }
00209
00210 return 0;
00211
00212 }
00213
00214 int EGdijkstraCheckOptimality (EGdGraphNode_t * s,
00215 EGdGraphNode_t * t,
00216 EGdijkstraCost_t ubound,
00217 size_t * os,
00218 EGdGraph_t * G)
00219 {
00220
00221 EGlistNode_t *n_it,
00222 *e_it;
00223 EGdGraphEdge_t *e;
00224 EGdGraphNode_t *n;
00225 unsigned int hid,
00226 tid;
00227 double vh,
00228 vt,
00229 ve;
00230
00231 s = 0;
00232 t = 0;
00233 ubound = 0;
00234
00235 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00236 {
00237 n = (EGdGraphNode_t *) (n_it->this);
00238 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00239 {
00240 e = (EGdGraphEdge_t *) (e_it->this);
00241 if (EGdijkstraGetDist (e->head, os) >
00242 (EGdijkstraGetDist (e->tail, os) + EGdijkstraGetEdgeLength (e, os)))
00243 {
00244 hid = e->head->id;
00245 tid = e->tail->id;
00246 vh = EGdijkstraCostToLf (EGdijkstraGetDist (e->head, os));
00247 vt = EGdijkstraCostToLf (EGdijkstraGetDist (e->tail, os));
00248 ve = EGdijkstraCostToLf (EGdijkstraGetEdgeLength (e, os));
00249 fprintf (stderr,
00250 "c(%u) = %lf c(%u) = %lf c(%u, %u) = %lf c(%u) + c(%u,%u) = %lf\n",
00251 tid, vt, hid, vh, tid, hid, ve, tid, tid, hid, vt + ve);
00252 return 1;
00253 }
00254 }
00255 }
00256
00257 return 0;
00258
00259 }
00260
00261 int EGdijkstraExtractSolution (EGdGraphEdge_t ** path,
00262 unsigned int *npath,
00263 EGdGraphNode_t * s,
00264 EGdGraphNode_t * t,
00265 size_t * os)
00266 {
00267
00268 EGdGraphEdge_t *e;
00269 EGdGraphNode_t *n;
00270 unsigned int pos;
00271
00272 s = 0;
00273 *npath = 0;
00274
00275 n = t;
00276 pos = EGdijkstraGetNdist (t, os);
00277 while (pos)
00278 {
00279 e = EGdijkstraGetFather (n, os);
00280 path[pos - 1] = e;
00281 n = e->tail;
00282 pos = EGdijkstraGetNdist (n, os);
00283 *npath += 1;
00284 }
00285
00286 return 0;
00287
00288 }