00001 #include "eg_greedykp.h"
00002 #define EG_PRIMALIZATION_ERROR 0.001
00003
00004 EGgreedyData_t* EGnewGreedyData(EGmemPool_t *mem)
00005 {
00006 EGgreedyData_t *data;
00007
00008 data = EGmemPoolSMalloc(mem, EGgreedyData_t, 1);
00009
00010 data->bdG = 0;
00011 data->cycleG = 0;
00012 data->bdGnodeMap = 0;
00013 data->cycleEdgeMap = 0;
00014 data->ddom_list = 0;
00015 data->ee_dist = 0;
00016 data->ee_prec = 0;
00017 data->eo_prec = 0;
00018
00019 return data;
00020 }
00021
00022 void EGfreeGreedyData(void *vdata)
00023 {
00024
00025 unsigned int i;
00026 EGgreedyData_t *data = (EGgreedyData_t*)(vdata);
00027
00028 EGmemPool_t *mem = data->cycleG->mem;
00029 if(data->randa) EGfree(data->randa);
00030 if(data->randb) EGfree(data->randb);
00031
00032 if (data->pndummy)
00033 free(data->pndummy);
00034 if (data->pedummy)
00035 free(data->pedummy);
00036
00037 if (data->bdnodes)
00038 free(data->bdnodes);
00039 if (data->pedges)
00040 free(data->pedges);
00041 if (data->pedgevals)
00042 free(data->pedgevals);
00043
00044 if (data->bdGnodeMap)
00045 EGmemPoolSFree(data->bdGnodeMap, EGdGraphNode_t*, data->bdG->nodes->size, mem);
00046 if (data->cycleEdgeMap)
00047 EGmemPoolSFree(data->cycleEdgeMap, EGdGraphEdge_t*, data->cycleG->nedges, mem);
00048
00049 for(i=0; i < data->bdG->nodes->size; i++)
00050 {
00051 if (data->ee_dist)
00052 EGmemPoolSFree(data->ee_dist[i], EGdijkstraCost_t, i+1, mem);
00053 #if EG_KP_HEURISTIC
00054 if (data->eo_dist)
00055 EGmemPoolSFree(data->eo_dist[i], EGdijkstraCost_t, i+1, mem);
00056 #endif
00057 if (data->ee_prec)
00058 EGmemPoolSFree(data->ee_prec[i], int, i+1, mem);
00059 if (data->eo_prec)
00060 EGmemPoolSFree(data->eo_prec[i], int, i+1, mem);
00061 }
00062
00063 if (data->ee_dist)
00064 EGmemPoolSFree(data->ee_dist, EGdijkstraCost_t*, data->bdG->nodes->size, mem);
00065 #if EG_KP_HEURISTIC
00066 if (data->eo_dist)
00067 EGmemPoolSFree(data->eo_dist, EGdijkstraCost_t*, data->bdG->nodes->size, mem);
00068 #endif
00069 if (data->ee_prec)
00070 EGmemPoolSFree(data->ee_prec, int*, data->bdG->nodes->size, mem);
00071 if (data->eo_prec)
00072 EGmemPoolSFree(data->eo_prec, int*, data->bdG->nodes->size, mem);
00073
00074 #if EG_KP_HEURISTIC
00075 EGmemPoolSFree(data->bdGtoCycleGmap, EGdGraphNode_t*, data->bdG->nodes->size, mem);
00076 #endif
00077
00078 if (data->cycleG)
00079 {
00080 EGdGraphClearMP(data->cycleG, EGfreeCycleDataMP, EGfreeDijkstraNodeDataMP, 0, mem, mem, 0);
00081 EGfreeDGraph(data->cycleG);
00082 }
00083
00084 EGmemPoolSFree(data, EGgreedyData_t, 1, mem);
00085
00086 return;
00087
00088 }
00089
00090 int EGfillGreedyData (EGgreedyData_t * data,
00091 EGdGraph_t * bdG,
00092 EGlist_t * ddom_list,
00093 EGlist_t** dembed,
00094 graphP G,
00095 int norig_nodes,
00096 int norig_edges,
00097 int nplanar_edges,
00098 int *orig_edges,
00099 int *planar_edges,
00100 double *orig_weight,
00101 double *planar_weight)
00102 {
00103
00104 int rval=0;
00105 register unsigned int i;
00106 EGmemPool_t *mem = bdG->mem;
00107 memset(data,0,sizeof(EGgreedyData_t));
00108 static size_t dij_os[6] = {
00109 [EG_DIJ_DIST] = offsetof (EGdijkstraNodeData_t, dist),
00110 [EG_DIJ_NDIST] = offsetof (EGdijkstraNodeData_t, ndist),
00111 [EG_DIJ_FATHER] = offsetof (EGdijkstraNodeData_t, father),
00112 [EG_DIJ_MARKER] = offsetof (EGdijkstraNodeData_t, marker),
00113 [EG_DIJ_HCONNECTOR] = offsetof (EGdijkstraNodeData_t, hc),
00114 [EG_DIJ_ELENGTH] = offsetof (EGcycleData_t, weight)
00115 };
00116
00117 EGdijkstraCost_t max_cycle_edge = EGdijkstraToCost(1.0),
00118 max_even_path = EGdijkstraToCost(1.0);
00119
00120 data->norig_nodes = norig_nodes;
00121 data->norig_edges = norig_edges;
00122 data->nplanar_edges = nplanar_edges;
00123 data->randa = EGsMalloc(unsigned int,norig_edges);
00124 data->randb = EGsMalloc(unsigned int,norig_edges);
00125 data->pndummy = EGsMalloc(unsigned char, data->norig_nodes);
00126 data->pedummy = EGsMalloc(unsigned char, data->norig_edges);
00127 data->pedges = EGsMalloc(EGdGraphEdge_t*,data->norig_edges);
00128 data->bdnodes = EGsMalloc(EGdGraphNode_t*,bdG->nodes->size);
00129 data->pedgevals = EGsMalloc(double,data->norig_edges);
00130
00131 data->nviolated = 0;
00132 data->min_violated = 10000.0;
00133 data->max_violated = -10000.0;
00134
00135 for( i = norig_edges ; i-- ; )
00136 {
00137 data->randa[i] = random()>>12;
00138 data->randb[i] = random()>>12;
00139 }
00140 data->orig_edges = orig_edges;
00141 data->planar_edges = planar_edges;
00142
00143 data->orig_weight = orig_weight;
00144 data->planar_weight = planar_weight;
00145
00146 data->bdG = bdG;
00147 data->ddom_list = ddom_list;
00148 data->G = G;
00149 data->cycleG = EGnewCycleGraph (mem, ddom_list, bdG, max_cycle_edge);
00150 TEST(!data->cycleG, "error generating cycle graph");
00151
00152 #if DISPLAY_MODE
00153 fprintf (stdout, "KP greedy data: Cycle graph has %u nodes and %d arcs.\n",
00154 data->cycleG->nodes->size, data->cycleG->nedges);
00155 fflush (stdout);
00156 #endif
00157
00158 data->dembed = dembed;
00159 data->ee_dist = EGmemPoolSMalloc (mem, EGdijkstraCost_t *, bdG->nodes->size);
00160 #if EG_KP_HEURISTIC
00161 data->eo_dist = EGmemPoolSMalloc (mem, EGdijkstraCost_t *, bdG->nodes->size);
00162 #endif
00163 data->ee_prec = EGmemPoolSMalloc (mem, int *, bdG->nodes->size);
00164 data->eo_prec = EGmemPoolSMalloc (mem, int *, bdG->nodes->size);
00165
00166 for (i = 0; i < bdG->nodes->size; i++)
00167 {
00168 data->ee_dist[i] = EGmemPoolSMalloc (mem, EGdijkstraCost_t, i+1);
00169 #if EG_KP_HEURISTIC
00170 data->eo_dist[i] = EGmemPoolSMalloc (mem, EGdijkstraCost_t, i+1);
00171 #endif
00172 data->ee_prec[i] = EGmemPoolSMalloc (mem, int, i+1);
00173 data->eo_prec[i] = EGmemPoolSMalloc (mem, int, i+1);
00174 }
00175
00176 data->cycleEdgeMap = EGmemPoolSMalloc(mem, EGdGraphEdge_t*, data->cycleG->nedges);
00177 {
00178 EGlistNode_t *vit, *eit;
00179 EGdGraphNode_t *v;
00180 EGdGraphEdge_t *e;
00181 for( vit = data->cycleG->nodes->begin; vit; vit=vit->next )
00182 {
00183 v = (EGdGraphNode_t*)(vit->this);
00184 for(eit=v->out_edges->begin; eit; eit=eit->next)
00185 {
00186 e = (EGdGraphEdge_t*)(eit->this);
00187 data->cycleEdgeMap[e->id] = e;
00188 }
00189 }
00190 }
00191
00192
00193
00194
00195 data->bdGnodeMap = EGmemPoolSMalloc(mem, EGdGraphNode_t*, bdG->nodes->size);
00196 {
00197 EGlistNode_t *it;
00198
00199 for(i=0, it=bdG->nodes->begin; it; it=it->next, i++)
00200 {
00201 data->bdGnodeMap[i] = (EGdGraphNode_t*)(it->this);
00202 }
00203 }
00204
00205
00206 #if EG_KP_HEURISTIC
00207 {
00208 EGdGraphNode_t *cycle_v, *bdg_v;
00209 EGlistNode_t *it;
00210
00211 data->bdGtoCycleGmap = EGmemPoolSMalloc(mem, EGdGraphNode_t*, data->bdG->nodes->size);
00212 for( it = data->cycleG->nodes->begin; it; it=it->next->next )
00213 {
00214 cycle_v = (EGdGraphNode_t*)(it->this);
00215 bdg_v = data->bdGnodeMap[cycle_v->id / 2];
00216 data->bdGtoCycleGmap[ bdg_v->id ] = cycle_v;
00217 }
00218 }
00219 #endif
00220
00221
00222 #if EG_GREEDYKP_FILLTABLE
00223 {
00224 EGlistNode_t *u_it, *v_it;
00225 EGdGraphNode_t *s, *t;
00226
00227 EGdijkstraCost_t dist;
00228 int prec;
00229 int s_id, t_id;
00230
00231 EGheap_t *my_heap = EGnewHeap (mem, 2, data->cycleG->nodes->size);
00232
00233
00234 for(u_it=data->cycleG->nodes->begin; u_it; u_it=((u_it->next)->next))
00235 {
00236
00237 TEST (!(u_it->next), "cycle graph badly defined");
00238
00239 s = (EGdGraphNode_t*)(u_it->this);
00240
00241 rval = EGpartialDijkstra (s,0,max_even_path,dij_os,my_heap,data->cycleG);
00242 TEST(rval, "error running dijkstra");
00243
00244
00245 for(v_it=data->cycleG->nodes->begin; v_it != u_it->next->next; v_it=v_it->next)
00246 {
00247 t = (EGdGraphNode_t*)(v_it->this);
00248
00249 s_id = data->bdGnodeMap[s->id/2]->id;
00250 t_id = data->bdGnodeMap[t->id/2]->id;
00251
00252
00253
00254
00255 if (v_it == u_it)
00256 {
00257 data->ee_dist[s_id][t_id] = 0;
00258 data->ee_prec[s_id][t_id] = -1;
00259 continue;
00260 }
00261
00262
00263 if (EGdijkstraGetMarker(t, dij_os) == UINT_MAX)
00264 {
00265 dist = EG_DIJKSTRA_COST_MAX;
00266 prec = 0;
00267 }
00268 else
00269 {
00270 dist = EGdijkstraGetDist(t, dij_os);
00271 prec = EGdijkstraGetFather(t, dij_os)->id;
00272 }
00273
00274
00275 if (t->id & 1)
00276 {
00277 if (t_id < s_id)
00278 {
00279 #if EG_KP_HEURISTIC
00280 data->eo_dist[s_id][t_id] = dist;
00281 #endif
00282 data->eo_prec[s_id][t_id] = prec;
00283 }
00284 else
00285 {
00286 #if EG_KP_HEURISTIC
00287 data->eo_dist[t_id][s_id] = dist;
00288 #endif
00289 data->eo_prec[t_id][s_id] = prec;
00290 }
00291 }
00292 else
00293 {
00294 if (t_id < s_id)
00295 {
00296 data->ee_dist[s_id][t_id] = dist;
00297 data->ee_prec[s_id][t_id] = prec;
00298 }
00299 else
00300 {
00301 data->ee_dist[t_id][s_id] = dist;
00302 data->ee_prec[t_id][s_id] = prec;
00303 }
00304 }
00305
00306 }
00307 }
00308
00309 EGfreeHeap (my_heap, mem);
00310
00311 }
00312
00313 #endif
00314
00315 return rval;
00316
00317 }
00318
00319
00320 EGdualCut_t* EGnewDualCut(EGmemPool_t *mem, unsigned int sz)
00321 {
00322
00323 EGdualCut_t *dc;
00324
00325 dc = EGmemPoolSMalloc(mem, EGdualCut_t, 1);
00326
00327 dc->sz = sz;
00328 dc->value = EGdijkstraToCost(0.0);
00329
00330 if(sz)
00331 dc->edges = EGmemPoolSMalloc(mem, EGdGraphEdge_t*, sz);
00332 else
00333 dc->edges = 0;
00334
00335 return dc;
00336
00337 }
00338
00339 void EGfreeDualCut(void *v, EGmemPool_t *mem)
00340 {
00341
00342 EGdualCut_t *dc = (EGdualCut_t*)(v);
00343
00344 if (dc->sz)
00345 EGmemPoolSFree(dc->edges, EGdGraphEdge_t*, dc->sz, mem);
00346 EGmemPoolSFree(dc, EGdualCut_t, 1, mem);
00347
00348 return;
00349
00350 }
00351
00352 EGdcutIter_t* EGnewDcutIter(EGgreedyData_t *gdata)
00353 {
00354
00355 EGdcutIter_t *zit;
00356
00357 if (!gdata || !gdata->cycleG || !gdata->ddom_list)
00358 return 0;
00359
00360 zit = EGmemPoolSMalloc(gdata->cycleG->mem, EGdcutIter_t, 1);
00361
00362 zit->num_it = 0;
00363 zit->ddit = gdata->ddom_list->begin;
00364 zit->current_side = 0;
00365 zit->current_middle = 0;
00366 zit->gdata = gdata;
00367
00368 return zit;
00369
00370 }
00371
00372 void EGfreeDcutIter(void *v)
00373 {
00374
00375 EGdcutIter_t *zit = (EGdcutIter_t*)(v);
00376
00377 if (!v)
00378 return;
00379
00380 EXIT(!zit->gdata || !zit->gdata->cycleG, "cycleG is null");
00381
00382 EGmemPoolSFree(v, EGdcutIter_t, 1, zit->gdata->cycleG->mem);
00383
00384 return;
00385
00386 }
00387
00388 int EGincrementDcutIter(EGdcutIter_t *zit)
00389 {
00390
00391 TEST(!zit || !zit->ddit, "error with zit");
00392
00393 zit->num_it += 1;
00394 zit->ddit = zit->ddit->next;
00395
00396 if (!zit->ddit)
00397 {
00398
00399 if (!zit->current_side)
00400 zit->current_side = 1;
00401 else if (zit->current_middle < 2)
00402 {
00403 zit->current_middle += 1;
00404 zit->current_side = 0;
00405 }
00406 else
00407 return 0;
00408
00409 zit->ddit = zit->gdata->ddom_list->begin;
00410
00411 }
00412
00413 return 0;
00414
00415 }
00416
00417 EGdualCut_t* EGgetDcut(EGdcutIter_t *zit)
00418 {
00419
00420 unsigned int i, j, p1, p2;
00421 EGdualCut_t *dc;
00422 EGddomino_t *ddom;
00423 EGmemPool_t *mem = zit->gdata->cycleG->mem;
00424
00425 size_t mos[6];
00426 mos[EG_DIJ_ELENGTH] = offsetof(EGmengerEdgeData_t, cost);
00427
00428 EGdijkstraCost_t val=EGdijkstraToCost(0.0);
00429
00430 EXIT(!zit || !zit->ddit, "bad zit");
00431
00432 ddom = zit->ddit->this;
00433
00434 switch(zit->current_middle)
00435 {
00436 case 0:
00437 p1=1; p2=2;
00438 break;
00439 case 1:
00440 p1=0; p2=2;
00441 break;
00442 case 2:
00443 p1=0; p2=1;
00444 break;
00445 default:
00446 return 0;
00447 break;
00448 }
00449
00450 dc = EGnewDualCut(mem, ddom->npath[p1]+ddom->npath[p2]);
00451
00452 for(i=0, j=0; i < ddom->npath[p1]; i++, j++)
00453 {
00454 dc->edges[j] = (EGdGraphEdge_t*)(ddom->path[p1][i]);
00455 val = EGdijkstraCostAdd(val, EGdijkstraGetEdgeLength(dc->edges[j], mos));
00456 }
00457 for(i=ddom->npath[p2]; i; i--, j++)
00458 {
00459 dc->edges[j] = (EGdGraphEdge_t*)(ddom->path[p2][i-1]);
00460 val = EGdijkstraCostAdd(val, EGdijkstraGetEdgeLength(dc->edges[j], mos));
00461 }
00462
00463 dc->value = val;
00464
00465 return dc;
00466
00467 }
00468
00469 int EGgetOddPrec (unsigned int s, unsigned int t, EGgreedyData_t*data)
00470 {
00471
00472 if (t < s)
00473 return ( data->eo_prec[s][t] );
00474 else
00475 return ( data->eo_prec[t][s] );
00476
00477 }
00478
00479 int EGgetEvenPrec (unsigned int s, unsigned int t, EGgreedyData_t*data)
00480 {
00481 #if DEBUG > 3
00482 if (s >= data->bdG->nodes->size)
00483 MESSAGE(1, "out of range s %u / %u", s, data->bdG->nodes->size);
00484 if (t >= data->bdG->nodes->size)
00485 MESSAGE(1, "out of range t %u / %u", t, data->bdG->nodes->size);
00486 #endif
00487
00488 if (t < s)
00489 return ( data->ee_prec[s][t] );
00490 else
00491 return ( data->ee_prec[t][s] );
00492 }
00493
00494 EGdijkstraCost_t EGgetEvenDistance (unsigned s, unsigned t, EGgreedyData_t*data)
00495 {
00496
00497 #if DEBUG > 3
00498 if (s >= data->bdG->nodes->size)
00499 MESSAGE(1, "out of range s %u / %u", s, data->bdG->nodes->size);
00500 if (t >= data->bdG->nodes->size)
00501 MESSAGE(1, "out of range t %u / %u", t, data->bdG->nodes->size);
00502 #endif
00503
00504 if(t < s)
00505 return ( data->ee_dist[s][t] );
00506 else
00507 return ( data->ee_dist[t][s] );
00508
00509 }
00510
00511 #if EG_KP_HEURISTIC
00512 EGdijkstraCost_t EGgetOddDistance (unsigned s, unsigned t, EGgreedyData_t*data)
00513 {
00514
00515 if(t < s)
00516 return ( data->eo_dist[s][t] );
00517 else
00518 return ( data->eo_dist[t][s] );
00519
00520 }
00521 #endif
00522
00523 int EGextractEEpath(unsigned int s,
00524 unsigned int t,
00525 EGgreedyData_t *data,
00526 EGlist_t *path)
00527 {
00528
00529 unsigned int curr_s = s, curr_t = t;
00530 int tot_even = 1, e_even = 1, rval=1;
00531 EGdGraphEdge_t *e;
00532 EGcycleData_t *e_data;
00533
00534 EGdijkstraCost_t dist;
00535 dist = EGdijkstraToCost(0.0);
00536
00537 EGlistClear(path, nullFree);
00538
00539 int ncycle = 0;
00540 while ( curr_t != curr_s )
00541 {
00542
00543 if (ncycle++ > 1000000)
00544 goto CLEANUP;
00545
00546 if (tot_even)
00547 e = data->cycleEdgeMap[EGgetEvenPrec(curr_s,curr_t,data)];
00548 else
00549 e = data->cycleEdgeMap[EGgetOddPrec(curr_s,curr_t,data)];
00550
00551 EGlistPushBack(path, e);
00552
00553 e_data = (EGcycleData_t*)(e->data);
00554
00555 dist = EGdijkstraCostAdd(dist, e_data->weight);
00556
00557 if ( e_data->e )
00558 e_even = 1;
00559 else
00560 e_even = 0;
00561
00562 if ( data->bdGnodeMap[e->head->id / 2]->id == curr_s )
00563 curr_s = data->bdGnodeMap[e->tail->id / 2]->id;
00564 else if ( data->bdGnodeMap[e->tail->id / 2]->id == curr_s )
00565 curr_s = data->bdGnodeMap[e->head->id / 2]->id;
00566 else if ( data->bdGnodeMap[e->head->id / 2]->id == curr_t )
00567 curr_t = data->bdGnodeMap[e->tail->id / 2]->id;
00568 else if ( data->bdGnodeMap[e->tail->id / 2]->id == curr_t )
00569 curr_t = data->bdGnodeMap[e->head->id / 2]->id;
00570 else
00571 {
00572 fprintf(stderr, "missing case\n");
00573 fprintf(stderr, "curr_s = %u\n", curr_s);
00574 fprintf(stderr, "curr_t = %u\n", curr_t);
00575 fprintf(stderr, "e_head = %u\n", data->bdGnodeMap[e->head->id / 2]->id);
00576 fprintf(stderr, "e_tail = %u\n", data->bdGnodeMap[e->tail->id / 2]->id);
00577 goto CLEANUP;
00578 }
00579
00580 if ( e_even == tot_even )
00581 tot_even = 1;
00582 else
00583 tot_even = 0;
00584
00585 }
00586
00587 if (!tot_even)
00588 {
00589
00590 EGlistClear(path, nullFree);
00591 }
00592 else
00593 {
00594 EGdijkstraCost_t const evendist = EGgetEvenDistance(s,t,data);
00595 if ( fabs(EGdijkstraCostToLf(dist) - EGdijkstraCostToLf( evendist)) > 0.0001 )
00596 {
00597 fprintf(stderr, "computed distance = %lf.\n", EGdijkstraCostToLf(dist));
00598 fprintf(stderr, "distance should be = %lf.\n", EGdijkstraCostToLf(evendist));
00599 fprintf(stderr, "distances do not match\n");
00600 rval = 1;
00601 goto CLEANUP;
00602 }
00603 }
00604
00605 rval = 0;
00606 CLEANUP:
00607
00608 return rval;
00609
00610 }
00611
00612 EGdkpc_t* EGdkdomToDKPC(EGdkdomino_t *dkdom,
00613 EGmemPool_t *mem)
00614 {
00615
00616 EGdkpc_t *dkpc;
00617 unsigned int i;
00618
00619 dkpc = EGmemPoolSMalloc(mem, EGdkpc_t, 1);
00620
00621 dkpc->nhandles = 0;
00622
00623 dkpc->dkdom = EGnewList(mem);
00624 for(i=0; i<EG_KPC_MAX_HANDLES; i++)
00625 dkpc->FH[i] = EGnewList(mem);
00626
00627 EGlistPushBack(dkpc->dkdom, dkdom);
00628
00629 dkpc->slack = EGdijkstraCostSub( dkdom->cut->value, EGdijkstraToCost(2.0) );
00630
00631 return dkpc;
00632
00633 }
00634
00635 EGdkpc_t* EGdcutToDKPC(EGdualCut_t *dc,
00636 unsigned int orientation,
00637 EGmemPool_t *mem)
00638 {
00639
00640 EGdkdomino_t *dkdom;
00641 dkdom = EGdcutToDKdom( EG_KPC_MAX_HANDLES, dc, orientation, mem);
00642 return (EGdkdomToDKPC(dkdom, mem));
00643
00644 }
00645
00646 void EGfreeDKPC(void *v, EGmemPool_t *mem)
00647 {
00648
00649 EGdkpc_t *dkpc;
00650 unsigned int i;
00651
00652 dkpc = (EGdkpc_t*)(v);
00653
00654 for(i=0; i < EG_KPC_MAX_HANDLES; i++)
00655 EGfreeList(dkpc->FH[i]);
00656
00657 EGlistClearMP(dkpc->dkdom, EGfreeDKdomino, mem);
00658 EGfreeList(dkpc->dkdom);
00659
00660 EGmemPoolSFree(dkpc, EGdkpc_t, 1, mem);
00661
00662 return;
00663
00664 }
00665
00666 EGdkdomino_t* EGdcutToDKdom(unsigned int max_k,
00667 EGdualCut_t *dc,
00668 unsigned int orientation,
00669 EGmemPool_t *mem)
00670 {
00671
00672 EGdkdomino_t *dkd=0;
00673
00674 dkd = EGmemPoolSMalloc(mem, EGdkdomino_t, 1);
00675 dkd->k = 0;
00676 dkd->max_k = max_k;
00677
00678 dkd->orientation=orientation;
00679 dkd->pairs = EGmemPoolSMalloc(mem, EGinternalPairs_t, max_k);
00680 dkd->handleid = EGmemPoolSMalloc(mem, unsigned int, max_k);
00681 dkd->cut = EGcopyDualCut(mem, dc);
00682
00683 return dkd;
00684
00685 }
00686
00687 void EGfreeDKdomino(void *v, EGmemPool_t *mem)
00688 {
00689
00690 unsigned int i;
00691 EGdkdomino_t *dkd;
00692
00693 dkd = (EGdkdomino_t*)(v);
00694
00695 for(i=0; i<dkd->max_k; i++)
00696 EGinternalPairsClear(&(dkd->pairs[i]),mem);
00697 EGmemPoolSFree(dkd->pairs, EGinternalPairs_t, dkd->max_k, mem);
00698 EGmemPoolSFree(dkd->handleid, unsigned int, dkd->max_k, mem);
00699
00700 EGfreeDualCut(dkd->cut, mem);
00701
00702 EGmemPoolSFree(dkd, EGdkdomino_t, 1, mem);
00703
00704 return;
00705
00706 }
00707
00708 EGdijkstraCost_t EGweightDKdomino(EGdkdomino_t *dkd)
00709 {
00710
00711 unsigned int i,j;
00712 EGdijkstraCost_t weight;
00713 size_t mos[EG_MENGER_NUMOS];
00714
00715 mos[EG_MENGER_ECOST] = offsetof (EGmengerEdgeData_t, cost);
00716 mos[EG_MENGER_EDATA] = offsetof (EGmengerEdgeData_t, data);
00717
00718 EGcomputeDualCutValue(dkd->cut);
00719 weight = dkd->cut->value;
00720
00721 for(i=0; i < dkd->k; i++)
00722 for(j=0; j < dkd->pairs[i].npath; j++)
00723 weight = EGdijkstraCostAdd(weight,
00724 EGmengerGetEdgeCost(dkd->pairs[i].stpath[j],mos));
00725
00726 weight = EGdijkstraCostSub(weight, EGdijkstraToCost( (double)(dkd->k+2) ));
00727
00728 return weight;
00729
00730 }
00731
00732 EGdijkstraCost_t EGcomputeDKPCslack(EGdkpc_t *dkpc)
00733 {
00734
00735 unsigned int i;
00736 EGlistNode_t *it;
00737 size_t mos[EG_MENGER_NUMOS];
00738
00739
00740
00741 EGdijkstraCost_t slack = EGdijkstraToCost(0.0);
00742 EGdijkstraCost_t weight;
00743
00744 mos[EG_MENGER_ECOST] = offsetof (EGmengerEdgeData_t, cost);
00745 mos[EG_MENGER_EDATA] = offsetof (EGmengerEdgeData_t, data);
00746
00747
00748
00749 for(it=dkpc->dkdom->begin; it; it=it->next)
00750 {
00751 weight = EGweightDKdomino( (EGdkdomino_t*)(it->this) );
00752 slack = EGdijkstraCostAdd(slack, weight);
00753 }
00754
00755
00756
00757 for(i=0; i < dkpc->nhandles; i++)
00758 for(it=dkpc->FH[i]->begin; it; it=it->next)
00759 slack = EGdijkstraCostAdd(slack, EGmengerGetEdgeCost(it->this,mos) );
00760
00761
00762
00763 slack = EGdijkstraCostSub(slack, EGdijkstraToCost( (double)(dkpc->nhandles) ) );
00764
00765 return slack;
00766
00767 }
00768
00769 int EGgrowHandle(EGdkpc_t *dkpc,
00770 EGdkdomino_t *link_dkdom,
00771 EGinternalPairs_t *p,
00772 EGgreedyData_t *data,
00773 EGmemPool_t *mem,
00774 unsigned char *const pndummy,
00775 unsigned char *const pedummy)
00776 {
00777
00778 int rval, h;
00779 EGlist_t *extpath;
00780 EGlistNode_t *it;
00781 EGdGraphEdge_t *e;
00782 EGcycleData_t *edata;
00783 EGdkdomino_t *dkdom = 0;
00784
00785
00786 h = dkpc->nhandles;
00787
00788
00789 TEST( h >= EG_KPC_MAX_HANDLES, "# of handles exceeded");
00790
00791
00792 extpath = p->extpath;
00793
00794 if (!extpath->size)
00795 goto CLEANUP;
00796
00797
00798
00799 rval = EGgrowDKdomino(link_dkdom, p, h, mem);
00800 CHECKRVAL(rval);
00801
00802
00803
00804 for(it=extpath->begin; it; it=it->next)
00805 {
00806 e = (EGdGraphEdge_t*)(it->this);
00807 edata = (EGcycleData_t*)(e->data);
00808 if (edata->e)
00809 EGlistPushBack(dkpc->FH[h],edata->e);
00810 if (edata->ddom)
00811 {
00812 dkdom = EGddominoToDKdom(edata->ddom, h, EG_KPC_MAX_HANDLES, data, mem, pndummy, pedummy);
00813 EGlistPushBack(dkpc->dkdom,dkdom);
00814 }
00815 }
00816
00817 dkpc->nhandles += 1;
00818 dkpc->slack = EGdijkstraCostAdd(dkpc->slack, p->value);
00819 dkpc->slack = EGdijkstraCostSub(dkpc->slack, EGdijkstraToCost(2.0));
00820
00821 CLEANUP:
00822
00823 return 0;
00824
00825 }
00826
00827 int EGgrowDKdomino(EGdkdomino_t *dkd,
00828 EGinternalPairs_t *p,
00829 int handle_num,
00830 EGmemPool_t *mem)
00831 {
00832
00833 TEST( dkd->k >= dkd->max_k, "invalid dkd k size (k = %d | max = %d)", dkd->k, dkd->max_k);
00834
00835 dkd->handleid[dkd->k] = handle_num;
00836 dkd->pairs[dkd->k].s = p->s;
00837 dkd->pairs[dkd->k].t = p->t;
00838
00839
00840
00841 dkd->pairs[dkd->k].value = p->value;
00842
00843
00844 dkd->pairs[dkd->k].npath = p->npath;
00845 dkd->pairs[dkd->k].stpath = EGmemPoolSMalloc(mem,EGdGraphEdge_t*,p->npath);
00846 memcpy(dkd->pairs[dkd->k].stpath,p->stpath,sizeof(EGdGraphEdge_t*)*p->npath);
00847
00848 dkd->k++;
00849
00850 return 0;
00851
00852 }
00853
00854 EGdkdomino_t *EGddominoToDKdom(EGddomino_t *ddom,
00855 int h,
00856 int max_nh,
00857 EGgreedyData_t *gdata,
00858 EGmemPool_t *mem,
00859 unsigned char *const pndummy,
00860 unsigned char *const pedummy)
00861 {
00862 unsigned int i;
00863 EGdkdomino_t *dkdom;
00864
00865 dkdom = EGmemPoolSMalloc(mem, EGdkdomino_t, 1);
00866
00867 dkdom->k = 1;
00868 dkdom->max_k = max_nh;
00869
00870 dkdom->handleid = EGmemPoolSMalloc(mem,unsigned int,max_nh);
00871 dkdom->handleid[0] = h;
00872
00873
00874 dkdom->pairs = EGmemPoolSMalloc(mem,EGinternalPairs_t,max_nh);
00875 dkdom->pairs[0].s = ddom->s;
00876 dkdom->pairs[0].t = ddom->t;
00877 dkdom->pairs[0].value = 0;
00878
00879
00880 dkdom->pairs[0].npath = ddom->npath[1];
00881 dkdom->pairs[0].stpath = EGmemPoolSMalloc(mem, EGdGraphEdge_t*, ddom->npath[1]);
00882 for(i=0; i < ddom->npath[1]; i++)
00883 dkdom->pairs[0].stpath[i] = ddom->path[1][i];
00884
00885
00886 dkdom->cut = EGnewDualCut(mem, ddom->npath[0]+ddom->npath[2]);
00887 for(i=0; i < ddom->npath[0]; i++)
00888 dkdom->cut->edges[i] = ddom->path[0][i];
00889 for(i=0; i < ddom->npath[2]; i++)
00890 dkdom->cut->edges[i+ddom->npath[0]] = ddom->path[2][i];
00891
00892
00893 int rval = EGgetOrientation(gdata,
00894 dkdom->cut,
00895 dkdom->pairs[0].npath,
00896 dkdom->pairs[0].stpath,
00897 &(dkdom->orientation),
00898 pndummy,
00899 pedummy);
00900 if (rval)
00901 {
00902 EGfreeDKdomino(dkdom, mem);
00903 dkdom = 0;
00904 }
00905
00906 return dkdom;
00907 }
00908
00909 EGdualCut_t* EGextractHandleCut(EGdkpc_t *dkpc, unsigned int h)
00910 {
00911
00912 unsigned int i,j;
00913 EGlist_t *hcut;
00914 EGlistNode_t *it;
00915 EGdkdomino_t *dkd;
00916 EGinternalPairs_t *p;
00917 EGdualCut_t *dc;
00918
00919 hcut = EGnewList(dkpc->dkdom->mempool);
00920
00921 for(it = dkpc->FH[h]->begin; it; it=it->next)
00922 EGlistPushBack(hcut, it->this);
00923
00924 for(it = dkpc->dkdom->begin; it; it=it->next)
00925 {
00926 dkd = (EGdkdomino_t*)(it->this);
00927 for(i=0; i < dkd->k; i++)
00928 if ( dkd->handleid[i] == h )
00929 {
00930 p = &(dkd->pairs[i]);
00931 for(j=0; j<p->npath; j++)
00932 EGlistPushBack(hcut, p->stpath[j]);
00933 }
00934 }
00935
00936 dc = EGnewDualCut(dkpc->dkdom->mempool, hcut->size);
00937 for(i=0, it = hcut->begin; it; it=it->next, i++)
00938 dc->edges[i] = (EGdGraphEdge_t*)(it->this);
00939 dc->value = EGdijkstraToCost(0.0);
00940
00941 EGfreeList(hcut);
00942
00943 return dc;
00944
00945 }
00946
00947 void EGdisplayDualCut(FILE *fout, EGdualCut_t* dc)
00948 {
00949
00950 unsigned int i;
00951 size_t mos[EG_MENGER_NUMOS];
00952
00953 mos[EG_MENGER_ECOST] = offsetof (EGmengerEdgeData_t, cost);
00954 mos[EG_MENGER_EDATA] = offsetof (EGmengerEdgeData_t, data);
00955
00956 fprintf(fout, "cut: (%d) ", dc->sz);
00957
00958 for(i=0; i < dc->sz; i++)
00959 fprintf(fout, "(%d,%d)[%4.3lf] ", dc->edges[i]->head->id,
00960 dc->edges[i]->tail->id,
00961 EGdijkstraCostToLf(EGmengerGetEdgeCost(dc->edges[i],mos)));
00962 fprintf(fout, "\n");
00963
00964 return;
00965
00966 }
00967
00968 void EGdisplayInternalPair(FILE *fout, EGinternalPairs_t *p)
00969 {
00970
00971 unsigned int i;
00972 size_t mos[EG_MENGER_NUMOS];
00973
00974 mos[EG_MENGER_ECOST] = offsetof (EGmengerEdgeData_t, cost);
00975 mos[EG_MENGER_EDATA] = offsetof (EGmengerEdgeData_t, data);
00976
00977 fprintf(fout, "(s=%d,t=%d) [sz=%d] ", p->s->id, p->t->id, p->npath);
00978
00979 for(i=0; i < p->npath; i++)
00980 fprintf(fout, "(%d %d)[%lf] ",
00981 p->stpath[i]->tail->id, p->stpath[i]->head->id,
00982 EGdijkstraCostToLf(EGmengerGetEdgeCost(p->stpath[i],mos)));
00983
00984 fprintf(fout, "\n");
00985
00986 return;
00987
00988 }
00989
00990 void EGdisplayDKdomino(FILE *fout, EGdkdomino_t *dkdom)
00991 {
00992
00993 unsigned int i;
00994 EGdijkstraCost_t weight;
00995
00996 fprintf(fout, "k=%d max_k = %d [orientation=%d]\n\n",
00997 dkdom->k, dkdom->max_k, dkdom->orientation);
00998
00999 fprintf(fout, "delta(T) = ");
01000 EGdisplayDualCut(fout, dkdom->cut);
01001 fprintf(fout, "\n");
01002
01003 for(i=0; i<dkdom->k; i++)
01004 {
01005 fprintf(fout, "path of handle %d: ", dkdom->handleid[i]);
01006 EGdisplayInternalPair(fout, &(dkdom->pairs[i]));
01007 fprintf(fout, "\n");
01008 }
01009
01010 weight = EGweightDKdomino(dkdom);
01011 fprintf(stderr, "*weight = %lf\n\n", EGdijkstraCostToLf(weight));
01012
01013 return;
01014
01015 }
01016
01017
01018 void EGdisplayDKPC(FILE *fout, EGdkpc_t *dkpc)
01019 {
01020
01021 unsigned int i,j;
01022 EGlistNode_t *it;
01023 EGdkdomino_t *dkd;
01024 EGdGraphEdge_t *e;
01025
01026 fprintf(fout, "----------- DKPC ----------- \n\n");
01027 fprintf(fout, "DKPC slack = %lf\n", EGdijkstraCostToLf(dkpc->slack));
01028 fprintf(fout, "nhandles = %d\n\n", dkpc->nhandles);
01029
01030 for(i=0; i < dkpc->nhandles; i++)
01031 {
01032 fprintf(fout, "FH[%1u] (%3u elements): ", i, dkpc->FH[i]->size );
01033 for(it=dkpc->FH[i]->begin; it; it=it->next)
01034 {
01035 e = (EGdGraphEdge_t*)(it->this);
01036 fprintf(fout, "(%d,%d)", e->tail->id, e->head->id);
01037 }
01038 fprintf(fout, "\n");
01039 }
01040
01041 fprintf(fout, "\n");
01042 fprintf(fout, "--- TEETH ---\n\n");
01043
01044 for(it = dkpc->dkdom->begin; it; it=it->next)
01045 {
01046 dkd = (EGdkdomino_t *)(it->this);
01047 EGdisplayDKdomino(fout, dkd);
01048 }
01049
01050 fprintf(fout, "--- HANDLES ---\n\n");
01051
01052 EGdualCut_t *dc;
01053
01054 for(i=0; i < dkpc->nhandles; i++)
01055 {
01056 dc = EGextractHandleCut(dkpc, i);
01057 fprintf(fout, "delta(H_%d): ", i);
01058 for(j=0; j < dc->sz; j++)
01059 {
01060 e = dc->edges[j];
01061 fprintf(fout, "(%d,%d)", e->tail->id, e->head->id);
01062 }
01063 fprintf(fout, "\n\n");
01064 EGfreeDualCut(dc, dkpc->dkdom->mempool);
01065 }
01066
01067
01068 return;
01069
01070 }
01071
01072 int EGprimalizeDKPC( EGdkpc_t *dkpc,
01073 EGgreedyData_t *gdata,
01074 EGpkpc_t *pkpc,
01075 unsigned char *const pndummy,
01076 unsigned char *const pedummy)
01077 {
01078
01079 int rval;
01080 double internal_slack,
01081 external_slack,
01082 orig_slack,
01083 planar_slack;
01084 EGdijkstraCost_t dij_external_slack;
01085 pkpc->randa = pkpc->randb = 0;
01086
01087 rval = EGprimalizeDKPCB( dkpc,
01088 gdata,
01089 &pkpc->nhandles,
01090 &pkpc->handle_size,
01091 &pkpc->handles,
01092 &pkpc->nteeth,
01093 &pkpc->teeth_size,
01094 &pkpc->teeth,
01095 &pkpc->teeth_k,
01096 &pkpc->teeth_handle,
01097 &pkpc->teeth_nhalf,
01098 &pkpc->teeth_halves,
01099 pndummy,
01100 pedummy);
01101 if (rval == EG_KP_NOST)
01102 return rval;
01103 CHECKRVAL(rval);
01104
01105 internal_slack = (double)EGdijkstraCostToLf(dkpc->slack);
01106 dij_external_slack = EGcomputeDKPCslack(dkpc);
01107 external_slack = (double)EGdijkstraCostToLf(dij_external_slack);
01108
01109 orig_slack = EGcomputePKPCslack(gdata,
01110 pkpc,
01111 gdata->norig_nodes,
01112 gdata->norig_edges,
01113 gdata->orig_edges,
01114 gdata->orig_weight);
01115
01116 planar_slack = EGcomputePKPCslack(gdata,
01117 pkpc,
01118 gdata->norig_nodes,
01119 gdata->nplanar_edges,
01120 gdata->planar_edges,
01121 gdata->planar_weight);
01122
01123 pkpc->slack = orig_slack;
01124
01125
01126 #if 0
01127 WARNING( (fabs(internal_slack - external_slack) > EG_PRIMALIZATION_ERROR) ,
01128 "internal slack (%lf) and external slack (%lf) are inconsistent",
01129 internal_slack, external_slack);
01130 WARNING( (fabs(internal_slack - planar_slack) > EG_PRIMALIZATION_ERROR),
01131 "dual slack (%lf) and primal slack (%lf) are inconsistent",
01132 internal_slack, planar_slack);
01133 #endif
01134 #warning A check could be added here to doubly ensure that the primal-dual conversion is correct.
01135
01136 return 0;
01137
01138 }
01139
01140 int EGprimalizeDKPCB( EGdkpc_t *dkpc,
01141 EGgreedyData_t *gdata,
01142 int *nhandles,
01143 int **handle_size,
01144 int ***handles,
01145 int *nteeth,
01146 int **teeth_size,
01147 int ***teeth,
01148 int **teeth_k,
01149 int ***teeth_handle,
01150 int ***teeth_nhalf,
01151 int ****teeth_halves,
01152 unsigned char *const pndummy,
01153 unsigned char *const pedummy)
01154 {
01155
01156 int rval;
01157 unsigned int i,j;
01158 EGdualCut_t *dc;
01159 EGlistNode_t *it;
01160 EGdkdomino_t *dkd;
01161 int kill_this_pkpc = 0;
01162
01163
01164 *nhandles = dkpc->nhandles;
01165
01166 *handle_size = EGsMalloc(int,dkpc->nhandles);
01167 *handles = EGsMalloc(int*,dkpc->nhandles);
01168
01169 for(i=0; i<dkpc->nhandles; i++)
01170 {
01171 dc = EGextractHandleCut(dkpc, i);
01172 rval = EGgetCutNodes(gdata,
01173 dc,
01174 0,
01175 &((*handle_size)[i]),
01176 &((*handles)[i]),
01177 pndummy,
01178 pedummy);
01179 CHECKRVAL(rval);
01180 EGfreeDualCut(dc, dkpc->dkdom->mempool);
01181 #warning Handles are not complemented before being added.
01182 }
01183
01184
01185 *nteeth = (int)(dkpc->dkdom->size);
01186
01187 *teeth_size = EGsMalloc(int,*nteeth);
01188 *teeth = EGsMalloc(int*,*nteeth);
01189 *teeth_k = EGsMalloc(int,*nteeth);
01190 *teeth_handle = EGsMalloc(int*,*nteeth);
01191 *teeth_nhalf = EGsMalloc(int*,*nteeth);
01192 *teeth_halves = EGsMalloc(int**,*nteeth);
01193
01194
01195 for(i=0, it=dkpc->dkdom->begin; it; it=it->next, i++)
01196 {
01197 dkd = (EGdkdomino_t*)(it->this);
01198
01199 EGcomputeDualCutValue(dkd->cut);
01200
01201 rval = EGgetCutNodes(gdata,
01202 dkd->cut,
01203 dkd->orientation,
01204 &((*teeth_size)[i]),
01205 &((*teeth)[i]),
01206 pndummy,
01207 pedummy);
01208 CHECKRVAL(rval);
01209
01210 (*teeth_k)[i] = dkd->k;
01211
01212 (*teeth_handle)[i] = EGsMalloc(int,dkd->k);
01213 (*teeth_nhalf)[i] = EGsMalloc(int,dkd->k);
01214 (*teeth_halves)[i] = EGsMalloc(int*,dkd->k);
01215
01216 for(j=0; j<dkd->k;j++)
01217 {
01218 (*teeth_handle)[i][j] = (int)dkd->handleid[j];
01219 rval = EGgetANodes( gdata,
01220 dkd,
01221 j,
01222 &((*teeth_nhalf)[i][j]),
01223 &((*teeth_halves)[i][j]),
01224 pndummy,
01225 pedummy,
01226 gdata->pedges);
01227 if (rval == EG_KP_NOST)
01228 kill_this_pkpc = 1;
01229 else
01230 CHECKRVAL(rval);
01231 }
01232 }
01233
01234 if (kill_this_pkpc)
01235 return EG_KP_NOST;
01236
01237 return 0;
01238
01239 }
01240
01241 void EGfreePKPC( void *v )
01242 {
01243
01244 EGpkpc_t *pkpc = (EGpkpc_t*)(v);
01245
01246 EGfreePKPCB( pkpc->nhandles,
01247 pkpc->handle_size,
01248 pkpc->handles,
01249 pkpc->nteeth,
01250 pkpc->teeth_size,
01251 pkpc->teeth,
01252 pkpc->teeth_k,
01253 pkpc->teeth_handle,
01254 pkpc->teeth_nhalf,
01255 pkpc->teeth_halves );
01256
01257 free(pkpc);
01258
01259 return;
01260
01261 }
01262
01263 int EGfreePKPCB( int nhandles,
01264 int *handle_size,
01265 int **handles,
01266 int nteeth,
01267 int *teeth_size,
01268 int **teeth,
01269 int *teeth_k,
01270 int **teeth_handle,
01271 int **teeth_nhalf,
01272 int ***teeth_halves )
01273 {
01274
01275 int i,j;
01276
01277 for(i=0; i < nhandles; i++)
01278 free(handles[i]);
01279
01280 free(handles);
01281 free(handle_size);
01282
01283 for(i=0; i < nteeth; i++)
01284 {
01285 free(teeth[i]);
01286 free(teeth_handle[i]);
01287 free(teeth_nhalf[i]);
01288 for(j=0; j < teeth_k[i]; j++)
01289 free(teeth_halves[i][j]);
01290 free(teeth_halves[i]);
01291 }
01292
01293 free(teeth_k);
01294 free(teeth_size);
01295
01296 free(teeth);
01297 free(teeth_handle);
01298 free(teeth_nhalf);
01299 free(teeth_halves);
01300
01301 return 0;
01302
01303 }
01304
01305 int EGnewPKPCset(int nineq,
01306 int **nhandles,
01307 int ***handle_size,
01308 int ****handles,
01309 int **nteeth,
01310 int ***teeth_size,
01311 int ****teeth,
01312 int ***teeth_k,
01313 int ****teeth_handle,
01314 int ****teeth_nhalf,
01315 int *****teeth_halves)
01316 {
01317
01318
01319
01320 *nhandles = EGsMalloc(int,nineq);
01321 *handle_size = EGsMalloc(int*,nineq);
01322 *handles = EGsMalloc(int**,nineq);
01323 *nteeth = EGsMalloc(int,nineq);
01324 *teeth_size = EGsMalloc(int*,nineq);
01325 *teeth = EGsMalloc(int**,nineq);
01326 *teeth_k = EGsMalloc(int*,nineq);
01327 *teeth_handle = EGsMalloc(int**,nineq);
01328 *teeth_nhalf = EGsMalloc(int**,nineq);
01329 *teeth_halves = EGsMalloc(int***,nineq);
01330
01331 return 0;
01332
01333 }
01334
01335 void EGcomputeDualCutValue( EGdualCut_t *dc )
01336 {
01337
01338 unsigned int i;
01339 size_t mos[EG_MENGER_NUMOS];
01340
01341 mos[EG_MENGER_ECOST] = offsetof (EGmengerEdgeData_t, cost);
01342 mos[EG_MENGER_EDATA] = offsetof (EGmengerEdgeData_t, data);
01343
01344 dc->value = EGdijkstraToCost(0.0);
01345 for(i=0; i < dc->sz; i++)
01346 dc->value = EGdijkstraCostAdd(dc->value,EGmengerGetEdgeCost(dc->edges[i],mos));
01347
01348 return;
01349
01350 }
01351
01352
01353 double EGcomputePrimalCutValue(EGgreedyData_t*data,
01354 EGpkpc_t*pkpc,
01355 int set_size,
01356 int *set_nodes,
01357 int nnodes,
01358 int nedges,
01359 int *edges,
01360 double *weight,
01361 unsigned char *dummy)
01362 {
01363 int i;
01364 double val = 0.0;
01365 memset(dummy, 0, sizeof(unsigned char)*nnodes);
01366 for(i=0; i < set_size; i++)
01367 {
01368 dummy[set_nodes[i]] = 1;
01369 }
01370 for(i=0; i < nedges; i++)
01371 if ( (dummy[edges[2*i]] + dummy[edges[2*i+1]]) == 1 )
01372 {
01373 val += weight[i];
01374 pkpc->randa += data->randa[i];
01375 pkpc->randb += data->randb[i];
01376 }
01377 return val;
01378 }
01379
01380
01381
01382 double EGcomputeInterfaceValue(int T_size,
01383 int *T_nodes,
01384 int A_size,
01385 int *A_nodes,
01386 int nnodes,
01387 int nedges,
01388 int *edges,
01389 double *weight,
01390 unsigned char *dummy)
01391 {
01392 int i;
01393 double val = 0.0;
01394
01395 memset(dummy, 0, sizeof(unsigned char)*nnodes);
01396
01397 for(i=0; i < T_size; i++)
01398 dummy[T_nodes[i]] = 1;
01399
01400 for(i=0; i < A_size; i++)
01401 if ( dummy[A_nodes[i]] )
01402 dummy[A_nodes[i]] = 2;
01403 else
01404 {
01405 EXIT(1, "A not a subset of T");
01406 }
01407
01408 for(i=0; i < nedges; i++)
01409 if ( dummy[edges[2*i]] + dummy[edges[2*i+1]] == 3 )
01410 val += weight[i];
01411
01412 return val;
01413 }
01414
01415 int EGincrementInterface( int T_size,
01416 int *T,
01417 int A_size,
01418 int *A,
01419 int nnodes,
01420 int nedges,
01421 int *edges,
01422 unsigned char *ndummy,
01423 unsigned char *emarkers )
01424 {
01425
01426 int i;
01427 memset(ndummy, 0, sizeof(unsigned char)*nnodes);
01428 for(i=0; i < T_size; i++) ndummy[ T[i] ] = 1;
01429 for(i=0; i < A_size; i++) ndummy[ A[i] ] = 2;
01430 for(i=0; i<nedges; i++)
01431 if ( ndummy[edges[2*i]] + ndummy[edges[2*i+1]] == 3 ) emarkers[i] += 1;
01432 return 0;
01433 }
01434
01435 double EGcomputePKPCslack( EGgreedyData_t*data,
01436 EGpkpc_t *pkpc,
01437 int nnodes,
01438 int nedges,
01439 int *edges,
01440 double *weight )
01441 {
01442 return ( EGcomputePKPCBslack( data,
01443 pkpc,
01444 pkpc->nhandles,
01445 pkpc->handle_size,
01446 pkpc->handles,
01447 pkpc->nteeth,
01448 pkpc->teeth_size,
01449 pkpc->teeth,
01450 pkpc->teeth_k,
01451 pkpc->teeth_handle,
01452 pkpc->teeth_nhalf,
01453 pkpc->teeth_halves,
01454 nnodes,
01455 nedges,
01456 edges,
01457 weight ) );
01458 }
01459
01460 double EGcomputePKPCBslack( EGgreedyData_t*data,
01461 EGpkpc_t*pkpc,
01462 int nhandles,
01463 int *handle_size,
01464 int **handles,
01465 int nteeth,
01466 int *teeth_size,
01467 int **teeth,
01468 int *teeth_k,
01469 int **teeth_handle,
01470 int **teeth_nhalf,
01471 int ***teeth_halves,
01472 int nnodes,
01473 int nedges,
01474 int *edges,
01475 double *weight)
01476
01477 {
01478
01479 int i,j,k;
01480 unsigned char *ndummy = data->pndummy, *edummy = data->pedummy;
01481 double slack = 0;
01482
01483
01484
01485
01486 for(i=0; i<nteeth; i++)
01487 slack += EGcomputePrimalCutValue(data,
01488 pkpc,
01489 teeth_size[i],
01490 teeth[i],
01491 nnodes,
01492 nedges,
01493 edges,
01494 weight,
01495 ndummy);
01496
01497
01498 for(i=0; i < nhandles; i++)
01499 {
01500
01501 memset(edummy, 0, sizeof(unsigned char)*nedges);
01502 for(j=0; j<nteeth;j++)
01503 for(k=0; k<teeth_k[j]; k++)
01504 if ( teeth_handle[j][k] == i )
01505 EGincrementInterface( teeth_size[j],
01506 teeth[j],
01507 teeth_nhalf[j][k],
01508 teeth_halves[j][k],
01509 nnodes,
01510 nedges,
01511 edges,
01512 ndummy,
01513 edummy);
01514
01515
01516 memset(ndummy, 0, sizeof(unsigned char)*nnodes);
01517 for(j=0; j<handle_size[i]; j++)
01518 ndummy[ handles[i][j] ] = 1;
01519
01520
01521 for(j=0; j<nedges; j++)
01522 {
01523
01524 if ( !(edummy[j]&1) && ( ndummy[edges[2*j]] + ndummy[edges[2*j+1]] == 1 ) )
01525 {
01526 slack += (edummy[j]+1)*weight[j];
01527 pkpc->randa += (edummy[j]+1)*data->randa[j];
01528 pkpc->randb += (edummy[j]+1)*data->randb[j];
01529 }
01530
01531
01532 if ( (edummy[j]&1) && ( ndummy[edges[2*j]] + ndummy[edges[2*j+1]] == 1 ) )
01533 {
01534 slack += (edummy[j])*weight[j];
01535 pkpc->randa += (edummy[j])*data->randa[j];
01536 pkpc->randb += (edummy[j])*data->randb[j];
01537 }
01538
01539
01540 if ( !(edummy[j]&1) && ( ndummy[edges[2*j]] + ndummy[edges[2*j+1]] != 1 ) )
01541 {
01542 slack += (edummy[j])*weight[j];
01543 pkpc->randa += (edummy[j])*data->randa[j];
01544 pkpc->randb += (edummy[j])*data->randb[j];
01545 }
01546
01547
01548 if ( (edummy[j]&1) && ( ndummy[edges[2*j]] + ndummy[edges[2*j+1]] != 1 ) )
01549 {
01550 slack += (edummy[j]+1)*weight[j];
01551 pkpc->randa += (edummy[j]+1)*data->randa[j];
01552 pkpc->randb += (edummy[j]+1)*data->randb[j];
01553 }
01554 }
01555
01556 }
01557
01558
01559 slack -= (double)nhandles;
01560
01561
01562 for(i=0; i < nteeth; i++)
01563 slack -= (double)teeth_k[i];
01564
01565
01566 slack -= (double)(2*nteeth);
01567
01568 return slack;
01569 }
01570
01571 int EGkpTo2pTooth( int kp_size,
01572 int* kp_nodes,
01573 int kp_k,
01574 int* kp_handles,
01575 int* kp_nhalf,
01576 int** kp_halves,
01577 int *tp_naset,
01578 int *tp_nbset,
01579 int *tp_nmset,
01580 int **tp_aset,
01581 int **tp_bset,
01582 int **tp_mset,
01583 int nnodes,
01584 unsigned char *vdummy )
01585 {
01586
01587 int k, i, m[2];
01588
01589 TEST( kp_k > 2 || kp_k < 1, "can only convert k-dominoes with 1 <= k <= 2");
01590
01591 memset( vdummy, 0, sizeof(unsigned char)*nnodes );
01592
01593
01594
01595
01596
01597
01598 for(i=0; i< kp_size; i++)
01599 vdummy[ kp_nodes[i] ] |= 1;
01600
01601
01602
01603
01604
01605 m[0] = 2*(kp_handles[0]+1);
01606 m[1] = 2*(2 - kp_handles[0]);
01607
01608
01609 for(k=0; k < kp_k; k++)
01610 for(i=0; i< kp_nhalf[k]; i++)
01611 vdummy[ kp_halves[k][i] ] |= m[k];
01612
01613
01614 *tp_naset = 0;
01615 *tp_nbset = 0;
01616 *tp_nmset = 0;
01617 for(i=0; i<nnodes; i++)
01618 {
01619 if (vdummy[i])
01620 (*tp_nmset) += 1;
01621 if (vdummy[i] & 2)
01622 (*tp_naset) += 1;
01623 if (vdummy[i] & 4)
01624 (*tp_nbset) += 1;
01625 }
01626
01627
01628 if (*tp_naset)
01629 (*tp_aset) = EGsMalloc(int,*tp_naset);
01630 if (*tp_nbset)
01631 (*tp_bset) = EGsMalloc(int,*tp_nbset);
01632 if (*tp_nmset)
01633 (*tp_mset) = EGsMalloc(int,*tp_nmset);
01634
01635
01636 *tp_naset = 0;
01637 *tp_nbset = 0;
01638 *tp_nmset = 0;
01639 for(i=0; i<nnodes; i++)
01640 {
01641 if (vdummy[i])
01642 (*tp_mset)[(*tp_nmset)++] = i;
01643 if (vdummy[i] & 2)
01644 (*tp_aset)[(*tp_naset)++] = i;
01645 if (vdummy[i] & 4)
01646 (*tp_bset)[(*tp_nbset)++] = i;
01647 }
01648
01649 return 0;
01650
01651 }
01652
01653
01654
01655
01656 int EGremoveHandles(EGdkpc_t *dkpc, EGmemPool_t *mem)
01657 {
01658
01659 unsigned int i;
01660 EGdkdomino_t *dkd;
01661 EGlistNode_t *it;
01662
01663
01664 if (!dkpc->nhandles)
01665 return 0;
01666
01667 for(i=0; i<dkpc->nhandles; i++)
01668 EGlistClear(dkpc->FH[i], nullFree);
01669
01670 dkpc->nhandles = 0;
01671
01672
01673 for(it=dkpc->dkdom->begin; it; it=it->next)
01674 {
01675 dkd = (EGdkdomino_t*)(it->this);
01676 for(i=0; i<dkd->max_k; i++)
01677 {
01678 dkd->pairs[i].npath = 0;
01679 dkd->pairs[i].stpath = 0;
01680 }
01681 }
01682
01683
01684 while(dkpc->dkdom->size > 1)
01685 EGlistEraseMP(dkpc->dkdom, dkpc->dkdom->end, EGfreeDKdomino, mem);
01686
01687
01688 dkd = (EGdkdomino_t*)(dkpc->dkdom->begin->this);
01689 dkd->k = 0;
01690
01691
01692
01693
01694
01695
01696 dkpc->slack = EGcomputeDKPCslack(dkpc);
01697
01698 return 0;
01699
01700 }
01701
01702 EGdualCut_t* EGcopyDualCut(EGmemPool_t *mem, EGdualCut_t *dc_in)
01703 {
01704
01705 unsigned int i;
01706 EGdualCut_t *dc_out;
01707
01708 dc_out = EGnewDualCut(mem, dc_in->sz);
01709
01710 for(i=0; i<dc_in->sz; i++)
01711 dc_out->edges[i] = dc_in->edges[i];
01712
01713 dc_out->value = dc_in->value;
01714
01715 return dc_out;
01716
01717 }
01718
01719 int KPseparateFromDualCut( EGdualCut_t *dcut,
01720 unsigned int orientation,
01721 EGgreedyData_t *gdata,
01722 int *nadded,
01723 double *best_val,
01724 double sample_time )
01725 {
01726
01727 int rval;
01728 int i;
01729 EGmemPool_t *mem = gdata->bdG->mem;
01730 int add_cut_to_heap = 1;
01731 double slack;
01732
01733 EGdkdomino_t *zdom;
01734 EGdkpc_t *dkpc;
01735 EGpkpc_t *pkpc, *hpkpc;
01736 EGlist_t *pairs_list;
01737 EGinternalPairs_t *p, *q;
01738 EGlistNode_t *it, *jt;
01739
01740
01741
01742 for( i = 0 ; i < 7 ; i++)
01743 if(EGdijkstraCostIsLess(dcut->value,EGdijkstraToCost(i+1.000001)))
01744 {
01745 gdata->delta_distr[i]++;
01746 break;
01747 }
01748
01749 pairs_list = EGnewList(mem);
01750
01751 (*nadded) = 0;
01752 (*best_val) = EGdijkstraToCost(1.0);
01753
01754
01755
01756 zdom = EGdcutToDKdom( EG_KPC_MAX_HANDLES,
01757 dcut,
01758 orientation,
01759 mem);
01760
01761 rval = EGgenerateInternalPairs( gdata,
01762 zdom,
01763 zdom->orientation,
01764 pairs_list,
01765 (unsigned int)gdata->max_handles*15,
01766 gdata->percentage,
01767 gdata->pndummy,
01768 gdata->pedummy,
01769 gdata->bdnodes);
01770 CHECKRVAL(rval);
01771
01772 EGfreeDKdomino(zdom, mem);
01773 zdom = 0;
01774
01775 if (sample_time > 0.1)
01776 {
01777
01778 EGlist_t *new_pairs;
01779
01780 new_pairs = EGnewList(gdata->bdG->mem);
01781 rval = EGgenerateRandomInternalPairs( gdata,
01782 new_pairs,
01783 pairs_list,
01784 (unsigned int)gdata->max_handles*35,
01785 sample_time );
01786 CHECKRVAL(rval);
01787
01788 pairs_list = EGmergeIPlists(pairs_list, new_pairs);
01789
01790 }
01791
01792
01793
01794 for(it=pairs_list->begin; it; it=it->next)
01795 for(jt=it->next; jt; jt=jt->next)
01796 {
01797
01798 p = (EGinternalPairs_t*)(it->this);
01799 q = (EGinternalPairs_t*)(jt->this);
01800
01801 if (p->s == q->s && p->t == q->t)
01802 continue;
01803
01804 zdom = EGdcutToDKdom( EG_KPC_MAX_HANDLES,
01805 dcut,
01806 orientation,
01807 mem);
01808
01809 dkpc = EGdkdomToDKPC(zdom, mem);
01810
01811 slack = EGdijkstraCostToLf(dkpc->slack);
01812
01813
01814 rval = EGgrowHandle(dkpc,
01815 zdom,
01816 p,
01817 gdata,
01818 mem,
01819 gdata->pndummy,
01820 gdata->pedummy);
01821 CHECKRVAL(rval);
01822
01823 rval = EGgrowHandle(dkpc,
01824 zdom,
01825 q,
01826 gdata,
01827 mem,
01828 gdata->pndummy,
01829 gdata->pedummy);
01830 CHECKRVAL(rval);
01831
01832
01833
01834 if (EGdijkstraCostToLf(dkpc->slack) > -0.01)
01835 {
01836 EGfreeDKPC(dkpc, mem);
01837 dkpc = 0;
01838 if (jt == pairs_list->begin->next)
01839 it = pairs_list->end;
01840 break;
01841 }
01842
01843
01844 pkpc = EGsMalloc(EGpkpc_t,1);
01845
01846 add_cut_to_heap = 1;
01847
01848 rval = EGprimalizeDKPC( dkpc,
01849 gdata,
01850 pkpc,
01851 gdata->pndummy,
01852 gdata->pedummy);
01853 if (rval == EG_KP_NOST)
01854 {
01855 rval = 0;
01856 add_cut_to_heap = 0;
01857 }
01858 else if (rval)
01859 {
01860 fprintf(stdout, "WARNING! graphs are inconsistent. Saving to 'inconsistent_graph.b.x'\n");
01861 saveBgraph ("inconsistent_graph.b.x", gdata->norig_nodes,
01862 gdata->norig_edges,
01863 gdata->orig_edges,
01864 gdata->orig_weight);
01865 }
01866 CHECKRVAL(rval);
01867
01868
01869 if (pkpc->slack > 0.0001)
01870 add_cut_to_heap = 0;
01871
01872
01873 for(i=0; i<pkpc->nhandles; i++)
01874 if ( !pkpc->handle_size[i] || (pkpc->handle_size[i] == gdata->norig_nodes) )
01875 {
01876 #warning Erasing constraints with empty handles.
01877
01878 add_cut_to_heap = 0;
01879 break;
01880 }
01881
01882
01883
01884 if (gdata->cut_heap->size == gdata->cut_heap->max_size)
01885 {
01886 const EGheapCost_t mv = EGheapGetMinVal(gdata->cut_heap);
01887 const double mv_lf = (double)EGheapCostToLf(mv);
01888 if ( !(fabs(pkpc->slack) > mv_lf) )
01889 add_cut_to_heap = 0;
01890 }
01891
01892
01893 if (add_cut_to_heap)
01894 for(i=0; i < (int)gdata->cut_heap->size; i++)
01895 {
01896 hpkpc = (EGpkpc_t*)(gdata->cut_heap->heap[i]->this);
01897 if (hpkpc->randa == pkpc->randa)
01898 if (hpkpc->randb == pkpc->randb)
01899 if (hpkpc->nhandles == pkpc->nhandles)
01900 if (hpkpc->nteeth == pkpc->nteeth)
01901 add_cut_to_heap = 0;
01902 }
01903
01904 if (add_cut_to_heap)
01905 {
01906
01907 if (gdata->cut_heap->size == gdata->cut_heap->max_size)
01908 {
01909 hpkpc = (EGpkpc_t*)(EGheapGetMin(gdata->cut_heap)->this);
01910 EGfreePKPC(hpkpc);
01911 EGheapDeleteMin(gdata->cut_heap, mem);
01912 }
01913
01914
01915 EGheapInsert( gdata->cut_heap,
01916 pkpc,
01917 EGheapToCost( fabs(pkpc->slack) ),
01918 mem );
01919 if ( !(*nadded) )
01920 (*best_val) = pkpc->slack;
01921 (*nadded) += 1;
01922 }
01923
01924
01925
01926 if (pkpc->slack < -0.01)
01927 gdata->nviolated += 1;
01928 if (pkpc->slack < gdata->min_violated)
01929 gdata->min_violated = pkpc->slack;
01930 if (pkpc->slack > gdata->max_violated)
01931 gdata->max_violated = pkpc->slack;
01932
01933 #if DISPLAY_MODE
01934 if (add_cut_to_heap)
01935 EGdisplayStatus(stdout, gdata);
01936 #endif
01937
01938
01939 EGfreeDKPC(dkpc, mem);
01940 dkpc = 0;
01941
01942
01943 if (!add_cut_to_heap && pkpc)
01944 EGfreePKPC(pkpc);
01945 pkpc = 0;
01946
01947 }
01948
01949
01950 EGlistClearMP(pairs_list,EGfreeInternalPairs,mem);
01951 EGfreeList(pairs_list);
01952
01953 return 0;
01954
01955 }
01956
01957 void EGdisplayStatus(FILE *fout, EGgreedyData_t *gdata)
01958 {
01959
01960 double hmax;
01961 EGheapCost_t hhmax;
01962
01963 if (gdata->cut_heap->size)
01964 {
01965 hhmax = EGheapGetMinVal(gdata->cut_heap);
01966 hmax = EGheapCostToLf(hhmax);
01967 }
01968 else
01969 hmax = 0.0;
01970
01971
01972 if(!(gdata->nviolated&0xf))
01973 fprintf(fout, "\rnviolated = %4u min = %10lf max = %10lf hsz = %3u hmax = %10lf",
01974 gdata->nviolated, gdata->min_violated, gdata->max_violated,
01975 gdata->cut_heap->size, -1*hmax);
01976
01977 return;
01978
01979 }
01980
01981
01982 int KPprocess_cut(int*cutset,
01983 int cutsize,
01984 double cutweight,
01985 void*process_indo,
01986 setlist**sets)
01987 {
01988 int rval = 0, nadded = 0;
01989 EGgreedyData_t*const data = (EGgreedyData_t*) process_indo;
01990 EGdualCut_t*dualcut = 0;
01991 double minslack;
01992 EGmemPool_t *mem = data->bdG->mem;
01993
01994
01995 sets = 0;
01996 cutweight = 0;
01997
01998
01999 rval = EGgetDualCut(data, &dualcut, cutsize, cutset, data->pndummy,
02000 data->pedummy, data->pedges);
02001 CHECKRVALG(rval,CLEANUP);
02002
02003
02004 rval = KPseparateFromDualCut(dualcut, 0, data, &nadded, &minslack, 0.0);
02005 CHECKRVALG(rval,CLEANUP);
02006
02007 if (nadded)
02008 {
02009 EGdualCut_t *dc_copy = EGcopyDualCut(mem, dualcut);
02010 EGaddDualCutToHeap(data->dc_heap,
02011 dc_copy,
02012 0,
02013 minslack,
02014 mem);
02015 }
02016
02017
02018 rval = KPseparateFromDualCut(dualcut, 1, data, &nadded, &minslack, 0.0);
02019 CHECKRVALG(rval,CLEANUP);
02020
02021 if (nadded)
02022 {
02023 EGdualCut_t *dc_copy = EGcopyDualCut(mem, dualcut);
02024 EGaddDualCutToHeap(data->dc_heap,
02025 dc_copy,
02026 1,
02027 minslack,
02028 mem);
02029 }
02030
02031 EGfreeDualCut(dualcut,data->bdG->mem);
02032
02033
02034 CLEANUP:
02035 return rval ? PROCESS_ERROR:PROCESS_INCOMPLETE;
02036 }
02037
02038 int EGaddDualCutToHeap(EGheap_t *h,
02039 EGdualCut_t *dc,
02040 int orientation,
02041 double lfval,
02042 EGmemPool_t *mem)
02043 {
02044
02045 unsigned int i;
02046 EGheapCost_t hval = EGheapToCost(fabs(lfval));
02047 EGdualCut_t *hdc;
02048 EGcutSeed_t *hcs;
02049 int add_dc_to_heap = 0;
02050
02051
02052 qsort (dc->edges, dc->sz, sizeof (EGdGraphEdge_t *), EGedgeCompare);
02053
02054
02055 for(i=0; i<h->size; i++)
02056 {
02057 hcs = (EGcutSeed_t*) h->heap[i]->this;
02058 hdc = hcs->dc;
02059 if ( hcs->orientation == orientation && EGareDualCutsEqual(hdc,dc) )
02060 goto DONE;
02061 }
02062
02063
02064 if ( h->size != h->max_size )
02065 add_dc_to_heap = 1;
02066
02067 else if (EGheapCostIsLess(EGheapGetMinVal(h),hval))
02068 {
02069
02070 hcs = (EGcutSeed_t*)EGheapGetMinThis(h);
02071 EGfreeDualCut(hcs->dc,mem);
02072 EGmemPoolSFree(hcs, EGcutSeed_t, 1, mem);
02073 EGheapDeleteMin(h,mem);
02074 add_dc_to_heap = 1;
02075 }
02076
02077 DONE:
02078
02079
02080 if (add_dc_to_heap)
02081 {
02082 EGcutSeed_t *cs;
02083 cs = EGmemPoolSMalloc(mem, EGcutSeed_t, 1);
02084 cs->dc = dc;
02085 cs->orientation = orientation;
02086 EGheapInsert(h,cs,hval,mem);
02087 }
02088 else
02089 EGfreeDualCut(dc,mem);
02090
02091 return 0;
02092
02093 }
02094
02095 int EGareDualCutsEqual(EGdualCut_t *a, EGdualCut_t *b)
02096 {
02097 unsigned int i, are_equal = 0;
02098
02099 if (a->sz != b->sz)
02100 goto DONE;
02101
02102 for (i = 0; i < a->sz; i++)
02103 if (EGboyerEdgeNumber (a->edges[i]) != EGboyerEdgeNumber (b->edges[i]))
02104 goto DONE;
02105
02106 are_equal = 1;
02107
02108 DONE:
02109
02110 return are_equal;
02111 }