00001 #include "eg_ddpconstraint.h"
00002
00003
00004
00005 #define EGddGetEdge(DOM,a,b) ((graphNodeP)(((DOM)->DDtype == DOM_CC_ONE) ? \
00006 (DOM)->path[a][b]:((EGmengerEdgeData_t*)(((EGdGraphEdge_t*)\
00007 ((DOM)->path[a][b]))->data))->data))
00008
00009 static inline int EGgetPrimalDPdist (EGddpConstraint_t const *const ddp,
00010
00011 double *const dist)
00012
00013 {
00014
00015
00016 double alphax = -1.0;
00017 register unsigned int k;
00018
00019
00020
00021 for (k = ddp->nF; k--;)
00022 alphax +=
00023 EGdijkstraCostToLf (((EGmengerEdgeData_t *) (ddp->F[k]->data))->cost);
00024
00025
00026 for (k = ddp->ndom; k--;)
00027 alphax += EGdijkstraCostToLf (ddp->ddom[k]->value);
00028
00029 alphax /= sqrt (((double) (ddp->nF + ddp->ndom)));
00030 *dist = alphax;
00031 return 0;
00032 }
00033
00034 static int EGdominoCompare (const void *p1,
00035 const void *p2)
00036 {
00037
00038 if ((*((ccddomp_t) (p1)))->id < (*((ccddomp_t) (p2)))->id)
00039 return -1;
00040 else if ((*((ccddomp_t) (p1)))->id > (*((ccddomp_t) (p2)))->id)
00041 return 1;
00042 return 0;
00043 }
00044
00045 static inline int EGgetPrimalDPangle (EGddpConstraint_t const *const ddp1,
00046
00047 EGddpConstraint_t const *const ddp2,
00048
00049 double *const angle)
00050
00051 {
00052
00053
00054
00055 register unsigned int k1 = 0,
00056 k2 = 0;
00057 double norm3 = 0;
00058
00059
00060 while (k1 < ddp1->nF && k2 < ddp2->nF)
00061 {
00062 switch (EGedgeCompare (ddp1->F + k1, ddp2->F + k2))
00063 {
00064 case 0:
00065 norm3 += 1;
00066 k1++;
00067 k2++;
00068 break;
00069 case 1:
00070 k1++;
00071 break;
00072 case -1:
00073 k2++;
00074 break;
00075 }
00076 }
00077 k1 = k2 = 0;
00078 while (k1 < ddp1->ndom && k2 < ddp2->ndom)
00079 {
00080 switch (EGdominoCompare (ddp1->ddom + k1, ddp2->ddom + k2))
00081 {
00082 case 0:
00083 norm3 += 1;
00084 k1++;
00085 k2++;
00086 break;
00087 case 1:
00088 k1++;
00089 break;
00090 case -1:
00091 k2++;
00092 break;
00093 }
00094 }
00095
00096 *angle = norm3;
00097 *angle /= sqrt ((double) ((ddp1->nF + ddp1->ndom) * (ddp2->nF + ddp2->ndom)));
00098
00099
00100 return 0;
00101 }
00102
00103 static long long unsigned int global_cnt = 0;
00104
00105 static inline double EGddpHeuristicVal (EGdijkstraCost_t dcost)
00106 {
00107
00108 double val = EGdijkstraCostToLf (dcost);
00109
00110 if (val < 0.01)
00111 val = 0.01;
00112
00113
00114
00115
00116
00117
00118 val = (1 / val);
00119
00120 return val;
00121
00122 }
00123
00124
00125
00126
00127
00128 static inline EGcycleData_t *EGnewCycleData (EGmemPool_t * mem,
00129 EGdijkstraCost_t new_weight,
00130 EGddomino_t * new_ddom,
00131 EGdGraphEdge_t * new_e)
00132 {
00133
00134 double val;
00135 EGcycleData_t *cycle_data;
00136
00137 if (EGdijkstraCostIsLess (new_weight, EGdijkstraToCost (-0.02)))
00138 {
00139 fprintf (stdout,
00140 "WARNING! cycle-data edge is less than -0.02 (%lf) set to 0.0\n",
00141 EGdijkstraCostToLf (new_weight));
00142 new_weight = EGdijkstraToCost (0.0);
00143 }
00144 cycle_data = EGmemPoolSMalloc (mem, EGcycleData_t, 1);
00145 cycle_data->weight = new_weight;
00146 cycle_data->e = new_e;
00147 cycle_data->ddom = new_ddom;
00148
00149 val = round (EGddpHeuristicVal (new_weight));
00150
00151 cycle_data->pweight = ((unsigned int) val);
00152
00153 return cycle_data;
00154
00155 }
00156
00157 void EGfreeCycleDataMP (void *v,
00158 EGmemPool_t * mem)
00159 {
00160
00161 EGmemPoolSFree (v, EGcycleData_t, 1, mem);
00162
00163 return;
00164
00165 }
00166
00167 EGdGraph_t *EGnewCycleGraph (EGmemPool_t * mem,
00168 EGlist_t * dlist,
00169 EGdGraph_t * bdG,
00170 EGdijkstraCost_t max_val)
00171 {
00172
00173 unsigned int p,
00174 ph,
00175 pt;
00176 EGdGraphNode_t *n;
00177 EGdGraphEdge_t *e;
00178 EGlistNode_t *n_it,
00179 *e_it,
00180 *dd_it;
00181 EGdGraph_t *cycleG;
00182 EGcycleData_t *edata;
00183 EGddomino_t *ddom;
00184 EGdijkstraNodeData_t *ndata;
00185 EGmengerEdgeData_t *mdata;
00186
00187 EGdGraphNode_t **node_array;
00188
00189 cycleG = EGnewDGraph (mem);
00190
00191
00192 node_array = EGmemPoolSMalloc (mem, EGdGraphNode_t *, 2 * (bdG->nodes->size));
00193
00194 for (n_it = bdG->nodes->begin; n_it; n_it = n_it->next)
00195 {
00196 n = (EGdGraphNode_t *) (n_it->this);
00197
00198
00199 p = 2 * (n->id);
00200 ndata = EGnewDijkstraNodeData (mem);
00201 ndata->father = 0;
00202 node_array[p] = EGdGraphAddNode (cycleG, ndata);
00203
00204 p = 2 * (n->id) + 1;
00205 ndata = EGnewDijkstraNodeData (mem);
00206 ndata->father = 0;
00207 node_array[p] = EGdGraphAddNode (cycleG, ndata);
00208 }
00209
00210
00211 for (n_it = bdG->nodes->begin; n_it; n_it = n_it->next)
00212 {
00213 n = (EGdGraphNode_t *) (n_it->this);
00214 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
00215 {
00216 e = (EGdGraphEdge_t *) (e_it->this);
00217 mdata = (EGmengerEdgeData_t *) (e->data);
00218 if (EGdijkstraCostIsLess (max_val, mdata->cost))
00219 continue;
00220
00221
00222
00223 ph = 2 * (e->head->id);
00224 pt = 2 * (e->tail->id);
00225 edata = EGnewCycleData (mem, mdata->cost, 0, e);
00226 EGdGraphAddEdge (cycleG, edata, node_array[ph], node_array[pt]);
00227
00228
00229
00230 ph = 2 * (e->head->id) + 1;
00231 pt = 2 * (e->tail->id) + 1;
00232 edata = EGnewCycleData (mem, mdata->cost, 0, e);
00233 EGdGraphAddEdge (cycleG, edata, node_array[ph], node_array[pt]);
00234
00235 }
00236 }
00237
00238
00239 for (dd_it = dlist->begin; dd_it; dd_it = dd_it->next)
00240 {
00241 ddom = (EGddomino_t *) (dd_it->this);
00242 if (EGdijkstraCostIsLess (max_val, ddom->primalValue))
00243 continue;
00244
00245
00246
00247 ph = 2 * (ddom->s->id);
00248 pt = 2 * (ddom->t->id) + 1;
00249 edata = EGnewCycleData (mem, ddom->primalValue, ddom, 0);
00250 EGdGraphAddEdge (cycleG, edata, node_array[ph], node_array[pt]);
00251
00252
00253
00254 ph = 2 * (ddom->s->id) + 1;
00255 pt = 2 * (ddom->t->id);
00256 edata = EGnewCycleData (mem, ddom->primalValue, ddom, 0);
00257 EGdGraphAddEdge (cycleG, edata, node_array[ph], node_array[pt]);
00258
00259
00260
00261 ph = 2 * (ddom->t->id);
00262 pt = 2 * (ddom->s->id) + 1;
00263 edata = EGnewCycleData (mem, ddom->primalValue, ddom, 0);
00264 EGdGraphAddEdge (cycleG, edata, node_array[ph], node_array[pt]);
00265
00266
00267
00268 ph = 2 * (ddom->t->id) + 1;
00269 pt = 2 * (ddom->s->id);
00270 edata = EGnewCycleData (mem, ddom->primalValue, ddom, 0);
00271 EGdGraphAddEdge (cycleG, edata, node_array[ph], node_array[pt]);
00272 }
00273
00274 EGmemPoolSFree (node_array, EGdGraphNode_t *, 2 * (bdG->nodes->size), mem);
00275
00276 return cycleG;
00277
00278 }
00279
00280 void EGfreeDDPconstraintMP (void *v,
00281 EGmemPool_t * mem)
00282 {
00283 EGddpConstraint_t *ddpc;
00284
00285 ddpc = (EGddpConstraint_t *) (v);
00286
00287 if (ddpc->ndom)
00288 EGmemPoolSFree (ddpc->ddom, EGddomino_t *, ddpc->ndom, mem);
00289 if (ddpc->nF)
00290 EGmemPoolSFree (ddpc->F, EGdGraphEdge_t *, ddpc->nF, mem);
00291
00292 EGmemPoolSFree (v, EGddpConstraint_t, 1, mem);
00293
00294 return;
00295 }
00296
00297
00298 int EGboyerEdgeNumber (const EGdGraphEdge_t * e)
00299 {
00300 EGmengerEdgeData_t *d;
00301 graphNodeP a;
00302
00303 d = (EGmengerEdgeData_t *) (e->data);
00304 a = (graphNodeP) (d->data);
00305
00306 return (a->id);
00307 }
00308
00309 int EGedgeCompare (const void *p1,
00310 const void *p2)
00311 {
00312 const EGdGraphEdge_t *e1,
00313 *e2;
00314
00315 e1 = (*((ccep_t) (p1)));
00316 e2 = (*((ccep_t) (p2)));
00317
00318 if (EGboyerEdgeNumber (e1) < EGboyerEdgeNumber (e2))
00319 return -1;
00320 else if (EGboyerEdgeNumber (e1) > EGboyerEdgeNumber (e2))
00321 return 1;
00322 return 0;
00323 }
00324
00325
00326 #define EGddGetEdgeCost(dedge) (\
00327 ((EGmengerEdgeData_t*)(((EGdGraphEdge_t*)(dedge))->data))->cost)
00328 static unsigned int __ndisc = 0;
00329 static unsigned int __accept = 0;
00330 static inline int EGddpMuCondition (EGddpConstraint_t * ddpc)
00331 {
00332 EGdijkstraCost_t muH = EGdijkstraToCost (ddpc->ndom + 1),
00333 p_cost[2];
00334 register unsigned int i;
00335 unsigned pth,
00336 dom;
00337
00338 for (i = ddpc->nF; i--;)
00339 muH = EGdijkstraCostSub (muH, EGddGetEdgeCost (ddpc->F[i]));
00340 for (dom = ddpc->ndom; dom--;)
00341 {
00342 p_cost[0] = EGdijkstraToCost (0);
00343 p_cost[1] = EGdijkstraToCost (100);
00344
00345 for (pth = 3; pth--;)
00346 {
00347 for (i = ddpc->ddom[dom]->npath[pth]; i--;)
00348 p_cost[0] = EGdijkstraCostAdd (p_cost[0],
00349 EGddGetEdgeCost (ddpc->ddom[dom]->
00350 path[pth][i]));
00351 if (EGdijkstraCostIsLess (p_cost[0], p_cost[1]))
00352 p_cost[1] = p_cost[0];
00353 }
00354 muH = EGdijkstraCostSub (muH, p_cost[1]);
00355 }
00356
00357 if (EGdijkstraCostIsLess (EGdijkstraToCost (0), muH))
00358 {
00359 __accept++;
00360 return 1;
00361 }
00362 __ndisc++;
00363
00364
00365 return 0;
00366 }
00367
00368 static inline int EGddpIsMinimal (EGddpConstraint_t * ddpc,
00369 unsigned int *marray,
00370 unsigned int marray_size)
00371 {
00372
00373 unsigned int i;
00374
00375 for (i = 0; i < marray_size; i++)
00376 marray[i] = 0;
00377
00378 for (i = 0; i < ddpc->nF; i++)
00379 {
00380 marray[ddpc->F[i]->head->id] += 1;
00381 marray[ddpc->F[i]->tail->id] += 1;
00382 }
00383
00384 for (i = 0; i < ddpc->ndom; i++)
00385 {
00386 marray[ddpc->ddom[i]->s->id] += 1;
00387 marray[ddpc->ddom[i]->t->id] += 1;
00388 }
00389
00390 for (i = 0; i < marray_size; i++)
00391 {
00392 if (marray[i] > 2)
00393 return 0;
00394 }
00395
00396 return 1;
00397
00398 }
00399
00400 static inline int EGddpExtractSolution (EGdGraphEdge_t ** path,
00401 unsigned int *npath,
00402 EGdGraphNode_t * t,
00403 EGdijkstraCost_t * LHS_val)
00404 {
00405
00406 EGdijkstraCost_t dcVal;
00407
00408 EGdGraphEdge_t *e;
00409 EGdGraphNode_t *n;
00410 EGdijkstraNodeData_t *dndata;
00411 EGcycleData_t *cdata;
00412
00413 unsigned int pos;
00414
00415 n = t;
00416 pos = 0;
00417 dcVal = EGdijkstraToCost (0.0);
00418
00419 while (((n->id) / 2 != (t->id) / 2) || !pos)
00420 {
00421 dndata = (EGdijkstraNodeData_t *) (n->data);
00422 e = dndata->father;
00423
00424 cdata = (EGcycleData_t *) (e->data);
00425 dcVal = EGdijkstraCostAdd (dcVal, cdata->weight);
00426
00427 path[pos] = e;
00428 n = e->tail;
00429
00430 pos += 1;
00431 }
00432
00433 *npath = pos;
00434 *LHS_val = dcVal;
00435
00436 return 0;
00437
00438 }
00439
00440 static inline int EGddpAreSame (EGddpConstraint_t * c1,
00441 EGddpConstraint_t * c2)
00442 {
00443 unsigned int i;
00444
00445 if ((c1->nF != c2->nF) || (c1->ndom != c2->ndom))
00446 return 0;
00447
00448 for (i = 0; i < c1->nF; i++)
00449 {
00450 if (EGboyerEdgeNumber (c1->F[i]) != EGboyerEdgeNumber (c2->F[i]))
00451 return 0;
00452 }
00453 for (i = 0; i < c1->ndom; i++)
00454 {
00455 if ((c1->ddom[i]->s->id) != (c2->ddom[i]->s->id))
00456 return 0;
00457 if ((c1->ddom[i]->t->id) != (c2->ddom[i]->t->id))
00458 return 0;
00459 if ((c1->ddom[i]->value != c2->ddom[i]->value))
00460 return 0;
00461 }
00462
00463 return 1;
00464
00465 }
00466
00467 static inline int EGddpSortData (EGddpConstraint_t * c)
00468 {
00469 if (c->ndom > 1)
00470 qsort (c->ddom, c->ndom, sizeof (EGddomino_t *), EGdominoCompare);
00471 if (c->nF > 1)
00472 qsort (c->F, c->nF, sizeof (EGdGraphEdge_t *), EGedgeCompare);
00473
00474 return 0;
00475 }
00476
00477 static inline EGddpConstraint_t *EGnewDDPconstraint (EGmemPool_t * mem,
00478 EGdGraphEdge_t ** dij_sol,
00479 unsigned int ndij_sol,
00480 int k,
00481 EGdijkstraCost_t val)
00482 {
00483
00484 EGcycleData_t *cdata;
00485 EGddpConstraint_t *ddpc;
00486 unsigned int i;
00487
00488 ddpc = EGmemPoolSMalloc (mem, EGddpConstraint_t, 1);
00489 ddpc->ndom = 0;
00490 ddpc->nF = 0;
00491
00492 for (i = 0; i < ndij_sol; i++)
00493 {
00494 cdata = (EGcycleData_t *) (dij_sol[i]->data);
00495 if (cdata->ddom)
00496 ddpc->ndom += 1;
00497 else
00498 ddpc->nF += 1;
00499 }
00500
00501 if (ddpc->nF)
00502 ddpc->F = EGmemPoolSMalloc (mem, EGdGraphEdge_t *, ddpc->nF);
00503 else
00504 ddpc->F = 0;
00505 if (ddpc->ndom)
00506 ddpc->ddom = EGmemPoolSMalloc (mem, EGddomino_t *, ddpc->ndom);
00507 else
00508 ddpc->ddom = 0;
00509
00510 ddpc->ndom = 0;
00511 ddpc->nF = 0;
00512
00513 for (i = 0; i < ndij_sol; i++)
00514 {
00515 cdata = (EGcycleData_t *) (dij_sol[i]->data);
00516 if (cdata->ddom)
00517 {
00518 ddpc->ddom[ddpc->ndom] = cdata->ddom;
00519 ddpc->ndom += 1;
00520 }
00521 else
00522 {
00523 ddpc->F[ddpc->nF] = cdata->e;
00524 ddpc->nF += 1;
00525 }
00526 }
00527
00528 ddpc->LHS_dp = val;
00529 ddpc->slack_dp = EGdijkstraCostToLf (val) - 1.0;
00530 return ddpc;
00531
00532 }
00533
00534
00535 static int EGddpAddCutIfNew (EGddpConstraint_t ** ddpc_array,
00536 double *const ddpc_dist,
00537 double *const ddpc_angle_norm,
00538 double *const *const ddpc_angle,
00539 unsigned int *const ddpc_size,
00540 unsigned int const ddpc_max_size,
00541 double *const ddpc_best_angle,
00542 double *const ddpc_worst_angle,
00543 unsigned int *const ddpc_worst_angle_id,
00544 EGdGraphNode_t * nrigh,
00545 EGdGraph_t * cycleG,
00546 EGdGraphEdge_t ** dij_sol,
00547 unsigned int *marray,
00548 char *sarray,
00549 size_t * os,
00550 int k,
00551 EGmemPool_t * mem)
00552 {
00553
00554 int rval;
00555 unsigned int ndij_sol;
00556 unsigned register int i;
00557 unsigned int hcmax = 0,
00558 worst_dist = 0,
00559 pos = *ddpc_size;
00560 EGddpConstraint_t *ddpc;
00561 EGdijkstraCost_t lhs_val;
00562 double val,
00563 dist,
00564 maxangle,
00565 dtmp,
00566 norm = 1.0;
00567
00568 EGddpExtractSolution (dij_sol, &ndij_sol, nrigh, &lhs_val);
00569
00570 os = 0;
00571
00572 if (((1.0) - EGdijkstraCostToLf (lhs_val)) <= ((DDP_MIN_VIOLATION)))
00573 return 0;
00574
00575
00576 ddpc = EGnewDDPconstraint (mem, dij_sol, ndij_sol, 1, lhs_val);
00577
00578
00579
00580 if (!(ddpc->ndom & 1))
00581 {
00582 EGfreeDDPconstraintMP (ddpc, mem);
00583 return 0;
00584 }
00585
00586
00587 if (ddpc->ndom < 3)
00588 {
00589 EGfreeDDPconstraintMP (ddpc, mem);
00590 return 0;
00591 }
00592
00593 rval = EGddpIsMinimal (ddpc, marray, cycleG->nodes->size / 2);
00594 if (!rval)
00595 {
00596 sarray[(nrigh->id) / 2] = 'M';
00597 EGfreeDDPconstraintMP (ddpc, mem);
00598 return 0;
00599 }
00600
00601
00602 rval = EGddpSortData (ddpc);
00603 CHECKRVAL (rval);
00604
00605
00606 for (i = *ddpc_size; i--;)
00607 {
00608 if (EGddpAreSame (ddpc, ddpc_array[i]))
00609 {
00610 sarray[(nrigh->id) / 2] = 'R';
00611 EGfreeDDPconstraintMP (ddpc, mem);
00612 return 0;
00613 }
00614 }
00615
00616
00617
00618 EGgetPrimalDPdist (ddpc, &dist);
00619 val = -1.0 * dist;
00620
00621 if (pos < ddpc_max_size)
00622 {
00623 ddpc_array[pos] = ddpc;
00624 ddpc_dist[pos] = val;
00625 ddpc_angle_norm[pos] = 1.0;
00626
00627 if (pos)
00628 {
00629 for (i = pos; i--;)
00630 {
00631 EGgetPrimalDPangle (ddpc, ddpc_array[i], &dtmp);
00632 ddpc_angle[pos][i] = dtmp;
00633 ddpc_angle[i][pos] = dtmp;
00634 ddpc_angle_norm[i] += dtmp * dtmp;
00635 ddpc_angle_norm[pos] += dtmp * dtmp;
00636 }
00637 }
00638 else
00639 *ddpc_worst_angle_id = 0;
00640 (*ddpc_size)++;
00641 pos++;
00642 MESSAGE (EG_DP_SELECT_DEBUG, "ddpc added because pool not full");
00643 }
00644
00645
00646 else
00647 {
00648 maxangle = 0.0;
00649 worst_dist = ddpc_max_size - 1;
00650
00651 for (i = ddpc_max_size; i--;)
00652 {
00653 EGgetPrimalDPangle (ddpc, ddpc_array[i], &dtmp);
00654 ddpc_angle[ddpc_max_size][i] = dtmp;
00655 norm += dtmp * dtmp;
00656 if (dtmp > maxangle)
00657 {
00658 hcmax = i;
00659 maxangle = dtmp;
00660 }
00661 if (ddpc_dist[worst_dist] > ddpc_dist[i])
00662 worst_dist = i;
00663 }
00664
00665
00666
00667 #if DDPC_REPLACE_CLOSE
00668 if ((maxangle > DP_BIG_ANGLE) && (ddpc_dist[hcmax] < val))
00669 {
00670 MESSAGE (EG_DP_SELECT_DEBUG, "ddpc added because dominate another"
00671 "inequality, angle(%lf) new disr(%lf) old dist(%lf)", maxangle,
00672 val, ddpc_dist[hcmax]);
00673 EGfreeDDPconstraintMP (ddpc_array[hcmax], mem);
00674 ddpc_array[hcmax] = ddpc;
00675 ddpc_dist[hcmax] = val;
00676 norm -= ddpc_angle[ddpc_max_size][hcmax] *
00677 ddpc_angle[ddpc_max_size][hcmax];
00678 for (i = ddpc_max_size; i--;)
00679 {
00680 dtmp = ddpc_angle[i][hcmax];
00681 ddpc_angle_norm[i] -= dtmp * dtmp;
00682 dtmp = ddpc_angle[ddpc_max_size][i];
00683 ddpc_angle_norm[i] += dtmp * dtmp;
00684 ddpc_angle[hcmax][i] = dtmp;
00685 ddpc_angle[i][hcmax] = dtmp;
00686 }
00687 ddpc_angle_norm[hcmax] = norm;
00688 }
00689 #else
00690 if (0)
00691 {
00692 }
00693 #endif
00694
00695
00696 #if DDPC_BEST_VIOLATION
00697 else if (val > ddpc_dist[worst_dist])
00698 {
00699 pos = worst_dist;
00700 MESSAGE (EG_DP_SELECT_DEBUG, "ddpc added because improve worst distance"
00701 " with norm(%lf) angle(%lf) new dist(%lf) old dist(%lf)",
00702 norm, maxangle, val, ddpc_dist[pos]);
00703 EGfreeDDPconstraintMP (ddpc_array[pos], mem);
00704 ddpc_array[pos] = ddpc;
00705 ddpc_dist[pos] = val;
00706 norm -= ddpc_angle[ddpc_max_size][pos] * ddpc_angle[ddpc_max_size][pos];
00707 for (i = ddpc_max_size; i--;)
00708 {
00709 dtmp = ddpc_angle[i][pos];
00710 ddpc_angle_norm[i] -= dtmp * dtmp;
00711 dtmp = ddpc_angle[ddpc_max_size][i];
00712 ddpc_angle_norm[i] += dtmp * dtmp;
00713 ddpc_angle[i][pos] = dtmp;
00714 ddpc_angle[pos][i] = dtmp;
00715 }
00716 ddpc_angle_norm[pos] = norm;
00717 }
00718 #endif
00719
00720
00721 #if DDPC_IMPROVE_SPREAD
00722 else if (*ddpc_worst_angle > SELECT_MIN_NORM && *ddpc_worst_angle +
00723 (ddpc_angle[ddpc_max_size][*ddpc_worst_angle_id]) *
00724 (ddpc_angle[ddpc_max_size][*ddpc_worst_angle_id]) > norm &&
00725 val > DP_MAXDECREASE * ddpc_dist[worst_dist])
00726 {
00727 pos = *ddpc_worst_angle_id;
00728 MESSAGE (EG_DP_SELECT_DEBUG, "ddpc added because improve worst norm(%lf)"
00729 " with norm(%lf) angle(%lf) new dist(%lf) old dist(%lf)",
00730 *ddpc_worst_angle, norm, maxangle, val, ddpc_dist[pos]);
00731 EGfreeDDPconstraintMP (ddpc_array[pos], mem);
00732 ddpc_array[pos] = ddpc;
00733 ddpc_dist[pos] = val;
00734 norm -= ddpc_angle[ddpc_max_size][pos] * ddpc_angle[ddpc_max_size][pos];
00735 for (i = ddpc_max_size; i--;)
00736 {
00737 dtmp = ddpc_angle[i][pos];
00738 ddpc_angle_norm[i] -= dtmp * dtmp;
00739 dtmp = ddpc_angle[ddpc_max_size][i];
00740 ddpc_angle_norm[i] += dtmp * dtmp;
00741 ddpc_angle[i][pos] = dtmp;
00742 ddpc_angle[pos][i] = dtmp;
00743 }
00744 ddpc_angle_norm[pos] = norm;
00745 }
00746 #endif
00747
00748 else
00749 {
00750 MESSAGE (EG_DP_SELECT_DEBUG, "ddpc discarded. worst norm(%lf) with norm"
00751 "(%lf) angle(%lf) new dist(%lf) old dist(%lf)",
00752 *ddpc_worst_angle, norm, maxangle, val, ddpc_dist[worst_dist]);
00753 EGfreeDDPconstraintMP (ddpc, mem);
00754 }
00755 }
00756
00757 *ddpc_worst_angle = 0.0;
00758 *ddpc_best_angle = ddpc_max_size;
00759 if (*ddpc_size)
00760 for (i = *ddpc_size; i--;)
00761 {
00762 dtmp = ddpc_angle_norm[i];
00763 if (dtmp > *ddpc_worst_angle)
00764 {
00765 *ddpc_worst_angle = dtmp;
00766 *ddpc_worst_angle_id = i;
00767 }
00768 if (dtmp < *ddpc_best_angle)
00769 *ddpc_best_angle = dtmp;
00770 }
00771
00772 return 0;
00773 }
00774
00775 static unsigned char *__edge_valid = 0;
00776 static unsigned int __edge_valid_size = 0;
00777 static inline EGdGraphEdge_t *EGddpHeuristicSample (EGdGraphNode_t * n,
00778 unsigned int
00779 *marked_node_array,
00780 unsigned int
00781 n_marked_dominoes,
00782 unsigned int *odd_num,
00783 int *ddom_markers,
00784 int k)
00785 {
00786
00787 int is_e_dom,
00788 head_pid,
00789 num_feasible = 0,
00790 dom_min;
00791 double rvalue;
00792 unsigned int irvalue,
00793 max_weight = 0,
00794 current_weight = 0;
00795 EGdGraphNode_t *head;
00796 EGdGraphEdge_t *e = 0,
00797 *next_e = 0,
00798 *saved_e = 0;
00799 EGcycleData_t *cd;
00800 EGlistNode_t *it;
00801
00802
00803 unsigned int edge_valid_it;
00804
00805
00806 if (__edge_valid_size < n->out_edges->size)
00807 {
00808 if(__edge_valid) EGfree (__edge_valid);
00809 __edge_valid_size = n->out_edges->size;
00810 __edge_valid = EGsMalloc (unsigned char,
00811 __edge_valid_size);
00812 }
00813 memset (__edge_valid, 0, sizeof (unsigned char) * n->out_edges->size);
00814
00815
00816 for (edge_valid_it = 0, it = n->out_edges->begin; it;
00817 it = it->next, edge_valid_it++)
00818 {
00819
00820
00821 e = (EGdGraphEdge_t *) (it->this);
00822 cd = (EGcycleData_t *) (e->data);
00823 head = e->head;
00824 head_pid = ((head->id) / 2);
00825
00826
00827 if (cd->ddom && ddom_markers && ddom_markers[cd->ddom->id])
00828 continue;
00829
00830
00831
00832
00833 if (marked_node_array[head_pid])
00834 {
00835 rvalue = random ();
00836 rvalue /= EGRAND_MAX;
00837 is_e_dom = (cd->ddom ? 1 : 0);
00838 if (rvalue < DP_HEUR_MORE_DOM_BIAS)
00839 dom_min = 2 + n_marked_dominoes + is_e_dom - odd_num[head_pid];
00840 else
00841 dom_min = n_marked_dominoes + is_e_dom - odd_num[head_pid];
00842
00843
00844 if ((dom_min >= DP_HEUR_MIN_DOM) && (dom_min & 1))
00845 {
00846 rvalue = random ();
00847 rvalue /= EGRAND_MAX;
00848 if (rvalue < DP_HEUR_CLOSE_BIAS)
00849 {
00850 next_e = e;
00851 goto FOUND_EDGE;
00852 }
00853 }
00854 else
00855 continue;
00856 }
00857
00858
00859 __edge_valid[edge_valid_it] = 1;
00860 num_feasible += 1;
00861 max_weight += cd->pweight;
00862 saved_e = e;
00863 }
00864
00865
00866 if (!num_feasible)
00867 return 0;
00868
00869 if (num_feasible == 1)
00870 {
00871 next_e = saved_e;
00872 goto FOUND_EDGE;
00873 }
00874
00875
00876 rvalue = random ();
00877 rvalue /= EGRAND_MAX;
00878 rvalue *= max_weight;
00879 rvalue = round (rvalue);
00880 irvalue = (unsigned int) (rvalue);
00881
00882
00883 for (edge_valid_it = 0, it = n->out_edges->begin; it;
00884 it = it->next, edge_valid_it++)
00885 {
00886
00887 if (!__edge_valid[edge_valid_it])
00888 continue;
00889
00890
00891 e = (EGdGraphEdge_t *) (it->this);
00892 current_weight += ((EGcycleData_t *) (e->data))->pweight;
00893 if (current_weight >= irvalue)
00894 {
00895 next_e = e;
00896 break;
00897 }
00898
00899 }
00900
00901 FOUND_EDGE:
00902
00903
00904 ADVTESTL (1, !next_e, 0, "error sampling edge");
00905
00906 return next_e;
00907
00908 }
00909
00910
00911
00912
00913
00914
00915 int EGddpAddHeuristicCuts_3 (EGddpConstraint_t ** ddpc_array,
00916 double *const ddpc_dist,
00917 double *const ddpc_angle_norm,
00918 double *const *const ddpc_angle,
00919 unsigned int *const ddpc_size,
00920 unsigned int const ddpc_max_size,
00921 double *const ddpc_best_angle,
00922 double *const ddpc_worst_angle,
00923 unsigned int *const ddpc_worst_angle_id,
00924 int const nedges,
00925 EGdGraphNode_t * start_node,
00926 EGdGraphEdge_t * start_edge,
00927 int k,
00928 double ubound,
00929 EGdGraph_t * cycleG,
00930 EGdGraphEdge_t ** dij_sol,
00931 unsigned int *marray,
00932 char *sarray,
00933 unsigned int *odd_num,
00934 unsigned int nddom,
00935 int *ddom_markers,
00936 size_t * os,
00937 double max_node_time,
00938 EGmemPool_t * mem)
00939 {
00940
00941 int rval;
00942 unsigned int stop = 0;
00943
00944 EGdijkstraCost_t path_val;
00945 unsigned int current_pid,
00946 n_marked_dominoes;
00947
00948 EGdGraphNode_t *current_node;
00949 EGdGraphEdge_t *current_edge;
00950
00951 EGdijkstraNodeData_t *node_data;
00952 EGcycleData_t *edge_data;
00953
00954 EGtimer_t t;
00955
00956
00957 if (!start_node)
00958 start_node = start_edge->tail;
00959
00960
00961 if (sarray[(start_node)->id / 2] == 'U')
00962 return 0;
00963
00964 EGtimerReset (&t);
00965 EGtimerStart (&t);
00966
00967 while (!stop)
00968 {
00969
00970 EGtimerStop (&t);
00971
00972 if (t.time > max_node_time)
00973 {
00974 stop = 1;
00975 break;
00976 }
00977
00978 EGtimerStart (&t);
00979
00980 global_cnt += 1;
00981
00982
00983 path_val = EGdijkstraToCost (0.0);
00984
00985
00986 memset (marray, 0, sizeof (unsigned int) * ((cycleG->nodes->size) / 2));
00987
00988
00989 memset (ddom_markers, 0, sizeof (int) * nddom);
00990
00991
00992 n_marked_dominoes = 0;
00993
00994
00995 current_node = start_node;
00996 current_pid = (start_node->id) / 2;
00997
00998
00999 marray[current_pid] = 1;
01000
01001
01002 odd_num[current_pid] = n_marked_dominoes;
01003
01004
01005 if (!start_edge)
01006 current_edge = EGddpHeuristicSample (current_node,
01007 marray,
01008 n_marked_dominoes,
01009 odd_num, ddom_markers, 1);
01010 else
01011 current_edge = start_edge;
01012
01013 do
01014 {
01015
01016
01017 if (!current_edge)
01018 break;
01019
01020
01021 current_node = current_edge->head;
01022 current_pid = (current_node->id) / 2;
01023 node_data = (EGdijkstraNodeData_t *) (current_node->data);
01024 edge_data = (EGcycleData_t *) (current_edge->data);
01025
01026
01027 node_data->father = current_edge;
01028
01029
01030 path_val = EGdijkstraCostAdd (path_val, edge_data->weight);
01031
01032
01033 if (edge_data->ddom)
01034 n_marked_dominoes++;
01035
01036
01037 if (edge_data->ddom && ddom_markers)
01038 ddom_markers[edge_data->ddom->id] = 1;
01039
01040
01041 if (marray[current_pid])
01042 {
01043
01044
01045 rval =
01046 EGddpAddCutIfNew (ddpc_array, ddpc_dist, ddpc_angle_norm, ddpc_angle,
01047 ddpc_size, ddpc_max_size, ddpc_best_angle,
01048 ddpc_worst_angle, ddpc_worst_angle_id,
01049 current_node, cycleG, dij_sol, marray, sarray, os,
01050 1, mem);
01051 CHECKRVAL (rval);
01052 break;
01053 }
01054
01055 if ((ubound - EGdijkstraCostToLf (path_val)) < DDP_MIN_VIOLATION)
01056 break;
01057
01058 marray[current_pid] = 1;
01059
01060 odd_num[current_pid] = n_marked_dominoes;
01061
01062 current_edge = EGddpHeuristicSample (current_node, marray,
01063 n_marked_dominoes, odd_num,
01064 ddom_markers, 1);
01065
01066 } while (1);
01067 }
01068 return 0;
01069 }
01070
01071
01072
01073 int EGddpcComputeAll (EGmemPool_t * mem,
01074 EGdGraph_t * bdG,
01075 EGlist_t * dlist,
01076 EGlist_t * ddpc_list,
01077 int const nedges,
01078 int k)
01079 {
01080 register unsigned int i;
01081 int rval;
01082 size_t os[6];
01083 EGlistNode_t *n_it;
01084 EGdGraph_t *cycleG;
01085 EGdGraphNode_t *nleft,
01086 *nrigh;
01087 EGheap_t *my_heap;
01088
01089 char *sarray;
01090 EGdijkstraCost_t max_val = EGdijkstraToCost (1 - DP_MAXVIOLATED_EPSILON);
01091 unsigned int *marray,
01092 *odd_num;
01093 double *max_weight;
01094 EGdGraphEdge_t **dij_sol;
01095
01096 EGddpConstraint_t **ddpc_array;
01097 double *ddpc_dist;
01098 double *ddpc_angle_norm;
01099 double **ddpc_angle;
01100 unsigned int ddpc_size;
01101 unsigned int ddpc_max_size;
01102 double ddpc_best_angle;
01103 double ddpc_worst_angle;
01104 unsigned int ddpc_worst_angle_id;
01105 TEST (k != 1, "k (%d) is not one", k);
01106
01107 #if DDP_HEURISTIC
01108 EGtimer_t heur_timer;
01109 double max_ntime = 0.0;
01110 #endif
01111
01112 #if DISPLAY_MODE
01113 fprintf (stdout, "DDPC: Computing dual DP constraints.\n");
01114 #if DDP_HEURISTIC
01115 fprintf (stdout, "DDPC: Random Walk Heuristic: ON. Time Limit = %lf.\n",
01116 DDP_HEURISTIC_MAXTIME);
01117 #endif
01118 fflush (stdout);
01119 #endif
01120
01121 os[EG_DIJ_DIST] = offsetof (EGdijkstraNodeData_t, dist);
01122 os[EG_DIJ_NDIST] = offsetof (EGdijkstraNodeData_t, ndist);
01123 os[EG_DIJ_FATHER] = offsetof (EGdijkstraNodeData_t, father);
01124 os[EG_DIJ_MARKER] = offsetof (EGdijkstraNodeData_t, marker);
01125 os[EG_DIJ_HCONNECTOR] = offsetof (EGdijkstraNodeData_t, hc);
01126 os[EG_DIJ_ELENGTH] = offsetof (EGcycleData_t, weight);
01127
01128 cycleG = EGnewCycleGraph (mem, dlist, bdG, max_val);
01129
01130 fprintf (stdout, "DDPC: Cycle graph has %d nodes and %d edges.\n",
01131 cycleG->nodes->size, cycleG->nedges);
01132
01133 my_heap = EGnewHeap (mem, 2, cycleG->nodes->size);
01134
01135 dij_sol = EGmemPoolSMalloc (mem, EGdGraphEdge_t *, cycleG->nedges);
01136 marray = EGmemPoolSMalloc (mem, unsigned int,
01137 bdG->nodes->size);
01138 sarray = EGmemPoolSMalloc (mem, char,
01139 bdG->nodes->size);
01140 odd_num = EGmemPoolSMalloc (mem, unsigned int,
01141 bdG->nodes->size);
01142 max_weight = EGmemPoolSMalloc (mem, double,
01143 cycleG->nodes->size);
01144
01145 #if DDP_HEURISTIC
01146
01147
01148 rval = EGddpSetMaxWeight (cycleG, max_weight);
01149 CHECKRVAL (rval);
01150
01151
01152 max_ntime = (DDP_HEURISTIC_MAXTIME / (cycleG->nodes->size / 2));
01153
01154
01155 EGtimerReset (&heur_timer);
01156
01157 #endif
01158
01159 ddpc_max_size = DDP_HEURISTIC_MAXCUTS;
01160 ddpc_array = EGmemPoolSMalloc (mem, EGddpConstraint_t *, ddpc_max_size);
01161 ddpc_dist = EGmemPoolSMalloc (mem, double,
01162 ddpc_max_size);
01163 ddpc_angle_norm = EGmemPoolSMalloc (mem, double,
01164 ddpc_max_size);
01165 ddpc_angle = EGmemPoolSMalloc (mem, double *,
01166 ddpc_max_size + 1);
01167 ddpc_angle[ddpc_max_size] = EGmemPoolSMalloc (mem, double,
01168 ddpc_max_size);
01169 for (i = ddpc_max_size; i--;)
01170 {
01171 ddpc_angle[i] = EGmemPoolSMalloc (mem, double,
01172 ddpc_max_size);
01173 ddpc_angle[i][i] = 1.0;
01174 }
01175 ddpc_size = 0;
01176
01177
01178 for (n_it = cycleG->nodes->begin; n_it; n_it = ((n_it->next)->next))
01179 {
01180
01181 TEST (!(n_it->next), "cycle graph badly defined");
01182
01183 nleft = (EGdGraphNode_t *) (n_it->this);
01184 nrigh = (EGdGraphNode_t *) (n_it->next->this);
01185
01186
01187 sarray[(nleft->id) / 2] = 'B';
01188
01189 rval =
01190 EGpartialDijkstra (nleft, nrigh, EGdijkstraToCost (((double) 1.0)), os,
01191 my_heap, cycleG);
01192 CHECKRVAL (rval);
01193
01194 if (EGdijkstraGetMarker (nrigh, os) == UINT_MAX)
01195 continue;
01196
01197 if ((1.0 - EGdijkstraCostToLf (EGdijkstraGetDist (nrigh, os))) <
01198 (DDP_MIN_VIOLATION))
01199 continue;
01200
01201 rval =
01202 EGddpAddCutIfNew (ddpc_array, ddpc_dist, ddpc_angle_norm, ddpc_angle,
01203 &ddpc_size, ddpc_max_size, &ddpc_best_angle,
01204 &ddpc_worst_angle, &ddpc_worst_angle_id, nrigh,
01205 cycleG, dij_sol, marray, sarray, os, 1, mem);
01206 CHECKRVAL (rval);
01207
01208 #if DDP_HEURISTIC
01209 EGtimerStart (&heur_timer);
01210 rval = EGddpAddHeuristicCuts_3 (ddpc_array, ddpc_dist, ddpc_angle_norm,
01211 ddpc_angle, &ddpc_size, ddpc_max_size,
01212 &ddpc_best_angle, &ddpc_worst_angle,
01213 &ddpc_worst_angle_id, nedges, nleft, 0, 1,
01214 1.0, cycleG, dij_sol, marray, sarray,
01215 odd_num, 0, 0, os, max_ntime, mem);
01216 CHECKRVAL (rval);
01217 EGtimerStop (&heur_timer);
01218
01219 #endif
01220
01221 }
01222
01223
01224 fprintf (stderr, "***Heuristic Iterations: %llu\n", global_cnt);
01225
01226 for (i = ddpc_size; i--;)
01227 EGlistPushBack (ddpc_list, ddpc_array[i]);
01228
01229 #if DISPLAY_MODE
01230 {
01231 EGddpConstraint_t *ddpc;
01232 double abs_slack,
01233 thresh,
01234 thresh_n;
01235 unsigned int range[DISPLAY_RESOLUTION],
01236 error = 0,
01237 maximally_violated = 0;
01238 double avg_teeth = 0.0;
01239
01240 for (i = 0; i < DISPLAY_RESOLUTION; i++)
01241 range[i] = 0;
01242
01243 for (n_it = ddpc_list->begin; n_it; n_it = n_it->next)
01244 {
01245 ddpc = (EGddpConstraint_t *) (n_it->this);
01246 avg_teeth += ddpc->ndom;
01247 for (i = 0; i < DISPLAY_RESOLUTION; i++)
01248 {
01249 abs_slack = -1 * ddpc->slack_dp;
01250 thresh = 1 * (IDR) * i + 1 * (IDR);
01251 thresh_n = 1 * IDR * i;
01252 if (thresh_n <= abs_slack && abs_slack <= thresh)
01253 {
01254 range[i] += 1;
01255 break;
01256 }
01257 }
01258
01259 if (i == DISPLAY_RESOLUTION)
01260 error += 1;
01261
01262 if (-1 * ddpc->slack_dp > (1.0) - DDPCONSTRAINT_MAXVIOL_EPSILON)
01263 maximally_violated += 1;
01264
01265 }
01266 avg_teeth = avg_teeth / ((double) ddpc_list->size);
01267 #if DDP_HEURISTIC
01268 fprintf (stdout, "DDPC: Total heuristic running time: %lf seconds.\n",
01269 heur_timer.time);
01270 #endif
01271 fprintf (stdout,
01272 "DDPC: Found %u dual DP-Constraints (avg number of teeth = %lf).\n",
01273 ddpc_list->size, avg_teeth);
01274 fprintf (stdout, "DDPC: %u / %u are maximally violated.\n",
01275 maximally_violated, ddpc_list->size);
01276 fflush (stdout);
01277
01278 fprintf (stdout, "DDPC: |slack values|\n");
01279 fflush (stdout);
01280
01281 for (i = 0; i < DISPLAY_RESOLUTION; i++)
01282 {
01283 thresh = 1 * IDR * i + IDR * 1;
01284 thresh_n = 1 * IDR * i;
01285 if (range[i])
01286 fprintf (stdout, "[%8lf, %8lf] %d\n", thresh_n, thresh, range[i]);
01287 fflush (stdout);
01288 }
01289 if (error)
01290 fprintf (stdout, "[%8lf, ) %d (out of range constraints)\n",
01291 1.0, error);
01292 }
01293 #endif
01294
01295 #if DISPLAY_MODE
01296 fprintf (stdout, "DDPC: Finished finding dual DP cuts.\n");
01297 fflush (stdout);
01298 #endif
01299
01300
01301 EGmemPoolSFree (ddpc_array, EGddpConstraint_t *, ddpc_max_size, mem);
01302 EGmemPoolSFree (ddpc_dist, double,
01303 ddpc_max_size,
01304 mem);
01305 EGmemPoolSFree (ddpc_angle_norm, double,
01306 ddpc_max_size,
01307 mem);
01308 for (i = ddpc_max_size + 1; i--;)
01309 EGmemPoolSFree (ddpc_angle[i], double,
01310 ddpc_max_size,
01311 mem);
01312 EGmemPoolSFree (ddpc_angle, double *,
01313 ddpc_max_size + 1,
01314 mem);
01315
01316 EGmemPoolSFree (max_weight, double,
01317 cycleG->nodes->size,
01318 mem);
01319 EGmemPoolSFree (odd_num, unsigned int,
01320 bdG->nodes->size,
01321 mem);
01322 EGmemPoolSFree (marray, unsigned int,
01323 bdG->nodes->size,
01324 mem);
01325 EGmemPoolSFree (sarray, char,
01326 bdG->nodes->size,
01327 mem);
01328 EGmemPoolSFree (dij_sol, EGdGraphEdge_t *, cycleG->nedges, mem);
01329
01330 EGfreeHeap (my_heap, mem);
01331 EGdGraphClearMP (cycleG, EGfreeCycleDataMP, EGfreeDijkstraNodeDataMP, 0, mem,
01332 mem, 0);
01333 EGfreeDGraph (cycleG);
01334
01335
01336 return 0;
01337 }
01338
01339
01340
01341 int EGddpIsSolutionValid (EGdGraphNode_t * t,
01342 int *ddom_markers,
01343 unsigned int num_ddom)
01344 {
01345
01346 EGdGraphEdge_t *e;
01347 EGdGraphNode_t *n;
01348 EGdijkstraNodeData_t *dndata;
01349 EGcycleData_t *cdata;
01350
01351 unsigned int pos;
01352
01353 memset (ddom_markers, 0, sizeof (int) * (num_ddom));
01354
01355 n = t;
01356 pos = 0;
01357
01358 while (((n->id) / 2 != (t->id) / 2) || !pos)
01359 {
01360 dndata = (EGdijkstraNodeData_t *) (n->data);
01361 e = dndata->father;
01362 cdata = (EGcycleData_t *) (e->data);
01363
01364 if (cdata->ddom)
01365 {
01366 if (ddom_markers[cdata->ddom->id])
01367 return 0;
01368 else
01369 ddom_markers[cdata->ddom->id] += 1;
01370 }
01371
01372 n = e->tail;
01373
01374 pos += 1;
01375 }
01376
01377 return 1;
01378
01379 }
01380
01381
01382 int EGddpSetMaxWeight (EGdGraph_t * cycleG,
01383 double *max_weight)
01384 {
01385
01386 EGdGraphEdge_t *e;
01387 EGdGraphNode_t *n;
01388 EGlistNode_t *e_it,
01389 *n_it;
01390 EGcycleData_t *cd;
01391 double val;
01392
01393 for (n_it = cycleG->nodes->begin; n_it; n_it = n_it->next)
01394 {
01395
01396 n = (EGdGraphNode_t *) (n_it->this);
01397 val = 0.0;
01398
01399 for (e_it = n->out_edges->begin; e_it; e_it = e_it->next)
01400 {
01401
01402 e = (EGdGraphEdge_t *) (e_it->this);
01403 cd = (EGcycleData_t *) (e->data);
01404
01405 val += cd->pweight;
01406
01407 }
01408
01409 max_weight[(n->id)] = val;
01410
01411 }
01412
01413 return 0;
01414
01415 }
01416
01417 void EGddpcDisplay (EGddpConstraint_t * ddpc,
01418 FILE * file)
01419 {
01420
01421 unsigned int i;
01422
01423 fprintf (stderr, "F [%u]: ", ddpc->nF);
01424 for (i = 0; i < ddpc->nF; i++)
01425 EGmengerDisplayEdgeBasic (ddpc->F[i], file);
01426 fprintf (stderr, "\n");
01427
01428 fprintf (stderr, "ddom [%u]: ", ddpc->ndom);
01429 for (i = 0; i < ddpc->ndom; i++)
01430 fprintf (stderr, "%d (1)(%lf) ", ddpc->ddom[i]->id,
01431 EGdijkstraCostToLf (ddpc->ddom[i]->value));
01432 fprintf (stderr, "\n");
01433
01434 return;
01435
01436 }