eg_ddomino.c

Go to the documentation of this file.
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 /* EGddominoComputeAll                                                       */
00078 /*                                                                           */
00079 /* Note: This function is the one which will take the most time. In order to */
00080 /* parallelize this the following steps can be taken:                        */
00081 /* a) For each s create a copy of diG.                                       */
00082 /* b) For each s use a different list (a dlist[s]).                          */
00083 /* c) For each s use a different copy of eCost.                              */
00084 /* d) At the end, merge the lists.                                           */
00085 /* These steps are important because these objects are not constant!! They   */
00086 /* changed over and over during the EGddominoComputeS execution.             */
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   //unsigned int prev = 0;
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   /* Initialize a local memory pool */
00314   loc_mem = mem;                //EGnewMemPool (100, EGmemPoolNewSize, EGmemPoolNewSize (1));
00315 
00316   /* Prepare the heap that will be used for all dijkstra runs                 */
00317   my_heap = EGnewHeap (loc_mem, 2, G->nodes->size);
00318 
00319   /* Prepare space for allocating flow solutions                              */
00320   pedges = EGmemPoolSMalloc (loc_mem, EGdGraphEdge_t *, G->nedges);
00321   pedges_beg = EGmemPoolSMalloc (loc_mem, unsigned int,
00322                                  4);
00323 
00324   /* Prepare the offset arrays                                                */
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   /* We will use solution to dijkstra from s many times                       */
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   /* For 1 pies, we only need consider nodes t at distance <= 2.0 from s */
00345   /* For 2 pies, this bound changes to 4.0                               */
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   /* We now call the flow algorithm once for each t > s                       */
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   /* Free allocated space                                                     */
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   //EGfreeMemPool (loc_mem);
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      * fprintf (file, "(%u %u) ",
00449      * ((EGdGraphEdge_t *) (ddom->path[i][j]))->tail->id,
00450      * ((EGdGraphEdge_t *) (ddom->path[i][j]))->head->id);
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      * ((edge *) (ddom->path[i][j]))->end0->number,
00457      * ((edge *) (ddom->path[i][j]))->end1->number);
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 }

Generated on Thu Oct 20 14:58:40 2005 for DominoParitySeparator by  doxygen 1.4.5