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
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
00050
00051
00052 int i,
00053 rval;
00054 int is_connected;
00055
00056 int eliminated_edges_b = 0,
00057 is_G_planar_b = 0;
00058
00059 int *edges = 0,
00060 nedges = 0,
00061 nelim_edges = 0;
00062 double *weight = 0;
00063
00064 graphP primalG = 0;
00065
00066 EGdGraph_t *biDualG = 0;
00067
00068 EGlist_t *dlist = 0;
00069 EGlist_t **dembed = 0;
00070 EGlist_t **lembed = 0;
00071
00072 EGmemPool_t *mem = 0;
00073
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
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
00113 mem = EGnewMemPool (512, EGmemPoolNewSize, EGmemPoolNewSize (1));
00114
00115
00116 dlist = EGnewList (mem);
00117
00118
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
00139
00140
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
00156
00157
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
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
00173
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
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
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
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
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
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
00272
00273 fprintf (stdout, "KP Separator: Looking for dual dominoes.\n");
00274 fflush (stdout);
00275 #endif
00276
00277
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
00291 rval = EGuntangleAllDomino (dlist, biDualG, dembed, mem);
00292 CHECKRVAL (rval);
00293
00294 if (!dlist->size)
00295 goto END_DP;
00296
00297
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
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
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
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
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
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
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
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
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
00530
00531
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
00545 if (dlist)
00546 {
00547 if (dlist->size)
00548 EGlistClearMP (dlist, EGfreeDdomino, mem);
00549 EGfreeList (dlist);
00550 }
00551
00552
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
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
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
00595 EGfreeMemPool (mem);
00596 gp_Free (&primalG);
00597 EGfree(pedummy);
00598 EGfree(pndummy);
00599
00600
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
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
00664
00665 *n2ineq = nineq;
00666
00667 *n2dominoes = EGsMalloc(int,nineq);
00668 for(i=0; i<nineq; i++)
00669 (*n2dominoes)[i] = nteeth[i];
00670
00671
00672
00673 unsigned char *vdummy = EGsMalloc(unsigned char,nnodes);
00674
00675 if(nineq)
00676 {
00677
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
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
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
00733 (*ahandle)[i] = EGsMalloc(int,(*nahandle)[i]);
00734 for(t=0; t<((*nahandle)[i]); t++)
00735 (*ahandle)[i][t] = handles[i][0][t];
00736
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
00745
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
00752
00753
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
00768 }
00769
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 }