00001 #include "eg_ddomino.h"
00002
00003 EGddomino_t *EGnewDdomino (EGmemPool_t * mem,
00004 EGdGraphEdge_t ** path,
00005 unsigned int *path_beg,
00006 EGdijkstraCost_t val)
00007 {
00008 unsigned int i;
00009 EGddomino_t *dom;
00010
00011 dom = EGmemPoolSMalloc (mem, EGddomino_t, 1);
00012
00013 dom->DDtype = DOM_DUAL_NORM;
00014 dom->s = path[0]->tail;
00015 dom->t = path[path_beg[1] - 1]->head;
00016
00017 dom->value = EGdijkstraCostSub (val, EGdijkstraToCost (3.0));
00018
00019 dom->path = EGmemPoolSMalloc (mem, void **,
00020 3);
00021 dom->npath = EGmemPoolSMalloc (mem, unsigned int,
00022 3);
00023
00024 dom->id = UINT_MAX;
00025
00026 for (i = 0; i < 3; i++)
00027 {
00028 dom->npath[i] = path_beg[i + 1] - path_beg[i];
00029 dom->path[i] = EGmemPoolSMalloc (mem, void *,
00030 dom->npath[i]);
00031 memcpy (dom->path[i], path + path_beg[i],
00032 sizeof (void *) * (dom->npath[i]));
00033 }
00034
00035 return dom;
00036 }
00037
00038 void EGfreeDdomino (void *v,
00039 EGmemPool_t * mem)
00040 {
00041
00042 int i;
00043 EGddomino_t *ddom;
00044
00045 ddom = (EGddomino_t *) v;
00046
00047 for (i = 0; i < 3; i++)
00048 EGmemPoolSFree (ddom->path[i], void *,
00049 ddom->npath[i],
00050 mem);
00051
00052 EGmemPoolSFree (ddom->npath, unsigned int,
00053 3,
00054 mem);
00055 EGmemPoolSFree (ddom->path, void **,
00056 3,
00057 mem);
00058
00059 EGmemPoolSFree (ddom, EGddomino_t, 1, mem);
00060
00061 return;
00062
00063 }
00064
00065 int EGfreeAllDDominoes (EGlist_t * dlist,
00066 EGmemPool_t * mem)
00067 {
00068
00069 int rval = EGlistClearMP (dlist, EGfreeDdomino, mem);
00070 CHECKRVAL (rval);
00071
00072 return rval;
00073
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 int EGddominoComputeAll (EGmemPool_t * mem,
00090 EGdGraph_t * G,
00091 EGlist_t * dlist,
00092 int k,
00093 double percentage)
00094 {
00095 int i,
00096 rval;
00097 unsigned int nnodes;
00098
00099 EGlistNode_t *n_it;
00100 EGdGraphNode_t *s,
00101 **nodes;
00102
00103 nnodes = G->nodes->size;
00104
00105 nodes =
00106 (EGdGraphNode_t **) EGmemPoolMalloc (mem,
00107 sizeof (EGdGraphNode_t *) * nnodes);
00108 for (i = 0, n_it = G->nodes->begin; n_it; n_it = n_it->next, i++)
00109 nodes[i] = (EGdGraphNode_t *) (n_it->this);
00110
00111 if (DP_TEETHING && (k == 1))
00112 EGddominoPerturb (G, EGdijkstraToCost (DP_TEETHING_PERTURBATION));
00113
00114 fprintf (stdout, "Node: %5d", 0);
00115 fflush (stdout);
00116 for (i = 0; (unsigned) i < nnodes; i++)
00117 {
00118
00119 s = nodes[i];
00120
00121 if (s->out_edges->size < 3)
00122 continue;
00123
00124 fprintf (stdout, "\rNode: %5d", s->id);
00125 fflush (stdout);
00126 rval = EGddominoComputeS (mem, s, G, dlist, k, percentage);
00127 CHECKRVAL (rval);
00128
00129 }
00130
00131 EGmemPoolFree (nodes, sizeof (EGdGraphNode_t *) * nnodes, mem);
00132
00133 fprintf (stdout, "\r");
00134 fflush (stdout);
00135
00136 if (DP_TEETHING && (k == 1))
00137 {
00138 EGddominoPerturb (G, EGdijkstraToCost (-1 * DP_TEETHING_PERTURBATION));
00139 EGddFixValues (dlist);
00140 }
00141
00142 return 0;
00143
00144 }
00145
00146 int EGddominoComputeAllRemote (EGmemPool_t * mem,
00147 EGdGraph_t * G,
00148 EGlist_t * dlist,
00149 int k,
00150 const char *boss_name,
00151 double ddp_heuristic_maxtime)
00152 {
00153
00154 static int graph_id = 0;
00155 CC_SFILE *s = (CC_SFILE *) NULL;
00156 int i,
00157 rval = 0,
00158 num;
00159 EGddomino_t *ddom;
00160 char request = 'Z';
00161
00162 EGdGraphEdge_t **dedges;
00163 EGdGraphNode_t **dnodes;
00164
00165 if (DP_TEETHING && (k == 1))
00166 EGddominoPerturb (G, EGdijkstraToCost (DP_TEETHING_PERTURBATION));
00167
00168 CCutil_printlabel ();
00169
00170 s = CCutil_snet_open (boss_name, CCtsp_DOMINO_PORT);
00171 if (!s)
00172 {
00173 fprintf (stderr, "CCutil_snet_open failed\n");
00174 rval = 1;
00175 goto CLEANUP;
00176 }
00177
00178 #if DISPLAY_MODE
00179 fprintf (stdout, "Sending graph id = %u\n", graph_id);
00180 fflush (stdout);
00181 #endif
00182
00183 rval = CCutil_swrite_char (s, CCtsp_DOMINO_GRAPH);
00184 CCcheck_rval (rval, "CCutil_swrite_char failed (GRAPH)");
00185
00186 rval = CCutil_swrite_int (s, graph_id);
00187 CCcheck_rval (rval, "Failed to send graph");
00188
00189 rval = CCutil_swrite_int (s, k);
00190 CCcheck_rval (rval, "Failed to send graph");
00191
00192 rval = CCutil_swrite_double (s, ddp_heuristic_maxtime);
00193 CCcheck_rval (rval, "Failed to send ddp_heuristic_maxtime");
00194
00195 rval = EGsendRealGraph (s, G, &dedges, &dnodes, mem);
00196 CCcheck_rval (rval, "Failed to send graph");
00197
00198 #if DISPLAY_MODE
00199 fprintf (stdout, "Graph sent. Waiting for dominoes.\n");
00200 fflush (stdout);
00201 #endif
00202
00203 while (request != CCtsp_DOMINO_SEND)
00204 {
00205
00206 CCutil_sclose (s);
00207
00208 sleep (2);
00209
00210 s = CCutil_snet_open (boss_name, CCtsp_DOMINO_PORT);
00211 if (!s)
00212 {
00213 fprintf (stderr, "CCutil_snet_open failed\n");
00214 rval = 1;
00215 goto CLEANUP;
00216 }
00217
00218 rval = CCutil_swrite_char (s, CCtsp_DOMINO_SEND);
00219 CCcheck_rval (rval, "CCutil_swrite_char failed (SEND)");
00220
00221 rval = CCutil_sread_char (s, &request);
00222 CCcheck_rval (rval, "CCutil_swrite_char failed (SEND)");
00223
00224 }
00225
00226 #if DISPLAY_MODE
00227 fprintf (stdout, "Preparing to receive dominoes.\n");
00228 fflush (stdout);
00229 #endif
00230
00231 rval = CCutil_sread_int (s, &num);
00232 CCcheck_rval (rval, "receive ndominoes failed");
00233
00234 #if DISPLAY_MODE
00235 fprintf (stdout, "Receiving %d dominoes.\n", num);
00236 fflush (stdout);
00237 #endif
00238
00239
00240 for (i = 0; i < num; i++)
00241 {
00242 rval = EGreceiveRealDomino (s, &ddom, dedges, dnodes, mem);
00243 CCcheck_rval (rval, "receive_dominos failed");
00244 EGlistPushBack (dlist, ddom);
00245 ddom->id = i;
00246 }
00247
00248 #if DISPLAY_MODE
00249 fprintf (stdout, "Done.\n");
00250 fflush (stdout);
00251 #endif
00252
00253 CLEANUP:
00254
00255 graph_id += 1;
00256 if (s)
00257 CCutil_sclose (s);
00258
00259 if (DP_TEETHING && (k == 1))
00260 {
00261 EGddominoPerturb (G, EGdijkstraToCost (-1 * DP_TEETHING_PERTURBATION));
00262 EGddFixValues (dlist);
00263 }
00264
00265 return rval;
00266
00267 }
00268
00269
00270 int EGddominoComputeS (EGmemPool_t * mem,
00271 EGdGraphNode_t * s,
00272 EGdGraph_t * G,
00273 EGlist_t * dlist,
00274 int k,
00275 double percentage)
00276 {
00277
00278 int rval;
00279 EGmemPool_t *loc_mem;
00280
00281 EGheap_t *my_heap;
00282 EGddomino_t *ddom;
00283 EGlistNode_t *n_it;
00284
00285 EGdijkstraCost_t val;
00286
00287 unsigned int *pedges_beg,
00288 found_paths;
00289 EGdGraphEdge_t **pedges;
00290 EGdGraphNode_t *t;
00291 size_t os[EG_MENGER_NUMOS] = {
00292 [EG_MENGER_PI] = offsetof (EGmengerNodeData_t, pi),
00293 [EG_MENGER_DIST] = offsetof (EGmengerNodeData_t, dist),
00294 [EG_MENGER_ORIG_DIST] = offsetof (EGmengerNodeData_t, orig_dist),
00295 [EG_MENGER_NDIST] = offsetof (EGmengerNodeData_t, ndist),
00296 [EG_MENGER_ORIG_NDIST] = offsetof (EGmengerNodeData_t, orig_ndist),
00297 [EG_MENGER_MARK] = offsetof (EGmengerNodeData_t, marker),
00298 [EG_MENGER_ORIG_MARK] = offsetof (EGmengerNodeData_t, orig_marker),
00299 [EG_MENGER_FATHER] = offsetof (EGmengerNodeData_t, father),
00300 [EG_MENGER_ORIG_FATHER] = offsetof (EGmengerNodeData_t, orig_father),
00301 [EG_MENGER_HEAP_CONNECTOR] = offsetof (EGmengerNodeData_t, hc),
00302 [EG_MENGER_ECOST] = offsetof (EGmengerEdgeData_t, cost),
00303 [EG_MENGER_REDUCED_ECOST] = offsetof (EGmengerEdgeData_t, reduced_cost),
00304 [EG_MENGER_IS_IN_SOL] = offsetof (EGmengerEdgeData_t, is_in_solution),
00305 [EG_MENGER_EDATA] = offsetof (EGmengerEdgeData_t, data)
00306 },
00307 dij_os[6];
00308
00309 #if DDOM_LARGE_MODE == 1
00310 EGlist_t *remlist;
00311 #endif
00312
00313
00314 loc_mem = mem;
00315
00316
00317 my_heap = EGnewHeap (loc_mem, 2, G->nodes->size);
00318
00319
00320 pedges = EGmemPoolSMalloc (loc_mem, EGdGraphEdge_t *, G->nedges);
00321 pedges_beg = EGmemPoolSMalloc (loc_mem, unsigned int,
00322 4);
00323
00324
00325 dij_os[EG_DIJ_DIST] = os[EG_MENGER_ORIG_DIST];
00326 dij_os[EG_DIJ_NDIST] = os[EG_MENGER_ORIG_NDIST];
00327 dij_os[EG_DIJ_FATHER] = os[EG_MENGER_ORIG_FATHER];
00328 dij_os[EG_DIJ_MARKER] = os[EG_MENGER_ORIG_MARK];
00329 dij_os[EG_DIJ_HCONNECTOR] = os[EG_MENGER_HEAP_CONNECTOR];
00330 dij_os[EG_DIJ_ELENGTH] = os[EG_MENGER_ECOST];
00331
00332 #if DDOM_LARGE_MODE == 0
00333
00334
00335 rval = EGpartialDijkstra (s, 0, EG_DIJKSTRA_COST_MAX, dij_os, my_heap, G);
00336 CHECKRVAL (rval);
00337
00338 #endif
00339
00340 #if DDOM_LARGE_MODE == 1
00341
00342 remlist = EGnewList (mem);
00343
00344
00345
00346 rval =
00347 EGpartialDijkstra (s, 0,
00348 EGdijkstraToCost (percentage * (2.0 + (k - 1) * 2.0)),
00349 dij_os, my_heap, G);
00350 CHECKRVAL (rval);
00351
00352 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00353 {
00354
00355 t = (EGdGraphNode_t *) (n_it->this);
00356
00357 if (EGmengerGetOrigMark (t, os) > UINT_MAX - 2)
00358 {
00359 rval = EGdGraphUnattachNode (G, t);
00360 CHECKRVAL (rval);
00361 EGlistPushHead (remlist, t);
00362 }
00363
00364 }
00365
00366 #endif
00367
00368
00369 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00370 {
00371
00372 t = (EGdGraphNode_t *) (n_it->this);
00373
00374 if (t->id <= s->id)
00375 continue;
00376
00377 found_paths = 0;
00378
00379 rval =
00380 EGmengerPathsADV (s, t, EGdijkstraToCost (3.0 + 1.0 * k - DDOM_EPSILON),
00381 3, &found_paths, &val, my_heap, os, G);
00382
00383 CHECKRVAL (rval);
00384
00385 if (found_paths)
00386 {
00387
00388 rval =
00389 EGmengerRecoverGraphAndSolution (G, os, s, t, found_paths, pedges,
00390 pedges_beg);
00391 if (rval)
00392 {
00393 MESSAGE (0,
00394 "WARNING!! Problem with menger. Running emergency recovery...");
00395 rval = EGmengerEmergencyRecovery (G, os);
00396 }
00397 CHECKRVAL (rval);
00398
00399 }
00400
00401 if (EGdijkstraCostIsLess
00402 (EGdijkstraToCost (2.0 + 2.0 * k - DDOM_EPSILON), val))
00403 continue;
00404
00405 ddom = EGnewDdomino (mem, pedges, pedges_beg, val);
00406 ddom->id = dlist->size;
00407 EGlistPushBack (dlist, (void *) ddom);
00408
00409 }
00410
00411 #if DDOM_LARGE_MODE == 1
00412 for (n_it = remlist->begin; n_it; n_it = n_it->next)
00413 {
00414 t = (EGdGraphNode_t *) (n_it->this);
00415 EGdGraphAttachNode (G, t);
00416 }
00417
00418 EGfreeList (remlist);
00419 #endif
00420
00421
00422 EGmemPoolFree (pedges, sizeof (EGdGraphEdge_t *) * (G->nedges), loc_mem);
00423 EGmemPoolFree (pedges_beg, sizeof (unsigned int) * 4, loc_mem);
00424 EGfreeHeap (my_heap, loc_mem);
00425
00426
00427 return 0;
00428
00429 }
00430
00431 void EGddominoDisplay (EGddomino_t * ddom,
00432 FILE * file)
00433 {
00434
00435 unsigned int i,
00436 j;
00437 fprintf (file, "s=%u, t=%u, val=%lf type=%s\n", ddom->s->id, ddom->t->id,
00438 EGdijkstraCostToLf (ddom->value), ddom->DDtype == DOM_DUAL_NORM ?
00439 "DualDominoNormal" : ddom->DDtype == DOM_CC_ONE ?
00440 "ConsecutiveOneDomino" : "Unknown type");
00441 for (i = 0; i < 3; i++)
00442 {
00443 fprintf (file, "path %u (%u): ", i, ddom->npath[i]);
00444 if (ddom->DDtype != DOM_CC_ONE)
00445 for (j = 0; j < ddom->npath[i]; j++)
00446 EGmengerDisplayEdgeBasic ((EGdGraphEdge_t *) ddom->path[i][j], file);
00447
00448
00449
00450
00451
00452 else if (ddom->DDtype == DOM_CC_ONE)
00453 for (j = 0; j < ddom->npath[i]; j++)
00454 fprintf (file, "(%u %u) ", 0, 0);
00455
00456
00457
00458
00459 else
00460 fprintf (file, "Unknown type ");
00461 fprintf (file, "\n");
00462 }
00463
00464 return;
00465
00466 }
00467
00468 int EGddominoPerturb (EGdGraph_t * G,
00469 EGdijkstraCost_t epsilon)
00470 {
00471
00472 size_t dij_os[6];
00473 EGdijkstraCost_t val;
00474 EGdGraphNode_t *n;
00475 EGdGraphEdge_t *e;
00476 EGlistNode_t *n_it, *e_it;
00477
00478 dij_os[EG_DIJ_ELENGTH] = offsetof (EGmengerEdgeData_t, cost);
00479
00480 for (n_it = G->nodes->begin; n_it; n_it = n_it->next)
00481 {
00482 n = (n_it->this);
00483 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00484 {
00485 e = e_it->this;
00486 val = EGdijkstraGetEdgeLength (e, dij_os);
00487 val = EGdijkstraCostSub (val, epsilon);
00488 if (fabs (EGdijkstraCostToLf (val)) > fabs (EGdijkstraCostToLf (epsilon)))
00489 EGdijkstraSetEdgeLength (e, dij_os, val);
00490 }
00491 }
00492
00493 return 0;
00494
00495 }
00496
00497 EGdijkstraCost_t EGddWeight (EGddomino_t * dd)
00498 {
00499
00500 unsigned int i,
00501 j;
00502 EGdijkstraCost_t val;
00503
00504 size_t dij_os[6];
00505
00506 val = EGdijkstraToCost (0.0);
00507 dij_os[EG_DIJ_ELENGTH] = offsetof (EGmengerEdgeData_t, cost);
00508
00509 for (i = 0; i < 3; i++)
00510 for (j = 0; j < dd->npath[i]; j++)
00511 val =
00512 EGdijkstraCostAdd (val,
00513 EGdijkstraGetEdgeLength (dd->path[i][j], dij_os));
00514
00515 return val;
00516
00517 }
00518
00519 int EGddFixValues (EGlist_t * dd_list)
00520 {
00521
00522 EGlistNode_t *it;
00523 EGddomino_t *ddom;
00524
00525 EGdijkstraCost_t val;
00526
00527 for (it = dd_list->begin; it; it = it->next)
00528 {
00529 ddom = (EGddomino_t *) (it->this);
00530 val = EGddWeight (ddom);
00531 ddom->value = EGdijkstraCostSub (val, EGdijkstraToCost (3.0));
00532 }
00533
00534 return 0;
00535
00536 }