00001 #include "eg_menger.h"
00002
00003
00004 int EGmengerUpdateResidualGraph (EGdGraph_t * G,
00005 EGdGraphEdge_t * e,
00006 size_t * os)
00007 {
00008
00009 EGdGraphNode_t *swap;
00010 EGdijkstraCost_t cost;
00011
00012
00013 EGdGraphUnattachEdge (G, e);
00014
00015
00016 cost =
00017 EGdijkstraCostMul (EGdijkstraToCost (-1.0), EGmengerGetEdgeCost (e, os));
00018 EGmengerSetEdgeCost (e, os, cost);
00019
00020
00021 swap = e->head;
00022 e->head = e->tail;
00023 e->tail = swap;
00024
00025
00026 EGdGraphAttachEdge (G, e);
00027
00028 return 0;
00029
00030 }
00031
00032 int EGmengerRecoverGraphAndSolution (EGdGraph_t * G,
00033 size_t * os,
00034 EGdGraphNode_t * s,
00035 EGdGraphNode_t * t,
00036 unsigned int npath,
00037 EGdGraphEdge_t ** path,
00038 unsigned int *path_beg)
00039 {
00040
00041 unsigned int i,
00042 pos;
00043 EGlistNode_t *n_it,
00044 *e_it;
00045 EGdGraphNode_t *n;
00046 EGdGraphEdge_t *e;
00047
00048 path_beg[0] = pos = 0;
00049 for (i = 0; i < npath; i++)
00050 {
00051 n = s;
00052 n_it = n->cn;
00053 while (n_it != t->cn)
00054 {
00055 for (e_it = n->in_edges->begin; e_it; e_it = e_it->next)
00056 {
00057 e = (EGdGraphEdge_t *) (e_it->this);
00058 if (EGmengerGetEdgeIsInSolution (e, os))
00059 {
00060 n = e->tail;
00061 n_it = n->cn;
00062 EGmengerSetEdgeIsInSolution (e, os, 0);
00063 EGmengerUpdateResidualGraph (G, e, os);
00064 path[pos++] = e;
00065 break;
00066 }
00067 }
00068 TEST (!e_it, "edge in solution not found for path %u", i);
00069 }
00070 path_beg[i + 1] = pos;
00071 }
00072
00073 return 0;
00074
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 int EGmengerPathsADV (EGdGraphNode_t * s,
00094 EGdGraphNode_t * t,
00095 EGdijkstraCost_t ubound,
00096 unsigned int npaths,
00097 unsigned int *nfpaths,
00098 EGdijkstraCost_t * menger_val,
00099 EGheap_t * dij_heap,
00100 size_t * os,
00101 EGdGraph_t * G)
00102 {
00103
00104
00105 int rval;
00106 unsigned int i;
00107 size_t dij_os[6];
00108
00109
00110
00111 unsigned int f,
00112 path_nedges;
00113 EGdGraphNode_t *n;
00114 EGdGraphEdge_t *e;
00115
00116 EGlistNode_t *n_it,
00117 *e_it;
00118 EGdijkstraCost_t prev_flow_val,
00119 dij_ubound,
00120 rcost,
00121 pi;
00122
00123
00124 *nfpaths = 0;
00125
00126
00127 dij_os[EG_DIJ_DIST] = os[EG_MENGER_DIST];
00128 dij_os[EG_DIJ_NDIST] = os[EG_MENGER_NDIST];
00129 dij_os[EG_DIJ_FATHER] = os[EG_MENGER_FATHER];
00130 dij_os[EG_DIJ_MARKER] = os[EG_MENGER_MARK];
00131 dij_os[EG_DIJ_HCONNECTOR] = os[EG_MENGER_HEAP_CONNECTOR];
00132 dij_os[EG_DIJ_ELENGTH] = os[EG_MENGER_REDUCED_ECOST];
00133
00134
00135 if (s->out_edges->size < npaths)
00136 goto NO_SOLUTION;
00137
00138
00139 if (t->in_edges->size < npaths)
00140 goto NO_SOLUTION;
00141
00142
00143 if (npaths * EGdijkstraCostToLf (EGmengerGetOrigDist (t, os)) >
00144 EGdijkstraCostToLf (ubound))
00145 goto NO_SOLUTION;
00146
00147 #if EG_MENGER_SAFEMODE > 1
00148
00149
00150
00151 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00152 {
00153 n = (EGdGraphNode_t *) (n_it->this);
00154 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00155 {
00156 e = (EGdGraphEdge_t *) (e_it->this);
00157 TEST (EGdijkstraCostIsLess
00158 (EGmengerGetEdgeCost (e, os), EGdijkstraToCost (0.0)),
00159 "negative edge");
00160 }
00161
00162 }
00163
00164 #endif
00165
00166
00167
00168
00169
00170
00171 *menger_val = prev_flow_val = EGmengerGetOrigDist (t, os);
00172
00173
00174 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00175 EGmengerSetPi (n_it->this, os,
00176 EGdijkstraCostMinus (EGmengerGetOrigDist (n_it->this, os)));
00177
00178
00179 n = t;
00180 path_nedges = EGmengerGetOrigNdist (n, os);
00181
00182 for (i = 0; i < path_nedges; i++)
00183 {
00184 e = EGmengerGetOrigFather (n, os);
00185 TEST (!e, "found node s (%u) before time %u / %u", n->id, i, path_nedges);
00186 n = e->tail;
00187
00188 EGmengerUpdateResidualGraph (G, e, os);
00189 EGmengerSetEdgeIsInSolution (e, os, 1);
00190 }
00191
00192
00193 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00194 {
00195 n = (EGdGraphNode_t *) (n_it->this);
00196 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00197 {
00198 e = (EGdGraphEdge_t *) (e_it->this);
00199
00200 rcost =
00201 EGdijkstraCostAdd (EGmengerGetEdgeCost (e, os),
00202 EGmengerGetPi (e->head, os));
00203 rcost = EGdijkstraCostSub (rcost, EGmengerGetPi (e->tail, os));
00204
00205 #if EG_MENGER_SAFEMODE
00206 if (EGdijkstraCostToLf (rcost) < 0.0)
00207 {
00208 fprintf (stderr,
00209 "negative edge, WARNING! rcost = %lf ecost = %lf pi_h = %lf pi_t = %lf\n",
00210 EGdijkstraCostToLf (rcost),
00211 EGdijkstraCostToLf (EGmengerGetEdgeCost (e, os)),
00212 EGdijkstraCostToLf (EGmengerGetPi (e->head, os)),
00213 EGdijkstraCostToLf (EGmengerGetPi (e->tail, os)));
00214 rcost = EGdijkstraToCost (0.0);
00215 }
00216 #endif
00217
00218 EGmengerSetEdgeReducedCost (e, os, rcost);
00219 TEST (EGdijkstraCostToLf (rcost) < 0.0,
00220 "\nERROR: Negative edge (%u,%u)! cost=%lf pi_h = %lf pi_t = %lf val = %lf | %lf",
00221 e->head->id, e->tail->id,
00222 EGdijkstraCostToLf (EGmengerGetEdgeCost (e, os)),
00223 EGdijkstraCostToLf (EGmengerGetPi (e->head, os)),
00224 EGdijkstraCostToLf (EGmengerGetPi (e->tail, os)),
00225 EGdijkstraCostToLf (EGmengerGetEdgeReducedCost (e, os)),
00226 EGdijkstraCostToLf (rcost));
00227 }
00228 }
00229
00230
00231
00232
00233
00234
00235 *nfpaths = 1;
00236
00237
00238 for (f = 1; f < npaths; f++)
00239 {
00240
00241
00242
00243 dij_ubound = EGdijkstraCostDiv (EGdijkstraCostSub (ubound, *menger_val),
00244 EGdijkstraToCost ((double) (npaths - f)));
00245 dij_ubound = EGdijkstraCostSub (dij_ubound, prev_flow_val);
00246
00247 #if MENGER_USE_BELLFORD == 0
00248 rval = EGpartialDijkstra (s, t, dij_ubound, dij_os, dij_heap, G);
00249 CHECKRVAL (rval);
00250 if (EGdijkstraGetMarker (t, dij_os) == UINT_MAX)
00251 goto NO_SOLUTION;
00252 #endif
00253
00254 #if MENGER_USE_BELLFORD
00255 rval = EGbellFord (s, dij_os, G);
00256 CHECKRVAL (rval);
00257 #endif
00258
00259
00260
00261
00262 if (EGdijkstraCostIsLess (dij_ubound, EGmengerGetDist (t, os)))
00263 goto NO_SOLUTION;
00264
00265
00266 prev_flow_val = EGdijkstraCostAdd (prev_flow_val, EGmengerGetDist (t, os));
00267 *menger_val = EGdijkstraCostAdd (prev_flow_val, *menger_val);
00268
00269
00270
00271
00272
00273 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00274 if (EGmengerGetMark (n_it->this, os) < UINT_MAX - 1)
00275 {
00276 pi =
00277 EGdijkstraCostAdd (EGmengerGetPi (n_it->this, os),
00278 EGmengerGetDist (t, os));
00279 pi = EGdijkstraCostSub (pi, EGmengerGetDist (n_it->this, os));
00280 EGmengerSetPi (n_it->this, os, pi);
00281 }
00282
00283
00284
00285 n = t;
00286 path_nedges = EGmengerGetNdist (n, os);
00287 for (i = 0; i < path_nedges; i++)
00288 {
00289 e = EGmengerGetFather (n, os);
00290 TEST (!e, "found node s (%u) before time %u / %u", n->id, i, path_nedges);
00291 n = e->tail;
00292
00293 EGmengerSetEdgeIsInSolution (e, os,
00294 1 - EGmengerGetEdgeIsInSolution (e, os));
00295 EGmengerUpdateResidualGraph (G, e, os);
00296 }
00297
00298
00299 *nfpaths += 1;
00300
00301
00302 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00303 {
00304 n = (EGdGraphNode_t *) (n_it->this);
00305 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00306 {
00307 e = (EGdGraphEdge_t *) (e_it->this);
00308 rcost =
00309 EGdijkstraCostAdd (EGmengerGetEdgeCost (e, os),
00310 EGmengerGetPi (e->head, os));
00311 rcost = EGdijkstraCostSub (rcost, EGmengerGetPi (e->tail, os));
00312
00313 #if EG_MENGER_SAFEMODE
00314 if (EGdijkstraCostToLf (rcost) < 0.0)
00315 {
00316 fprintf (stdout,
00317 "WARNING! Negative reduced-cost edge (value = %lf).\n",
00318 EGdijkstraCostToLf (rcost));
00319 rcost = EGdijkstraToCost (0.0);
00320 }
00321 #endif
00322
00323 EGmengerSetEdgeReducedCost (e, os, rcost);
00324 TEST (EGdijkstraCostToLf (rcost) < 0.0,
00325 "ERROR: Negative edge (%u,%u)! cost=%lf pi_h = %lf pi_t = %lf val = %lf | %lf",
00326 e->head->id, e->tail->id,
00327 EGdijkstraCostToLf (EGmengerGetEdgeCost (e, os)),
00328 EGdijkstraCostToLf (EGmengerGetPi (e->head, os)),
00329 EGdijkstraCostToLf (EGmengerGetPi (e->tail, os)),
00330 EGdijkstraCostToLf (EGmengerGetEdgeReducedCost (e, os)),
00331 EGdijkstraCostToLf (rcost));
00332 }
00333 }
00334
00335
00336
00337 }
00338
00339 return 0;
00340
00341 NO_SOLUTION:
00342
00343 *menger_val = EG_DIJKSTRA_COST_MAX;
00344
00345 return 0;
00346
00347 }
00348
00349 int EGmengerEmergencyRecovery (EGdGraph_t * G,
00350 size_t * os)
00351 {
00352
00353 unsigned int cnt = 0;
00354
00355 EGlistNode_t *n_it,
00356 *e_it;
00357
00358 EGdGraphNode_t *n;
00359 EGdGraphEdge_t *e;
00360
00361
00362
00363 FIX_GRAPH:
00364
00365 cnt += 1;
00366
00367 if (cnt > 2 * (G->nedges))
00368 return 1;
00369
00370 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00371 {
00372 n = (EGdGraphNode_t *) (n_it->this);
00373 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00374 {
00375 e = (EGdGraphEdge_t *) (e_it->this);
00376 if (EGmengerGetEdgeIsInSolution (e, os))
00377 {
00378 EGmengerSetEdgeIsInSolution (e, os, 0);
00379 EGmengerUpdateResidualGraph (G, e, os);
00380 goto FIX_GRAPH;
00381 }
00382 }
00383 }
00384
00385
00386
00387 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00388 {
00389 n = (EGdGraphNode_t *) (n_it->this);
00390 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00391 {
00392 e = (EGdGraphEdge_t *) (e_it->this);
00393 if (EGdijkstraCostToLf (EGmengerGetEdgeCost (e, os)) < 0.0)
00394 return 1;
00395 }
00396 }
00397
00398 return 0;
00399
00400 }