00001 #include "eg_greedysample.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 int EGgenerateRandomInternalPairs( EGgreedyData_t *const gdata,
00012 EGlist_t *const new_pairs,
00013 EGlist_t *const old_pairs,
00014 unsigned int max_new_pairs,
00015 double sample_time )
00016 {
00017
00018 int rval;
00019 EGlistNode_t *it;
00020 EGinternalPairs_t *old_p, *new_p;
00021 EGdijkstraCost_t ext_ubound;
00022 EGlist_t *ext_path;
00023 EGdijkstraCost_t ext_path_val;
00024 EGmemPool_t *mem = gdata->bdG->mem;
00025 EGtimer_t timer;
00026
00027 const int ext_parity = 0;
00028 const EGdijkstraCost_t dij_two = EGdijkstraToCost(2.0);
00029
00030 for(it=old_pairs->end; it; it=it->prev)
00031 {
00032
00033 old_p = (EGinternalPairs_t*)(it->this);
00034 ext_ubound = EGdijkstraCostSub(dij_two,old_p->ivalue);
00035 EGtimerReset(&timer);
00036
00037 while(1)
00038 {
00039
00040 EGtimerStart(&timer);
00041
00042 ext_path = EGnewList(mem);
00043
00044 rval = EGgreedySample(old_p->s,
00045 old_p->t,
00046 ext_ubound,
00047 ext_parity,
00048 gdata,
00049 &ext_path_val,
00050 ext_path);
00051 CHECKRVAL(rval);
00052
00053 if (!ext_path->size)
00054 {
00055
00056 EGfreeList(ext_path);
00057 }
00058 else
00059 {
00060
00061 new_p = EGnewRandomInternalPairs(old_p, ext_path, ext_path_val, mem);
00062 TEST(!new_p, "bad internal pair generated");
00063 EGaddIPtoList(new_p, new_pairs, max_new_pairs);
00064 }
00065
00066 EGtimerStop(&timer);
00067
00068 if (timer.time > (sample_time / old_pairs->size) )
00069 break;
00070 }
00071
00072 }
00073
00074 return 0;
00075
00076 }
00077
00078 EGinternalPairs_t* EGnewRandomInternalPairs( EGinternalPairs_t *old_pair,
00079 EGlist_t *ext_path,
00080 EGdijkstraCost_t ext_value,
00081 EGmemPool_t *mem )
00082 {
00083 EGinternalPairs_t *p;
00084
00085 p = EGmemPoolSMalloc(mem, EGinternalPairs_t, 1);
00086
00087 p->s = old_pair->s;
00088 p->t = old_pair->t;
00089
00090 p->value = old_pair->ivalue + ext_value;
00091 p->ivalue = old_pair->ivalue;
00092 p->evalue = ext_value;
00093
00094 p->npath = old_pair->npath;
00095 p->stpath = EGmemPoolSMalloc(mem, EGdGraphEdge_t*, p->npath);
00096 memcpy(p->stpath, old_pair->stpath, sizeof(EGdGraphEdge_t*)*(p->npath));
00097
00098 p->extpath = ext_path;
00099
00100 return p;
00101 }
00102
00103
00104
00105
00106 int EGgreedySample( EGdGraphNode_t *bdg_s,
00107 EGdGraphNode_t *bdg_t,
00108 EGdijkstraCost_t st_ubound,
00109 int st_parity,
00110 EGgreedyData_t *gdata,
00111 EGdijkstraCost_t *path_val,
00112 EGlist_t *path )
00113 {
00114
00115 unsigned int cnt = 0;
00116 EGdGraphNode_t *s, *t;
00117 EGdGraphNode_t *curr_s;
00118 EGdGraphEdge_t *curr_e;
00119 EGcycleData_t *cd;
00120 int curr_parity = 0, rem_parity=st_parity;
00121 int e_parity = 0;
00122 int curr_s_bdg_id;
00123 EGdijkstraCost_t e_val, rem_ubound, curr_val;
00124 EGlist_t *curr_path;
00125
00126 if (!st_parity)
00127 {
00128 s = gdata->bdGtoCycleGmap[ bdg_s->id ];
00129 t = gdata->bdGtoCycleGmap[ bdg_t->id ];
00130 }
00131 else
00132 {
00133 s = gdata->bdGtoCycleGmap[ bdg_s->id ];
00134 t = (EGdGraphNode_t*) gdata->bdGtoCycleGmap[ bdg_t->id ]->cn->next->this;
00135 }
00136
00137 curr_path = EGnewList(gdata->bdG->mem);
00138 EGlistClear(path, nullFree);
00139
00140 *path_val = st_ubound;
00141
00142
00143 {
00144
00145
00146
00147
00148 curr_s = s;
00149 curr_val = EGdijkstraToCost(0.0);
00150 curr_parity = 0;
00151 rem_ubound = st_ubound;
00152 rem_parity = st_parity;
00153 EGlistClear(curr_path,nullFree);
00154 memset(gdata->bdnodes, 0, sizeof(EGdGraphNode_t*)*gdata->bdG->nodes->size);
00155
00156
00157 for(cnt=0; cnt < gdata->cycleG->nodes->size; cnt++)
00158 {
00159
00160
00161 curr_s_bdg_id = gdata->bdGnodeMap[curr_s->id/2]->id;
00162 gdata->bdnodes[curr_s_bdg_id] = (EGdGraphNode_t*)(1);
00163
00164
00165 curr_e = EGgreedySampleEdge(curr_s,
00166 t,
00167 rem_ubound,
00168 rem_parity,
00169 gdata);
00170 if (!curr_e)
00171 {
00172 EGlistClear(curr_path, nullFree);
00173
00174 break;
00175 }
00176
00177
00178 cd = (EGcycleData_t*)curr_e->data;
00179 e_parity = (cd->ddom ? 1 : 0);
00180 curr_parity = ( e_parity == curr_parity ? 0 : 1 );
00181 rem_parity = ( st_parity ? 1 - curr_parity : curr_parity );
00182
00183
00184
00185
00186
00187
00188 e_val = cd->weight;
00189 curr_val = EGdijkstraCostAdd(curr_val, e_val);
00190 rem_ubound = EGdijkstraCostSub(st_ubound, curr_val);
00191
00192 curr_s = curr_e->head;
00193 EGlistPushBack(curr_path, curr_e);
00194
00195
00196 if ( (curr_s->id/2) == (t->id/2) )
00197 break;
00198 }
00199
00200
00201
00202
00203 if ( cnt == gdata->cycleG->nodes->size )
00204 {
00205 EGlistClear(curr_path, nullFree);
00206 MESSAGE(1, "WARNING: GOT CAUGHT IN AN INFINITE LOOP");
00207 }
00208
00209
00210 if ( curr_path->size && (curr_parity != st_parity) )
00211 {
00212
00213 EGlistClear(curr_path, nullFree);
00214 }
00215
00216
00217 if ( curr_path->size && EGdijkstraCostIsLess(curr_val, *path_val) )
00218 {
00219 EGlistClear(path,nullFree);
00220 while(curr_path->size)
00221 {
00222 EGlistPushBack(path, curr_path->begin->this);
00223 EGlistErase(curr_path, curr_path->begin, nullFree);
00224 }
00225 *path_val = curr_val;
00226 }
00227 EGlistClear(curr_path, nullFree);
00228
00229 }
00230
00231 EGfreeList(curr_path);
00232
00233 return 0;
00234
00235 }
00236
00237 EGdGraphEdge_t* EGgreedySampleEdge(EGdGraphNode_t *s,
00238 EGdGraphNode_t *t,
00239 EGdijkstraCost_t st_ubound,
00240 int st_parity,
00241 EGgreedyData_t *gdata)
00242 {
00243
00244 int i, e_parity, cnt;
00245 unsigned int bdg_head, bdg_t;
00246 EGlistNode_t *it;
00247 EGdGraphEdge_t *next_e=0, *e;
00248 EGdijkstraCost_t slack, st_lbound;
00249 double tot = 0.0;
00250 double rvalue;
00251 EGcycleData_t *cd;
00252
00253 double *cand_weight = gdata->pedgevals;
00254 EGdGraphEdge_t **cand_edge = gdata->pedges;
00255
00256
00257
00258
00259
00260 for(i=0, cnt=0, it=s->out_edges->begin; it && cnt < gdata->norig_edges; it=it->next, i++)
00261 {
00262
00263 e = (EGdGraphEdge_t*)(it->this);
00264 cd = (EGcycleData_t*)(e->data);
00265
00266 e_parity = (cd->ddom ? 1 : 0);
00267
00268 bdg_head = gdata->bdGnodeMap[ e->head->id / 2 ]->id;
00269 bdg_t = gdata->bdGnodeMap[ t->id / 2 ]->id;
00270
00271
00272 if ( gdata->bdnodes[bdg_head] )
00273 continue;
00274
00275
00276 if ( st_parity == e_parity )
00277 {
00278 if (EGdijkstraCostIsLess(st_ubound, EGgetEvenDistance(bdg_head, bdg_t, gdata)))
00279 continue;
00280 st_lbound = EGdijkstraCostAdd( cd->weight, EGgetEvenDistance(bdg_head, bdg_t, gdata) );
00281 }
00282 else
00283 {
00284 if (EGdijkstraCostIsLess(st_ubound, EGgetOddDistance(bdg_head, bdg_t, gdata)))
00285 continue;
00286 st_lbound = EGdijkstraCostAdd( cd->weight, EGgetOddDistance(bdg_head, bdg_t, gdata) );
00287 }
00288
00289 slack = EGdijkstraCostSub( st_ubound, st_lbound );
00290
00291 #if 0
00292 fprintf(stderr, "%d candidate: (%d, %d) [%d, %lf] dist(%d, %d, %d) = %lf slack=%lf\n", i,
00293 e->tail->id, e->head->id, e_parity, EGdijkstraCostToLf(cd->weight),
00294 e->tail->id, e->head->id, t->id, EGdijkstraCostToLf(st_lbound), EGdijkstraCostToLf(slack));
00295 #endif
00296
00297 if ( EGdijkstraCostIsLess(slack,EGdijkstraToCost(0.0)) )
00298 continue;
00299
00300 cand_edge[cnt] = e;
00301 cand_weight[cnt] = EGdijkstraCostToLf(slack);
00302 tot += cand_weight[cnt];
00303 cnt += 1;
00304
00305 }
00306
00307 if (!cnt || cnt == gdata->norig_edges)
00308 goto DONE;
00309
00310 next_e = cand_edge[0];
00311
00312 rvalue = random();
00313 rvalue /= EGRAND_MAX;
00314 rvalue *= tot;
00315
00316 tot = 0.0;
00317
00318 for(i=0; i<cnt; i++)
00319 {
00320 tot += cand_weight[i];
00321 if ( rvalue < tot )
00322 {
00323 next_e = cand_edge[i];
00324 break;
00325 }
00326 }
00327
00328 DONE:
00329
00330 return next_e;
00331
00332 }
00333
00334
00335
00336 int EGaddIPtoList(EGinternalPairs_t *p, EGlist_t *pairs, unsigned int max_size)
00337 {
00338
00339 EGinternalPairs_t *q, *r;
00340 EGlistNode_t *it=0, *it2=0;
00341
00342
00343
00344 if ( pairs->size && pairs->size == max_size )
00345 {
00346 q = (EGinternalPairs_t*)(pairs->end->this);
00347 if ( !EGdijkstraCostIsLess(p->value, q->value) )
00348 goto NO_ADD;
00349 }
00350
00351
00352 for(it = pairs->begin; it; it=it->next)
00353 {
00354 q = (EGinternalPairs_t*)(it->this);
00355 if ( !EGdijkstraCostIsLess(q->value, p->value) )
00356 break;
00357 }
00358
00359
00360
00361
00362 for(it2 = it; it2; it2=it2->next)
00363 {
00364 r = (EGinternalPairs_t*)(it2->this);
00365 if (r->value == p->value)
00366 {
00367 if (r->s == p->s)
00368 if (r->t == p->t)
00369 if (r->extpath->size == p->extpath->size)
00370 if (r->extpath->begin->this == p->extpath->begin->this)
00371 if (r->extpath->end->this == p->extpath->end->this)
00372 goto NO_ADD;
00373 }
00374 else
00375 break;
00376 }
00377
00378
00379 if (it)
00380 EGlistInsertBefore(pairs,it,p);
00381 else
00382 EGlistPushBack(pairs, p);
00383
00384 while(pairs->size > max_size)
00385 EGlistEraseMP(pairs, pairs->end, EGfreeInternalPairs, pairs->mempool);
00386
00387 return 0;
00388
00389 NO_ADD:
00390
00391 EGfreeInternalPairs(p,pairs->mempool);
00392
00393 return 0;
00394
00395 }
00396
00397
00398 EGlist_t* EGmergeIPlists(EGlist_t *first, EGlist_t *second)
00399 {
00400
00401 EGlist_t *mlist;
00402 EGlistNode_t *it1, *it2;
00403 EGinternalPairs_t *p1, *p2;
00404
00405 mlist = EGnewList(first->mempool);
00406
00407 for(it1=first->begin, it2=second->begin; it1 || it2; )
00408 {
00409 p1 = it1 ? (EGinternalPairs_t*)(it1->this) : 0;
00410 p2 = it2 ? (EGinternalPairs_t*)(it2->this) : 0;
00411 if (!it1)
00412 {
00413 EGlistPushBack(mlist, p2);
00414 it2=it2->next;
00415 }
00416 else if (!it2)
00417 {
00418 EGlistPushBack(mlist, p1);
00419 it1=it1->next;
00420 }
00421 else if (p1->value < p2->value)
00422 {
00423 EGlistPushBack(mlist, p1);
00424 it1=it1->next;
00425 }
00426 else
00427 {
00428 EGlistPushBack(mlist, p2);
00429 it2=it2->next;
00430 }
00431 }
00432
00433 EGlistClear(first, nullFree);
00434 EGlistClear(second, nullFree);
00435 EGfreeList(first);
00436 EGfreeList(second);
00437
00438 return mlist;
00439
00440 }