eg_kpseparator.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 
00004 #include "eg_list.h"
00005 #include "eg_mempool.h"
00006 #include "graph_boyer.h"
00007 #include "graphdual.h"
00008 
00009 #include "eg_util.h"
00010 #include "eg_dgraph.h"
00011 #include "eg_ddomino.h"
00012 #include "eg_pdp.h"
00013 #include "eg_util.h"
00014 #include "eg_ddpconstraint.h"
00015 #include "bc_spanning.h"
00016 #include "bc_util.h"
00017 #include "cookInterface.h"
00018 #include "eg_1pchecker.h"
00019 #include "eg_emptyhandles.h"
00020 #include "eg_greedykp.h"
00021 #include "eg_kppairs.h"
00022 #include "eg_2pchecker.h"
00023 #include "karger.h"
00024 #include "eg_greedytypes.h"
00025 
00026 double DKP_HEURISTIC_MAXTIME = 10.0;
00027 
00028 /* Function Definitions */
00029 int KPseparator (int max_handles,
00030                  int nnodes,
00031                  int norig_edges,
00032                  int *const orig_edges,
00033                  double *const orig_weight,
00034                  int *nineq,
00035                  int **nhandles,
00036                  int ***handle_size,
00037                  int ****handles,
00038                  int **nteeth,
00039                  int ***teeth_size,
00040                  int ****teeth,
00041                  int ***teeth_k,
00042                  int ****teeth_handle,
00043                  int ****teeth_nhalf,
00044                  int *****teeth_halves,
00045                  const char *const boss_name,
00046                  double percentage) 
00047 {
00048 
00049   /* **************** DECLARE VARIABLES **************** */
00050 
00051   /* auxiliary variables */
00052   int i,
00053     rval;
00054   int is_connected;
00055   /* flags */
00056   int eliminated_edges_b = 0,
00057     is_G_planar_b = 0;
00058   /* where we will store the edges that are bigger than ZERO_X_EPSILON */
00059   int *edges = 0,
00060     nedges = 0,
00061     nelim_edges = 0;
00062   double *weight = 0;
00063   /* for the primal-dual-primal conversions we need an 'applegate' graph */
00064   graphP primalG = 0;
00065   /* the bi-directed dual over which we will search for ddominoes */
00066   EGdGraph_t *biDualG = 0;
00067   /* the list of ddominoes */
00068   EGlist_t *dlist = 0;
00069   EGlist_t **dembed = 0;
00070   EGlist_t **lembed = 0;
00071   /* memory pool */
00072   EGmemPool_t *mem = 0;
00073   /* used for handling the list of ddominoes */
00074   EGddomino_t *ddom;
00075   EGlistNode_t *ddom_it;
00076 #if ELIM_EDGES
00077   int *planar_edges = 0,
00078     nplanar_edges = 0,
00079    *elim_edges = 0;
00080   double *planar_weight = 0,
00081     error = 0;
00082 #endif
00083 #if DISPLAY_MODE
00084   unsigned int distr[10] = {0,0,0,0,0,0,0,0,0,0};
00085   int nfeasible = 0;
00086   int ncorrected = 0;
00087   int nnegative = 0;
00088   double dual_val,
00089     prim_val;
00090 #endif
00091    EGdualCut_t *dcut=0;
00092    EGdcutIter_t *dcut_it=0;
00093    EGgreedyData_t *gdata=0;
00094    EGpkpc_t *pkpc = 0;
00095    int nadded = 0;
00096    double minslack;
00097    unsigned char *pndummy=EGsMalloc(unsigned char,nnodes), 
00098     *pedummy=EGsMalloc(unsigned char, norig_edges);
00099 
00100   /* ******************* INITIALIZE DATA STRUCTURES ******************* */
00101   *nineq = 0;
00102   *nhandles = 0;
00103   *handle_size = 0;
00104   *handles = 0;
00105   *nteeth = 0;
00106   *teeth_size = 0;
00107   *teeth = 0;
00108   *teeth_k = 0;
00109   *teeth_handle = 0;
00110   *teeth_nhalf = 0;
00111   *teeth_halves = 0;
00112   /* initialize memory pool                                                   */
00113   mem = EGnewMemPool (512, EGmemPoolNewSize, EGmemPoolNewSize (1));
00114 
00115   /* initialize linked lists                                                  */
00116   dlist = EGnewList (mem);
00117 
00118   /* ******************* INFORM USER ******************* */
00119 
00120   fprintf (stdout, "KP Version %s\n", DP_VERSION_STRING);
00121 #if DISPLAY_MODE
00122   if (!boss_name)
00123     fprintf (stdout, "KP Separator: NO boss.\n");
00124   else
00125     fprintf (stdout, "KP Separator: Boss name = %s.\n", boss_name);
00126   fflush (stdout);
00127 #endif
00128 
00129 #if LOG_MODE
00130   saveBgraph ("graph.b.x", nnodes, norig_edges, orig_edges, orig_weight);
00131 #endif
00132 
00133 #if DISPLAY_MODE
00134   fprintf (stdout, "KP Separator: Graph G^* has %d nodes, and %d edges.\n", nnodes, norig_edges);
00135   fflush (stdout);
00136 #endif
00137 
00138   /* ******************* REMOVE SMALL EDGES ******************* */
00139 
00140   /* remove small edges (ie: those smaller than ZERO_X_EPSILON)               */
00141   rval = removeSmallEdges (ZERO_X_EPSILON, orig_edges, norig_edges, orig_weight,
00142                            &nedges, &edges, &weight, mem);
00143   CHECKRVAL (rval);
00144 
00145 #if DISPLAY_MODE
00146   fprintf (stdout,
00147            "KP Separator: Eliminated %d edges of value less than %lf.\n",
00148            (norig_edges - nedges), ZERO_X_EPSILON);
00149   fflush (stdout);
00150   fprintf (stdout, "KP Separator: Graph G^* now has %d nodes, and %d edges.\n",
00151            nnodes, nedges);
00152   fflush (stdout);
00153 #endif
00154 
00155   /* ******************* PLANARIZE GRAPH IF NECESSARY  ******************* */
00156 
00157   /* check if the graph is planar                                             */
00158   primalG = gp_New ();
00159   rval = cook2boyerGraph (primalG, nnodes, nedges, edges);
00160   CHECKRVAL (rval);
00161   is_G_planar_b = gp_Embed (primalG, EMBEDFLAGS_PLANAR);
00162   rval = gp_SortVertices (primalG);
00163   EXITRVAL (rval);
00164 
00165   /* if not planar, run heuristic to planarize                                */
00166   if (is_G_planar_b != OK)
00167   {
00168 #if DISPLAY_MODE
00169     fprintf (stdout, "KP Separator: Graph G^* is not planar.\n");
00170     fflush (stdout);
00171 #endif
00172     /* First: Contractions.                                                   */
00173     /* Second: Eliminate Edges using the Kruskal Heuristic.                   */
00174 #if ELIM_EDGES
00175 #if DISPLAY_MODE
00176     fprintf (stdout, "KP Separator: Running edge-elimination "
00177              "heuristic to find planar sub-graph.\n");
00178     fflush (stdout);
00179 #endif
00180 
00181     /* cuidado! */
00182     planar_edges = EGmemPoolMalloc (mem, sizeof (int) * 2 * nedges);
00183     planar_weight = EGmemPoolMalloc (mem, sizeof (double) * nedges);
00184     elim_edges = EGmemPoolMalloc (mem, sizeof (int) * nedges);
00185     /* cuidado! */
00186 
00187     rval =
00188       DPedgeEliminationHeuristic (nnodes, nedges, edges, weight, &nplanar_edges,
00189                                   planar_edges, planar_weight, &nelim_edges,
00190                                   elim_edges);
00191 
00192     CHECKRVAL (rval);
00193 
00194 #if DISPLAY_MODE
00195     fprintf (stdout, "KP Separator: Completed edge-elimination.");
00196     fflush (stdout);
00197 #endif
00198 
00199     eliminated_edges_b = 1;
00200     TEST (nplanar_edges == nedges, "ERROR: Graph is not planar, yet no edges "
00201           "were eliminated.");
00202 
00203     for (i = 0; i < nedges - nplanar_edges; i++)
00204       error += weight[elim_edges[i]];
00205 
00206 #if DISPLAY_MODE
00207     fprintf (stdout, "KP Separator: Found a planar sub-graph with %d edges.\n",
00208              nplanar_edges);
00209     fflush (stdout);
00210     fprintf (stdout, "KP Separator: Total weight of eliminated edges is %lf.\n",
00211              error);
00212     fflush (stdout);
00213 #endif
00214 #endif
00215   }
00216 
00217   /* if graph is planar, we use the original edge set.                        */
00218   else
00219   {
00220 #if DISPLAY_MODE
00221     fprintf (stdout, "KP Separator: Graph G^* is planar.\n");
00222     fflush (stdout);
00223 #endif
00224     eliminated_edges_b = 0;
00225     planar_edges = edges;
00226     nplanar_edges = nedges;
00227     planar_weight = weight;
00228   }
00229 
00230 #if LOG_MODE
00231   saveBgraph ("graph.planar.b.x", nnodes, nplanar_edges, planar_edges,
00232               planar_weight);
00233   saveGraph ("graph.planar.x", nnodes, nplanar_edges, planar_edges,
00234              planar_weight);
00235 #endif
00236 
00237   /* ******************* COMPUTE DUAL GRAPH  ******************* */
00238 
00239 #if DISPLAY_MODE
00240   fprintf (stdout, "KP Separator: Computing dual of G^*.\n");
00241   fflush (stdout);
00242 #endif
00243   is_connected = EGisCookGraphConnected (nnodes, nplanar_edges, planar_edges,
00244                                          mem);
00245 
00246 #if DISPLAY_MODE
00247   if (is_connected)
00248     fprintf (stdout, "KP Separator: G^* is connected.\n");
00249   else
00250     fprintf (stdout, "KP Separator: G^* is not connected.\n");
00251 #endif
00252 
00253   if (!is_connected)
00254     goto END_DP;
00255 
00256   /* compute dual of graph                                                    */
00257   gp_Free (&primalG);
00258   primalG = gp_New ();
00259   rval = cook2boyerGraph (primalG, nnodes, nplanar_edges, planar_edges);
00260   CHECKRVAL (rval);
00261   biDualG = getDualBoyer (primalG, nnodes, nplanar_edges, planar_weight,
00262                           &dembed, mem, &lembed);
00263   if (!biDualG)
00264     goto END_DP;
00265 
00266 #if DISPLAY_MODE
00267   fprintf (stdout, "KP Separator: Bi-directed dual graph "
00268            "has %d nodes and %d edges.\n",
00269            biDualG->nodes->size, biDualG->nedges);
00270 
00271   /* ******************* COMPUTE AND FIX DUAL 1-DOMINOES  ******************* */
00272 
00273   fprintf (stdout, "KP Separator: Looking for dual dominoes.\n");
00274   fflush (stdout);
00275 #endif
00276 
00277   /* with dual of planar graph, obtain dual dominoes                          */
00278   if (boss_name == 0)
00279     rval = EGddominoComputeAll (mem, biDualG, dlist, EG_DOMINO_K, percentage);
00280   else
00281     rval = EGddominoComputeAllRemote (mem, biDualG, dlist, EG_DOMINO_K, boss_name, DKP_HEURISTIC_MAXTIME);
00282 
00283   CHECKRVAL (rval);
00284 
00285 #if DISPLAY_MODE
00286   fprintf (stdout, "KP Separator: Found %d dual dominoes.\n", dlist->size);
00287   fflush (stdout);
00288 #endif
00289 
00290   /* now we untengle all the obtained dominoes */
00291   rval = EGuntangleAllDomino (dlist, biDualG, dembed, mem);
00292   CHECKRVAL (rval);
00293 
00294   if (!dlist->size)
00295     goto END_DP;
00296 
00297   /* if using an edge-elimination heuristic, we might want to fix (some? all?) domino values and store this corrected value in primalValue. If there is no edge-elimination we also need to set primalValue, however, in this case there is no need for corrections. Finally, we need to fix numerical errors. Specifically, should we encounter dominoes with slightly negative values, we will round these up to zero (slightly negative == DP_RESET_VALUE. */
00298   rval =
00299     EGfixDualDominos (dlist, nnodes, nedges, weight, edges,
00300                       elim_edges, nelim_edges, primalG, mem);
00301   CHECKRVAL (rval);
00302 
00303 
00304 #if DISPLAY_MODE
00305   if (eliminated_edges_b)
00306   {
00307 
00308     ncorrected = 0;
00309     nnegative = 0;
00310     nfeasible = 0;
00311 
00312     for (ddom_it = dlist->begin; ddom_it; ddom_it = ddom_it->next)
00313     {
00314 
00315       ddom = (EGddomino_t *) (ddom_it->this);
00316       dual_val = EGdijkstraCostToLf (ddom->value);
00317       prim_val = EGdijkstraCostToLf (ddom->primalValue);
00318 
00319       if (fabs (dual_val - prim_val) > 0.0001)
00320       {
00321         ncorrected++;
00322       }
00323       if (dual_val < 0)
00324       {
00325         nnegative++;
00326       }
00327       if (prim_val < 1.0000)
00328         nfeasible++;
00329     }
00330     fprintf (stdout,
00331              "KP Separator: Corrected %d values. %d / %d dominoes remain feasible.\n",
00332              ncorrected, nfeasible, dlist->size);
00333     fflush (stdout);
00334   }
00335 #endif
00336 
00337   /* ******************* PREPARE DATA FOR GREEDY ALG **************** */
00338 
00339 #if DISPLAY_MODE
00340   fprintf (stdout, "KP Separator: Constructing greedy data.\n");
00341   fflush (stdout);
00342 #endif
00343 
00344   gdata = EGnewGreedyData(mem);
00345   rval = EGfillGreedyData(gdata, 
00346                           biDualG, 
00347                           dlist,
00348                           lembed,
00349                           primalG,
00350                           nnodes,
00351                           norig_edges,
00352                           nplanar_edges,
00353                           orig_edges,
00354                           planar_edges,
00355                           orig_weight,
00356                           planar_weight);
00357   CHECKRVAL(rval);
00358 
00359  /* allocate memory for one constraint */
00360 
00361   TEST( max_handles != 2, "implementatin only good for max_handles = 2" );
00362 
00363   gdata->max_handles = max_handles;
00364   gdata->percentage = percentage;
00365   gdata->cut_heap = EGnewHeap(mem, 2, EG_KP_MAX_CUTS);
00366   gdata->dc_heap = EGnewHeap(mem, 2, EG_KP_MAX_SAMPLE);
00367   
00368   /* ******************* LOOP THROUGH ZERO-DOMINOES ***************** */
00369 
00370   #if EG_USE_ZERO_DOMINOES
00371   #if DISPLAY_MODE
00372   fprintf(stdout, "KP: Generating domino-based dual cuts.\n");
00373   #endif
00374   dcut_it = EGnewDcutIter(gdata);
00375   while( dcut_it->ddit )
00376   {
00377      dcut = EGgetDcut(dcut_it);
00378      rval = KPseparateFromDualCut( dcut, 
00379                                    (unsigned int)dcut_it->current_side, 
00380                                    gdata,
00381                                    &nadded,
00382                                    &minslack,
00383                                    0.0 );
00384       CHECKRVAL(rval);
00385 
00386       EGincrementDcutIter(dcut_it);
00387      
00388       if (nadded)
00389         EGaddDualCutToHeap(gdata->dc_heap,
00390                            dcut,
00391                            (unsigned int)dcut_it->current_side, 
00392                            minslack,
00393                            mem);
00394       else
00395         EGfreeDualCut(dcut,mem);
00396   }
00397   EGfreeDcutIter(dcut_it);
00398   #endif
00399 
00400   #if EG_USE_KARGER 
00401   /* ***************** LOOP WITH KARGER ***************************** */ 
00402 
00403   setlist*sets = 0;
00404   #if DISPLAY_MODE
00405   fprintf(stdout, "\nKP: Generating karger-based dual cuts.\n");
00406   #endif
00407   max_numiter = EG_KARGER_MAX_ITER;
00408   double max_time = ((double)gdata->norig_nodes * EG_KARGER_TIME_PER_NODE);
00409   if (EG_KARGER_MAX_TOT_TIME)
00410     max_time = EG_KARGER_MAX_TOT_TIME;
00411   const int seed = EG_KARGER_SEED;
00412   fprintf(stdout, "KP: Karger sample time = %lf seconds.\n", max_time);
00413   rval = karger(gdata->norig_nodes, gdata->norig_edges, gdata->orig_edges,
00414                 gdata->orig_weight, 3, 6.0, max_time, seed, &sets, choose_edge1,
00415                 gdata, KPprocess_cut);
00416   CHECKRVAL(rval);
00417   #endif
00418 
00419   /* ***************** LOOP WITH SAMPLING *************************** */ 
00420 
00421   #if EG_USE_SAMPLING
00422   double factor = 1.0;
00423   srandom(EG_KP_SAMPLE_SEED);
00424   while(gdata->dc_heap->size)
00425   {
00426     EGcutSeed_t *cseed;
00427     factor += .25;
00428     cseed = EGheapGetMinThis(gdata->dc_heap);
00429     dcut = cseed->dc;
00430     minslack = EGheapCostToLf(EGheapGetMinVal(gdata->dc_heap));
00431     fprintf(stdout, "\nKP: Sampling. Current cut lower bound = %lf (time = %lf).\n", minslack, EG_KP_SAMPLE_TIME*factor);
00432     rval = KPseparateFromDualCut( dcut, 
00433                                   (unsigned int)cseed->orientation, 
00434                                   gdata,
00435                                   &nadded,
00436                                   &minslack,
00437                                   EG_KP_SAMPLE_TIME*factor );
00438     EGheapDeleteMin(gdata->dc_heap,mem);
00439     EGmemPoolSFree(cseed, EGcutSeed_t, 1, mem);
00440     EGfreeDualCut(dcut,mem);
00441   }
00442   #endif
00443 
00444   /* ***************** DISPLAY 0-CUT STATS ************************** */ 
00445   
00446   #if DISPLAY_MODE
00447   fprintf(stdout,"\n0-Cut values:\n");
00448   for( i = 0 ; i < 7 ; i++)
00449     if(gdata->delta_distr[i])
00450       fprintf(stdout,"[%lf,%lf] = %u\n", i*1.0, (i+1)*1.0, 
00451               gdata->delta_distr[i]);
00452   fprintf(stdout, "KP: Finished generating dual cuts.\n");
00453   #endif
00454 
00455   /* ***************** STORE USER ARRAYS *************************** */ 
00456 
00457   if (gdata->cut_heap->size)
00458   {
00459 
00460      *nineq = gdata->cut_heap->size;
00461      rval = EGnewPKPCset( *nineq,
00462                            nhandles,
00463                            handle_size,
00464                            handles,
00465                            nteeth,
00466                            teeth_size,
00467                            teeth,
00468                            teeth_k,
00469                            teeth_handle,
00470                            teeth_nhalf,
00471                            teeth_halves );
00472      CHECKRVAL(rval);
00473    
00474      int tot = gdata->cut_heap->size; 
00475      for(i=0; gdata->cut_heap->size; i++)
00476      {
00477 
00478         pkpc = (EGpkpc_t*) EGheapGetMinThis(gdata->cut_heap);
00479         int w = tot - i - 1;
00480         //fprintf(stderr, "slack[%d] = %lf\n", w, pkpc->slack);
00481 
00482         #if DISPLAY_MODE
00483         if(pkpc->slack > -0.1)
00484           distr[0]++;
00485         else if(pkpc->slack > -0.2)
00486           distr[1]++;
00487         else if(pkpc->slack > -0.3)
00488           distr[2]++;
00489         else if(pkpc->slack > -0.4)
00490           distr[3]++;
00491         else if(pkpc->slack > -0.5)
00492           distr[4]++;
00493         else if(pkpc->slack > -0.6)
00494           distr[5]++;
00495         else if(pkpc->slack > -0.7)
00496           distr[6]++;
00497         else if(pkpc->slack > -0.8)
00498           distr[7]++;
00499         else if(pkpc->slack > -0.9)
00500           distr[8]++;
00501         else 
00502           distr[9]++;
00503         #endif
00504 
00505         (*nhandles)[w] = pkpc->nhandles;
00506         (*handle_size)[w] = pkpc->handle_size;
00507         (*handles)[w] = pkpc->handles;
00508         (*nteeth)[w] = pkpc->nteeth;
00509         (*teeth_size)[w] = pkpc->teeth_size;
00510         (*teeth)[w] = pkpc->teeth;
00511         (*teeth_k)[w] = pkpc->teeth_k;
00512         (*teeth_handle)[w] = pkpc->teeth_handle;
00513         (*teeth_nhalf)[w] = pkpc->teeth_nhalf;
00514         (*teeth_halves)[w] = pkpc->teeth_halves;
00515 
00516         EGheapDeleteMin(gdata->cut_heap, mem);
00517         EGfree(pkpc);
00518      }
00519 
00520     #if DISPLAY_MODE
00521     fprintf(stdout,"KP: Primal distribution of cuts:\n");
00522     for( i = 10 ; i-- ;)
00523       if(distr[i])
00524         fprintf(stdout,"[%lf,%lf] %u\n", 0.1*i, 0.1*(i+1),distr[i]);
00525     #endif
00526 
00527   }
00528 
00529   /* ******************* CLEAN UP THE MEMORY ******************* */
00530 
00531 /* EGfree up used memory */
00532 
00533 END_DP:
00534 
00535 #if DISPLAY_MODE
00536   fprintf (stdout, "KP Separator: Bye.\n");
00537   fflush (stdout);
00538 #endif
00539 
00540   if (gdata->cut_heap) EGfreeHeap(gdata->cut_heap, mem);
00541   if (gdata->dc_heap) EGfreeHeap(gdata->dc_heap, mem);
00542   EGfreeGreedyData(gdata);
00543 
00544   /* EGfree dlist, ddplist, and pdplist */
00545   if (dlist)
00546   {
00547     if (dlist->size)
00548       EGlistClearMP (dlist, EGfreeDdomino, mem);
00549     EGfreeList (dlist);
00550   }
00551 
00552   /* EGfree 'graphdual' objects */
00553   if (weight)
00554     EGmemPoolFree (weight, sizeof (double) * nedges, mem);
00555   if (edges)
00556     EGmemPoolFree (edges, sizeof (int) * 2 * nedges, mem);
00557 
00558 #if ELIM_EDGES
00559   /* EGfree planar-graph heuristic data structures */
00560   if (eliminated_edges_b)
00561   {
00562     EGmemPoolSFree (planar_edges, int,
00563                     2 * nedges,
00564                     mem);
00565     EGmemPoolSFree (elim_edges, int,
00566                     nedges,
00567                     mem);
00568     EGmemPoolSFree (planar_weight, double,
00569                     nedges,
00570                     mem);
00571   }
00572 #endif
00573 
00574   /* EGfree biDualG: weight, edges, and graph structure. */
00575   if (biDualG)
00576   {
00577     EGdGraphClearMP (biDualG, EGfreeMengerEdgeDataMP, EGfreeMengerNodeDataMP, 0,
00578                      mem, mem, 0);
00579     EGfreeDGraph (biDualG);
00580   }
00581 
00582   if (lembed)
00583   {
00584     for (i = nplanar_edges - nnodes + 2; i--;)
00585       EGfreeList (lembed[i]);
00586     EGmemPoolSFree (lembed, EGlist_t *, nplanar_edges - nnodes + 2, mem);
00587   }
00588   if (dembed)
00589   {
00590     for (i = nplanar_edges - nnodes + 2; i--;)
00591       EGfreeList (dembed[i]);
00592     EGmemPoolSFree (dembed, EGlist_t *, nplanar_edges - nnodes + 2, mem);
00593   }
00594   /* EGfree memory pool */
00595   EGfreeMemPool (mem);
00596   gp_Free (&primalG);
00597   EGfree(pedummy);
00598   EGfree(pndummy);
00599 
00600   /* return */
00601   return 0;
00602 
00603 }
00604 
00605 int DP2separator(int nnodes,
00606                  int norig_edges,
00607                  int *const orig_edges,
00608                  double *const orig_weight,
00609                  int *const n2ineq,
00610                  int **const n2dominoes,
00611                  int ***const naset,
00612                  int ***const nbset,
00613                  int ***const nmset,
00614                  int **const nahandle,
00615                  int **const nbhandle,
00616                  int ****const aset,
00617                  int ****const bset,
00618                  int ****const mset,
00619                  int ***const ahandle,
00620                  int ***const bhandle,
00621                  const char *const boss_name,
00622                  double percentage,
00623                  double d2p_heuristic_a_maxtime,
00624                  double d2p_heuristic_b_maxtime,
00625                  double d2p_heuristic_c_maxtime)
00626 {
00627 
00628   int i, t, rval = 0;
00629   int nineq = 0,
00630       *nhandles = 0,
00631       **handle_size = 0,
00632       ***handles = 0,
00633       *nteeth = 0,
00634       **teeth_size = 0,
00635       ***teeth = 0,
00636       **teeth_k = 0,
00637       ***teeth_handle = 0,
00638       ***teeth_nhalf = 0,
00639       ****teeth_halves = 0,
00640       **ineq_coef = 0;
00641   double* violation = 0; 
00642 
00643   //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00644   rval = KPseparator (2,
00645                       nnodes, 
00646                       norig_edges, 
00647                       orig_edges, 
00648                       orig_weight, 
00649                       &nineq,
00650                       &nhandles,
00651                       &handle_size,
00652                       &handles,
00653                       &nteeth, 
00654                       &teeth_size,
00655                       &teeth,
00656                       &teeth_k,
00657                       &teeth_handle,
00658                       &teeth_nhalf,
00659                       &teeth_halves, 
00660                       boss_name, 
00661                       percentage);
00662   CHECKRVAL(rval);
00663   //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00664 
00665   *n2ineq = nineq;
00666 
00667   *n2dominoes = EGsMalloc(int,nineq);
00668   for(i=0; i<nineq; i++)
00669     (*n2dominoes)[i] = nteeth[i];
00670 
00671   //(*n2dominoes) = (nteeth);
00672   
00673   unsigned char *vdummy = EGsMalloc(unsigned char,nnodes);
00674 
00675   if(nineq)
00676   {
00677     //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00678     *naset = EGsMalloc(int*,nineq);
00679     *nbset = EGsMalloc(int*,nineq);
00680     *nmset = EGsMalloc(int*,nineq);
00681     *nahandle = EGsMalloc(int,nineq);
00682     *nbhandle = EGsMalloc(int,nineq);
00683     *aset = EGsMalloc(int**,nineq);
00684     *bset = EGsMalloc(int**,nineq);
00685     *mset = EGsMalloc(int**,nineq);
00686     *ahandle = EGsMalloc(int*,nineq);
00687     *bhandle = EGsMalloc(int*,nineq);
00688     for(i=0; i<nineq; i++)
00689     {
00690       (*naset)[i] = EGsMalloc(int,nteeth[i]);
00691       (*nbset)[i] = EGsMalloc(int,nteeth[i]);
00692       (*nmset)[i] = EGsMalloc(int,nteeth[i]);
00693       (*aset)[i] = EGsMalloc(int*,nteeth[i]);
00694       (*bset)[i] = EGsMalloc(int*,nteeth[i]);
00695       (*mset)[i] = EGsMalloc(int*,nteeth[i]);
00696       for(t=0; t < nteeth[i]; t++)
00697       {
00698         rval = EGkpTo2pTooth( teeth_size[i][t],
00699                               teeth[i][t],
00700                               teeth_k[i][t],
00701                               teeth_handle[i][t],
00702                               teeth_nhalf[i][t],
00703                               teeth_halves[i][t],
00704                               &((*naset)[i][t]),
00705                               &((*nbset)[i][t]),
00706                               &((*nmset)[i][t]),
00707                               &((*aset)[i][t]),
00708                               &((*bset)[i][t]),
00709                               &((*mset)[i][t]),
00710                               nnodes,
00711                               vdummy );
00712         CHECKRVAL(rval);
00713       }
00714     }
00715     //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00716 
00717     for(i=0; i<nineq; i++)
00718     {
00719       (*nahandle)[i] = handle_size[i][0];
00720       if (nhandles[i] > 1)
00721         (*nbhandle)[i] = handle_size[i][1];
00722       else
00723         (*nbhandle)[i] = 0;
00724     }
00725     //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00726 
00727     ineq_coef = EGsMalloc(int*,nineq);
00728     violation = EGsMalloc(double,nineq);
00729     for(i=0; i<nineq; i++)
00730     {
00731       ineq_coef[i] = EGsMalloc(int,norig_edges);
00732       /* a handle */
00733       (*ahandle)[i] = EGsMalloc(int,(*nahandle)[i]);
00734       for(t=0; t<((*nahandle)[i]); t++)
00735          (*ahandle)[i][t] = handles[i][0][t];
00736      /* bhandle */
00737       if ( (*nbhandle)[i] )
00738          (*bhandle)[i] = EGsMalloc(int,(*nbhandle)[i]);
00739       else
00740          (*bhandle)[i] = 0;
00741       for(t=0; t<((*nbhandle)[i]); t++)
00742          (*bhandle)[i][t] = handles[i][1][t];
00743     }
00744     //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00745     /* check the inequality */
00746     rval = EG2pChecker( nnodes, norig_edges, orig_edges, orig_weight, 
00747                         *n2ineq, *n2dominoes, *naset, *nbset, *nmset, 
00748                         *nahandle, *nbhandle, *aset, *bset, *mset, *ahandle,
00749                         *bhandle, violation, ineq_coef);
00750     CHECKRVAL(rval);
00751     //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00752   
00753     /* free constraints in old form */
00754     for(i=0; i < nineq; i++)
00755     {
00756       EGfree((ineq_coef[i]));
00757       EGfreePKPCB(nhandles[i],
00758                   handle_size[i],
00759                   handles[i],
00760                   nteeth[i],
00761                   teeth_size[i],
00762                   teeth[i],
00763                   teeth_k[i],
00764                   teeth_handle[i],
00765                   teeth_nhalf[i],
00766                   teeth_halves[i]);
00767       //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00768     }
00769     //MESSAGE(0,"nhandles %p, nineq %d",(void*)nhandles, nineq);
00770     free(nhandles);
00771     free(handle_size);
00772     free(handles);
00773     free(nteeth);
00774     free(teeth_size);
00775     free(teeth);
00776     free(teeth_k);
00777     free(teeth_handle);
00778     free(teeth_nhalf);
00779     free(teeth_halves);
00780     EGfree(ineq_coef);
00781     EGfree(violation);
00782   }
00783   EGfree(vdummy);
00784   return rval;
00785 }

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