00001 #include "eg_kppairs.h"
00002
00003 #define GETOTHEREND(_cedge) (G->G[gp_GetTwinArc(G,_cedge - G->G)].v)
00004 #define GETROOTEDGE(curroot) (G->G + G->G[curroot].link[1])
00005 #define GETNEXTEDGE(curedge,curroot) ((curedge->link[1] < G->N) ? GETROOTEDGE(curroot) : (G->G + curedge->link[1]))
00006
00007
00008 #define EG_KPPAIRS_VERBOSE 100
00009 #define EG_KPPAIRS_DEBUG 0
00010
00011 static size_t os[EG_MENGER_NUMOS] = {
00012 [EG_MENGER_PI] = offsetof (EGmengerNodeData_t, pi),
00013 [EG_MENGER_DIST] = offsetof (EGmengerNodeData_t, dist),
00014 [EG_MENGER_ORIG_DIST] = offsetof (EGmengerNodeData_t, orig_dist),
00015 [EG_MENGER_NDIST] = offsetof (EGmengerNodeData_t, ndist),
00016 [EG_MENGER_ORIG_NDIST] = offsetof (EGmengerNodeData_t, orig_ndist),
00017 [EG_MENGER_MARK] = offsetof (EGmengerNodeData_t, marker),
00018 [EG_MENGER_ORIG_MARK] = offsetof (EGmengerNodeData_t, orig_marker),
00019 [EG_MENGER_FATHER] = offsetof (EGmengerNodeData_t, father),
00020 [EG_MENGER_ORIG_FATHER] = offsetof (EGmengerNodeData_t, orig_father),
00021 [EG_MENGER_HEAP_CONNECTOR] = offsetof (EGmengerNodeData_t, hc),
00022 [EG_MENGER_ECOST] = offsetof (EGmengerEdgeData_t, cost),
00023 [EG_MENGER_REDUCED_ECOST] = offsetof (EGmengerEdgeData_t, reduced_cost),
00024 [EG_MENGER_IS_IN_SOL] = offsetof (EGmengerEdgeData_t, is_in_solution),
00025 [EG_MENGER_EDATA] = offsetof (EGmengerEdgeData_t, data)
00026 };
00027 static size_t dij_os[6] = {
00028 [EG_DIJ_DIST] = offsetof (EGmengerNodeData_t, orig_dist),
00029 [EG_DIJ_NDIST] = offsetof (EGmengerNodeData_t, orig_ndist),
00030 [EG_DIJ_FATHER] = offsetof (EGmengerNodeData_t, orig_father),
00031 [EG_DIJ_MARKER] = offsetof (EGmengerNodeData_t, orig_marker),
00032 [EG_DIJ_HCONNECTOR] = offsetof (EGmengerNodeData_t, hc),
00033 [EG_DIJ_ELENGTH] = offsetof (EGmengerEdgeData_t, cost)
00034 };
00035
00036 #define KP_CHECK_SUM_IS_LESS(a,b,c) \
00037 WARNINGL(EG_KPPAIRS_DEBUG, EGdijkstraCostIsLess( EGdijkstraCostAdd((a),(b)), EGdijkstraToCost(c)), "Inequality not satisfied %lf < %lf", EGdijkstraCostToLf(EGdijkstraCostAdd((a), (b))), c)
00038
00058 int static EGdoPrimalDfs( const unsigned n_marks,
00059 size_t*const set_sz,
00060 EGlist_t** CUT,
00061 unsigned char*const node_mark,
00062 unsigned char*const edge_mark,
00063 EGgreedyData_t*const data)
00064 {
00065 int rval = 0;
00066 const size_t nedges = data->bdG->edge_id_max/2;
00067 const size_t nnodes = nedges + 2 - data->bdG->node_id_max;
00068 size_t node_id = 0, other_id;
00069 const graphP G = data->G;
00070 register unsigned i;
00071 unsigned char cur_mark = 0, oth_mark;
00072 graphNodeP pedge;
00073 for( i = n_marks ; i-- ; )
00074 {
00075 set_sz[i] = 0;
00076 EGlistClear(CUT[i],0);
00077 }
00078 memset(node_mark,0,sizeof(unsigned char)*nnodes);
00079 node_mark[node_id] = cur_mark+1;
00080 set_sz[cur_mark] += 1;
00081 EGlistPushHead(CUT[cur_mark],(void*)node_id);
00082 do
00083 {
00084 node_id = (size_t)(CUT[cur_mark]->begin->this);
00085 EGlistErase(CUT[cur_mark],CUT[cur_mark]->begin,0);
00086 pedge = GETROOTEDGE(node_id);
00087 do
00088 {
00089 if(edge_mark[pedge->id]&128U) goto NEXT_EDGE;
00090 edge_mark[pedge->id] |= 128U;
00091 other_id = pedge->v;
00092 oth_mark = cur_mark ^ ((edge_mark[pedge->id])&127U);
00093 if(node_mark[other_id])
00094 {
00095 TESTG((rval=(oth_mark+1!=node_mark[other_id])), CLEANUP, "Imposible");
00096 goto NEXT_EDGE;
00097 }
00098 node_mark[other_id] = oth_mark + 1;
00099 set_sz[oth_mark] += 1;
00100 EGlistPushHead(CUT[oth_mark],(void*)other_id);
00101 NEXT_EDGE:
00102 pedge = GETNEXTEDGE(pedge, node_id);
00103 } while(pedge != GETROOTEDGE(node_id));
00104 cur_mark = 0;
00105 while( cur_mark < n_marks && !(CUT[cur_mark]->size)) cur_mark++;
00106 } while( cur_mark < n_marks);
00107 node_id = 0;
00108 #if KPPAIRS_VERBOSE <= DEBUG
00109 fprintf(stderr,"Number of Sets found %u\n",n_marks);
00110 #endif
00111 for( i = n_marks ; i-- ; )
00112 {
00113 node_id += set_sz[i];
00114 #if KPPAIRS_VERBOSE <= DEBUG
00115 fprintf(stderr,"\tset[%u]=%zd\n",i,set_sz[i]);
00116 #endif
00117 }
00118 TESTG((rval=(node_id != nnodes)), CLEANUP, "Imposible, nnodes %zd, marked nodes %zd",nnodes,node_id);
00119 CLEANUP:
00120 return rval;
00121 }
00122
00123
00124
00125 int EGgenerateInternalPairs (EGgreedyData_t*const data,
00126 EGdkdomino_t*const zerodom,
00127 const unsigned int orientation,
00128 EGlist_t*const pairs,
00129 const unsigned max_pairs,
00130 double const percentage,
00131 unsigned char*const node_mark,
00132 unsigned char*const edge_mark,
00133 EGdGraphNode_t**const dc_nodes)
00134 {
00135 unsigned register int i = 0, j = 0, k = 0;
00136 int node_id, other_id;
00137
00138 EGdGraph_t*const bdG = data->bdG;
00139 EGmemPool_t* mem = bdG->mem;
00140 EGlist_t*CUT[2]={EGnewList(mem),EGnewList(mem)};
00141 size_t set_sz[2] = {0,0};
00142 EGinternalPairs_t *worst_pair = 0, *cur_pair = 0;
00143 unsigned char const cur_mark = orientation ? 2U : 1U;
00144 unsigned int tot_pairs = 0;
00145 EGlist_t* unattach_edges = EGnewList(mem);
00146 EGdGraphNode_t *cur_node;
00147 EGdGraphEdge_t *tmp_edge = 0;
00148 EGheap_t* dij_heap = EGnewHeap(mem, 2, bdG->nodes->size);
00149 EGlistNode_t* It1;
00150 const graphP G = data->G;
00151 graphNodeP pedge;
00152 unsigned int cycle_sz = zerodom->cut->sz;
00153 int rval = 0;
00154 EGlist_t *extpath;
00155 MESSAGE(KPPAIRS_VERBOSE,"Entering for cut %p orientation %u",
00156 (void*)zerodom->cut, orientation);
00157
00158 EGdijkstraCost_t dist, path_dist;
00159 EGdijkstraCost_t const slack = EGdijkstraCostMul(EGdijkstraToCost(2.0),
00160 EGdijkstraToCost(percentage));
00161
00162 TESTG((rval=(bdG->node_id_max!=bdG->nodes->size)),CLEANUP,"Imposible!");
00163
00164
00165
00166 memset(dc_nodes,0,sizeof(EGdGraphNode_t*)*bdG->nodes->size);
00167 memset(edge_mark,0,sizeof(unsigned char)*bdG->edge_id_max/2);
00168 for( i = cycle_sz ; i-- ; )
00169 {
00170 WARNINGL(KPPAIRS_VERBOSE, edge_mark[ EGmengerGetEdgeData(
00171 zerodom->cut->edges[i],os)->id], "repeated edge %p in cut",
00172 (void*)zerodom->cut->edges[i]);
00173 edge_mark[EGmengerGetEdgeData(zerodom->cut->edges[i],os)->id] ^= 1U;
00174 dc_nodes[zerodom->cut->edges[i]->head->id] = zerodom->cut->edges[i]->head;
00175 dc_nodes[zerodom->cut->edges[i]->tail->id] = zerodom->cut->edges[i]->tail;
00176 }
00177
00178
00179 rval = EGdoPrimalDfs(2,set_sz,CUT,node_mark,edge_mark,data);
00180 CHECKRVALG(rval,CLEANUP);
00181 TESTG((rval=!set_sz[cur_mark-1]),CLEANUP,"Empty set! imposible!");
00182
00183
00184 for( i = 0, tot_pairs = 0 ; i < bdG->nodes->size ; i++ )
00185 if(dc_nodes[i]) dc_nodes[tot_pairs++] = dc_nodes[i];
00186 TESTG((rval=(cycle_sz < tot_pairs)),CLEANUP,"Imposible!, cycle_sz %u "
00187 "cycle_nodes %u",cycle_sz, tot_pairs);
00188 cycle_sz = tot_pairs;
00189
00190
00191
00192
00193 for( i = cycle_sz ; i-- ; )
00194 {
00195 cur_node = dc_nodes[i];
00196 MESSAGE(KPPAIRS_VERBOSE,"Checking node %u", cur_node->id);
00197 for( It1 = cur_node->out_edges->begin ; It1 ; It1 = It1->next)
00198 {
00199 pedge = EGmengerGetEdgeData(It1->this,os);
00200 node_id = pedge->v;
00201 other_id = GETOTHEREND(pedge);
00202 if(node_mark[node_id] != cur_mark || node_mark[other_id] != cur_mark)
00203 {
00204 MESSAGE(KPPAIRS_VERBOSE,"Unnattaching edge %p: %u (%u,%u)",
00205 It1->this, ((EGdGraphEdge_t*)It1->this)->id,
00206 ((EGdGraphEdge_t*)It1->this)->tail->id,
00207 ((EGdGraphEdge_t*)It1->this)->head->id);
00208 EGlistPushBack(unattach_edges,It1->this);
00209
00210 }
00211 }
00212 }
00213 for(It1 = unattach_edges->begin ; It1; It1 = It1->next)
00214 EGdGraphUnattachEdge(bdG,((EGdGraphEdge_t*)It1->this));
00215
00216 #if KPPAIRS_VERBOSE <= DEBUG
00217 MESSAGE(KPPAIRS_VERBOSE,"Unattach %u edges from G", unattach_edges->size);
00218 EGdGraphDisplay(bdG,0,0,0,stderr);
00219 #endif
00220
00221
00222 tot_pairs = 0;
00223 for( i = cycle_sz ; i-- ; )
00224 {
00225 rval = EGpartialDijkstra( dc_nodes[i], 0, slack , dij_os, dij_heap, bdG);
00226 CHECKRVALG(rval,CLEANUP);
00227 for( j = i ; j-- ; )
00228 {
00229
00230 if(EGmengerGetOrigMark(dc_nodes[j],os) > UINT_MAX - 2) continue;
00231
00232 path_dist = EGdijkstraGetDist(dc_nodes[j],dij_os);
00233 dist = EGdijkstraCostAdd( path_dist, EGgetEvenDistance(dc_nodes[i]->id,
00234 dc_nodes[j]->id, data));
00235
00236
00237
00238 if(EGdijkstraCostIsLess(slack,dist)) continue;
00239
00240 for(k = zerodom->k ; k-- ; )
00241 {
00242 if(dc_nodes[i] == zerodom->pairs[k].s &&
00243 dc_nodes[j] == zerodom->pairs[k].t)
00244 continue;
00245 if(dc_nodes[i] == zerodom->pairs[k].t &&
00246 dc_nodes[j] == zerodom->pairs[k].s)
00247 continue;
00248 }
00249 MESSAGE(KPPAIRS_VERBOSE,"Path (%u,%u) with value %lf", dc_nodes[i]->id,
00250 dc_nodes[j]->id, EGdijkstraCostToLf(dist));
00251
00252 if(pairs->size >= max_pairs)
00253 {
00254 worst_pair = (EGinternalPairs_t*)pairs->end->this;
00255 if(EGdijkstraCostIsLess(worst_pair->value,dist)) continue;
00256 }
00257
00258
00259 extpath = EGnewList(mem);
00260 EGextractEEpath(dc_nodes[i]->id, dc_nodes[j]->id, data, extpath);
00261 if (!extpath->size)
00262 {
00263 #warning WARNING: This happens a lot!! Look.
00264 EGlistClear(extpath, nullFree);
00265 EGfreeList(extpath);
00266 continue;
00267 }
00268
00269
00270 tot_pairs++;
00271 cur_pair = EGmemPoolSMalloc(mem,EGinternalPairs_t,1);
00272 cur_pair->s = dc_nodes[i];
00273 cur_pair->t = dc_nodes[j];
00274 cur_pair->ivalue = path_dist;
00275 cur_pair->value = dist;
00276 cur_pair->stpath = EGmemPoolSMalloc(mem, EGdGraphEdge_t*, EGdijkstraGetNdist(dc_nodes[j], dij_os));
00277 EGdijkstraExtractSolution( cur_pair->stpath, &cur_pair->npath, dc_nodes[i], dc_nodes[j], dij_os );
00278 cur_pair->extpath = extpath;
00279
00280
00281 for(It1 = pairs->end ; It1 ; It1 = It1->prev)
00282 {
00283 worst_pair = (EGinternalPairs_t*)It1->this;
00284 if(EGdijkstraCostIsLess(worst_pair->value,dist))
00285 break;
00286 }
00287 if(It1) EGlistInsertAfter(pairs,It1,cur_pair);
00288 else EGlistPushHead(pairs,cur_pair);
00289 while(pairs->size > max_pairs)
00290 {
00291 EGlistEraseMP(pairs,pairs->end,EGfreeInternalPairs,mem);
00292 }
00293 }
00294 }
00295
00296
00297 CLEANUP:
00298 if(tot_pairs)
00299 MESSAGE(KPPAIRS_VERBOSE, "for kdom %p generate %u pairs, value range"
00300 " [%lf,%lf], eliminated edges %u",
00301 (void*)zerodom, tot_pairs, pairs->size ?
00302 EGdijkstraCostToLf(((EGinternalPairs_t*)pairs->begin->this)->value):
00303 2.0, pairs->size ?
00304 EGdijkstraCostToLf(((EGinternalPairs_t*)pairs->end->this)->value):
00305 2.0, unattach_edges->size);
00306 for(It1 = unattach_edges->begin ; It1; It1 = It1->next)
00307 {
00308 tmp_edge = (EGdGraphEdge_t*)It1->this;
00309 EGdGraphAttachEdge(bdG,tmp_edge);
00310 }
00311 EGfreeList(unattach_edges);
00312 EGfreeHeap(dij_heap,mem);
00313 EGfreeList(CUT[0]);
00314 EGfreeList(CUT[1]);
00315 return rval;
00316 }
00317
00318
00319 void EGinternalPairsClear(void*pair,EGmemPool_t*mem)
00320 {
00321
00322 EGinternalPairs_t*const p = (EGinternalPairs_t*)pair;
00323 if(p->stpath) EGmemPoolSFree(p->stpath, EGdGraphEdge_t*, p->npath, mem);
00324 p->stpath = 0;
00325 p->npath = 0;
00326 if(p->extpath)
00327 {
00328 EGlistClear(p->extpath, nullFree);
00329 EGfreeList(p->extpath);
00330 p->extpath = 0;
00331 }
00332 return;
00333 }
00334
00335
00336 void EGfreeInternalPairs(void*pair,EGmemPool_t*mem)
00337 {
00338 EGinternalPairsClear(pair,mem);
00339 EGmemPoolSFree(pair,EGinternalPairs_t,1,mem);
00340 return;
00341 }
00342
00343
00344 int EGgetCutNodes(EGgreedyData_t*const data,
00345 EGdualCut_t*const dualcut,
00346 const unsigned int orientation,
00347 int*const cutsz,
00348 int**const cutnodes,
00349 unsigned char*const node_mark,
00350 unsigned char*const edge_mark)
00351 {
00352 unsigned register int i = 0;
00353 int j = 0;
00354 EGmemPool_t* mem = data->bdG->mem;
00355 EGlist_t*CUT[2]={EGnewList(mem),EGnewList(mem)};
00356 size_t set_sz[2] = {0,0};
00357 unsigned char cur_mark = orientation ? 2U : 1U;
00358 unsigned const int cycle_sz = dualcut->sz;
00359 const size_t nedges = data->bdG->edge_id_max/2;
00360 const size_t nnodes = nedges + 2 - data->bdG->node_id_max;
00361 int rval = 0;
00362
00363
00364 TESTG((rval=(data->bdG->node_id_max!=data->bdG->nodes->size)),
00365 CLEANUP,"Imposible!");
00366
00367
00368
00369 memset(edge_mark,0,sizeof(unsigned char)*nedges);
00370 for( i = cycle_sz ; i-- ; )
00371 edge_mark[EGmengerGetEdgeData(dualcut->edges[i],os)->id] ^= 1U;
00372
00373
00374 rval = EGdoPrimalDfs(2,set_sz,CUT,node_mark,edge_mark,data);
00375 CHECKRVALG(rval,CLEANUP);
00376 TESTG((rval=!set_sz[cur_mark-1]),CLEANUP,"Empty set! imposible!");
00377
00378
00379 *cutsz = set_sz[cur_mark-1];
00380 if(*cutsz) *cutnodes = EGsMalloc(int,*cutsz);
00381 j = 0;
00382 for( i = nnodes ; i-- ; )
00383 if(node_mark[i] == cur_mark)
00384 (*cutnodes)[j++] = i;
00385 TESTG((rval=(j!=(*cutsz))), CLEANUP, "Imposible!");
00386
00387
00388 CLEANUP:
00389 EGfreeList(CUT[0]);
00390 EGfreeList(CUT[1]);
00391 return rval;
00392 }
00393
00394
00395 int EGgetANodes(EGgreedyData_t*const data,
00396 EGdkdomino_t*const kdom,
00397 int unsigned const k,
00398 int*const cutsz,
00399 int**const cutnodes,
00400 unsigned char*const node_mark,
00401 unsigned char*const edge_mark,
00402 EGdGraphEdge_t**const dc_nodes)
00403 {
00404 unsigned register int i = 0;
00405 int j = 0;
00406 EGmemPool_t* mem = data->bdG->mem;
00407 EGlist_t*CUT[4]={EGnewList(mem),EGnewList(mem),EGnewList(mem),EGnewList(mem)};
00408 size_t set_sz[4] = {0,0,0,0};
00409 unsigned char cur_mark = kdom->orientation ? 4U : 2U;
00410 unsigned const int cycle_sz = kdom->cut->sz;
00411 const size_t nedges = data->bdG->edge_id_max/2;
00412 const size_t nnodes = nedges + 2 - data->bdG->node_id_max;
00413 EGdGraphNode_t*s = kdom->pairs[k].s;
00414 EGdGraphNode_t*const t = kdom->pairs[k].t;
00415 EGdGraphEdge_t*e=0;
00416 int rval = 0;
00417 EGlistNode_t* It = 0;
00418 *cutsz = 0;
00419 *cutnodes = 0;
00420 EGlist_t* DFS = EGnewList(mem);
00421 memset(dc_nodes,0,sizeof(EGdGraphEdge_t*)*data->bdG->nodes->size);
00422
00423
00424 TESTG((rval=(data->bdG->node_id_max!=data->bdG->nodes->size)),
00425 CLEANUP,"Imposible!");
00426
00427
00428
00429 memset(edge_mark,0,sizeof(unsigned char)*nedges);
00430 for( i = cycle_sz ; i-- ; )
00431 edge_mark[EGmengerGetEdgeData(kdom->cut->edges[i],os)->id] ^= 2U;
00432
00433
00434 EGlistPushBack(DFS,s);
00435 while(DFS->size && s!= t)
00436 {
00437 s = (EGdGraphNode_t*)DFS->begin->this;
00438 EGlistErase(DFS,DFS->begin,0);
00439 for( It = s->out_edges->begin ; It ; It = It->next)
00440 {
00441 e = (EGdGraphEdge_t*)It->this;
00442 if(edge_mark[EGmengerGetEdgeData(e,os)->id]== 2 && !dc_nodes[e->head->id])
00443 {
00444 dc_nodes[e->head->id] = e;
00445 EGlistPushHead(DFS,e->head);
00446 edge_mark[EGmengerGetEdgeData(e,os)->id] = 3;
00447 }
00448 }
00449 }
00450 if(s!=t)
00451 {
00452 rval = EG_KP_NOST;
00453
00454 goto CLEANUP;
00455 }
00456
00457
00458
00459 memset(edge_mark,0,sizeof(unsigned char)*nedges);
00460 for( i = cycle_sz ; i-- ; )
00461 edge_mark[EGmengerGetEdgeData(kdom->cut->edges[i],os)->id] ^= 2U;
00462
00463
00464 for( i = kdom->pairs[k].npath ; i-- ; )
00465 edge_mark[EGmengerGetEdgeData(kdom->pairs[k].stpath[i],os)->id] ^= 1U;
00466
00467
00468 for( e = dc_nodes[t->id] ; e && e->head != kdom->pairs[k].s ; e = dc_nodes[e->tail->id])
00469 edge_mark[EGmengerGetEdgeData(e,os)->id] ^= 1U;
00470
00471
00472 rval = EGdoPrimalDfs(4,set_sz,CUT,node_mark,edge_mark,data);
00473 CHECKRVALG(rval,CLEANUP);
00474 TESTG((rval=!set_sz[cur_mark-1]),CLEANUP,"Empty set! imposible!");
00475
00476
00477 *cutsz = set_sz[cur_mark-1];
00478 if(*cutsz) *cutnodes = EGsMalloc(int,*cutsz);
00479 j = 0;
00480 for( i = nnodes ; i-- ; )
00481 if(node_mark[i] == cur_mark)
00482 (*cutnodes)[j++] = i;
00483 TESTG((rval=(j!=(*cutsz))), CLEANUP, "Imposible!");
00484
00485
00486 CLEANUP:
00487 EGfreeList(DFS);
00488 EGfreeList(CUT[0]);
00489 EGfreeList(CUT[1]);
00490 EGfreeList(CUT[2]);
00491 EGfreeList(CUT[3]);
00492 return rval;
00493 }
00494
00495
00496 int EGgetOrientation( EGgreedyData_t*const data,
00497 EGdualCut_t*const dualcut,
00498 int unsigned const pathsz,
00499 EGdGraphEdge_t**const path,
00500 unsigned int*const orientation,
00501 unsigned char*const node_mark,
00502 unsigned char*const edge_mark)
00503 {
00504 unsigned register int i = 0;
00505 EGmemPool_t* mem = data->bdG->mem;
00506 EGlist_t*CUT[2]={EGnewList(mem),EGnewList(mem)};
00507 size_t set_sz[2] = {0,0};
00508 unsigned char cur_mark = 0;
00509 unsigned const int cycle_sz = dualcut->sz;
00510 const size_t nedges = data->bdG->edge_id_max/2;
00511 const graphP G = data->G;
00512 graphNodeP pedge;
00513 int rval = 0;
00514
00515
00516 TESTG((rval=(data->bdG->node_id_max!=data->bdG->nodes->size)),
00517 CLEANUP,"Imposible!");
00518
00519
00520
00521 memset(edge_mark,0,sizeof(unsigned char)*nedges);
00522 for( i = cycle_sz ; i-- ; )
00523 edge_mark[EGmengerGetEdgeData(dualcut->edges[i],os)->id] ^= 1U;
00524
00525
00526 rval = EGdoPrimalDfs(2,set_sz,CUT,node_mark,edge_mark,data);
00527 CHECKRVALG(rval,CLEANUP);
00528
00529
00530 cur_mark = node_mark[EGmengerGetEdgeData(path[0],os)->v];
00531 *orientation = cur_mark - 1;
00532 for( i = pathsz ; i-- ; )
00533 {
00534 pedge = EGmengerGetEdgeData(path[i],os);
00535 TESTG((rval=((node_mark[pedge->v]!=cur_mark) ||
00536 (node_mark[GETOTHEREND(pedge)]!=cur_mark))),
00537 CLEANUP, "Imposible!");
00538 }
00539
00540
00541 CLEANUP:
00542 EGfreeList(CUT[0]);
00543 EGfreeList(CUT[1]);
00544 return rval;
00545 }
00546
00547
00548 int EGgetDualCut( EGgreedyData_t*const data,
00549 EGdualCut_t**const dualcut,
00550 const int pset_sz,
00551 const int*const pset,
00552 unsigned char*const node_mark,
00553 unsigned char*const edge_mark,
00554 EGdGraphEdge_t**const dc_nodes)
00555 {
00556 int rval = 0;
00557 register unsigned int i;
00558 unsigned cycle_sz = 0;
00559 EGlistNode_t *nit,*eit;
00560 EGdGraphNode_t*c_node;
00561 EGdGraphEdge_t*c_edge;
00562 const graphP G = data->G;
00563 EGdijkstraCost_t cutval = EGdijkstraToCost(0.0);
00564 graphNodeP pedge;
00565
00566 memset(dc_nodes,0,sizeof(EGdGraphEdge_t*)*data->norig_edges);
00567 memset(node_mark,0,sizeof(unsigned char)*data->norig_nodes);
00568 memset(edge_mark,0,sizeof(unsigned char)*data->norig_edges);
00569
00570 for( i = pset_sz ; i-- ; ) node_mark[pset[i]] = 1;
00571
00572 for( nit = data->bdG->nodes->begin ; nit ; nit = nit->next)
00573 {
00574 c_node = (EGdGraphNode_t*)nit->this;
00575 for(eit = c_node->out_edges->begin ; eit ; eit = eit->next)
00576 {
00577 c_edge = (EGdGraphEdge_t*)eit->this;
00578 pedge = EGmengerGetEdgeData(c_edge,os);
00579 if(edge_mark[pedge->id]) continue;
00580 if(node_mark[pedge->v] != node_mark[GETOTHEREND(pedge)])
00581 {
00582 edge_mark[pedge->id] = 1;
00583 cutval = EGdijkstraCostAdd( cutval,
00584 EGdijkstraGetEdgeLength( c_edge, dij_os) );
00585 dc_nodes[cycle_sz++] = c_edge;
00586 }
00587 }
00588 }
00589
00590 *dualcut = EGnewDualCut(data->bdG->mem, cycle_sz);
00591 memcpy((*dualcut)->edges,dc_nodes,cycle_sz*sizeof(EGdGraphEdge_t*));
00592 (*dualcut)->value = cutval;
00593 return rval;
00594 }