00001
00002
00003
00004
00005
00006 #ifndef __VOLUME_HPP__
00007 #define __VOLUME_HPP__
00008
00009 #include <cfloat>
00010 #include <algorithm>
00011 #include <cstdio>
00012 #include <cmath>
00013
00014 #ifndef VOL_DEBUG
00015
00016 #define VOL_DEBUG 0
00017 #endif
00018
00019 template <class T> static inline T
00020 VolMax(register const T x, register const T y) {
00021 return ((x) > (y)) ? (x) : (y);
00022 }
00023
00024 template <class T> static inline T
00025 VolAbs(register const T x) {
00026 return ((x) > 0) ? (x) : -(x);
00027 }
00028
00029
00030
00031 #if defined(VOL_DEBUG) && (VOL_DEBUG != 0)
00032 #define VOL_TEST_INDEX(i, size) \
00033 { \
00034 if ((i) < 0 || (i) >= (size)) { \
00035 printf("bad VOL_?vector index\n"); \
00036 abort(); \
00037 } \
00038 }
00039 #define VOL_TEST_SIZE(size) \
00040 { \
00041 if (s <= 0) { \
00042 printf("bad VOL_?vector size\n"); \
00043 abort(); \
00044 } \
00045 }
00046 #else
00047 #define VOL_TEST_INDEX(i, size)
00048 #define VOL_TEST_SIZE(size)
00049 #endif
00050
00051
00052
00053 class VOL_dvector;
00054 class VOL_ivector;
00055 class VOL_primal;
00056 class VOL_dual;
00057 class VOL_swing;
00058 class VOL_alpha_factor;
00059 class VOL_vh;
00060 class VOL_indc;
00061 class VOL_user_hooks;
00062 class VOL_problem;
00063
00064
00065
00069 struct VOL_parms {
00071 double lambdainit;
00073 double alphainit;
00075 double alphamin;
00077 double alphafactor;
00078
00080 double ubinit;
00081
00083 double primal_abs_precision;
00085 double gap_abs_precision;
00087 double gap_rel_precision;
00089 double granularity;
00090
00093 double minimum_rel_ascent;
00095 int ascent_first_check;
00098 int ascent_check_invl;
00099
00101 int maxsgriters;
00102
00113 int printflag;
00115 int printinvl;
00117 int heurinvl;
00118
00121 int greentestinvl;
00124 int yellowtestinvl;
00127 int redtestinvl;
00128
00130 int alphaint;
00131
00133 char* temp_dualfile;
00134 };
00135
00136
00137
00146 class VOL_dvector {
00147 public:
00149 double* v;
00151 int sz;
00152
00153 public:
00155 VOL_dvector(const int s) {
00156 VOL_TEST_SIZE(s);
00157 v = new double[sz = s];
00158 }
00160 VOL_dvector() : v(0), sz(0) {}
00162 VOL_dvector(const VOL_dvector& x) : v(0), sz(0) {
00163 sz = x.sz;
00164 if (sz > 0) {
00165 v = new double[sz];
00166 std::copy(x.v, x.v + sz, v);
00167 }
00168 }
00170 ~VOL_dvector() { delete[] v; }
00171
00173 inline int size() const {return sz;}
00174
00176 inline double& operator[](const int i) {
00177 VOL_TEST_INDEX(i, sz);
00178 return v[i];
00179 }
00180
00182 inline double operator[](const int i) const {
00183 VOL_TEST_INDEX(i, sz);
00184 return v[i];
00185 }
00186
00189 inline void clear() {
00190 delete[] v;
00191 v = 0;
00192 sz = 0;
00193 }
00196 inline void cc(const double gamma, const VOL_dvector& w) {
00197 if (sz != w.sz) {
00198 printf("bad VOL_dvector sizes\n");
00199 abort();
00200 }
00201 double * p_v = v - 1;
00202 const double * p_w = w.v - 1;
00203 const double * const p_e = v + sz;
00204 const double one_gamma = 1.0 - gamma;
00205 while ( ++p_v != p_e ){
00206 *p_v = one_gamma * (*p_v) + gamma * (*++p_w);
00207 }
00208 }
00209
00212 inline void allocate(const int s) {
00213 VOL_TEST_SIZE(s);
00214 delete[] v;
00215 v = new double[sz = s];
00216 }
00217
00219 inline void swap(VOL_dvector& w) {
00220 std::swap(v, w.v);
00221 std::swap(sz, w.sz);
00222 }
00223
00225 VOL_dvector& operator=(const VOL_dvector& w);
00227 VOL_dvector& operator=(const double w);
00228 };
00229
00230
00240 class VOL_ivector {
00241 public:
00243 int* v;
00245 int sz;
00246 public:
00248 VOL_ivector(const int s) {
00249 VOL_TEST_SIZE(s);
00250 v = new int[sz = s];
00251 }
00253 VOL_ivector() : v(0), sz(0) {}
00255 VOL_ivector(const VOL_ivector& x) {
00256 sz = x.sz;
00257 if (sz > 0) {
00258 v = new int[sz];
00259 std::copy(x.v, x.v + sz, v);
00260 }
00261 }
00263 ~VOL_ivector(){
00264 delete [] v;
00265 }
00266
00268 inline int size() const { return sz; }
00270 inline int& operator[](const int i) {
00271 VOL_TEST_INDEX(i, sz);
00272 return v[i];
00273 }
00274
00276 inline int operator[](const int i) const {
00277 VOL_TEST_INDEX(i, sz);
00278 return v[i];
00279 }
00280
00283 inline void clear() {
00284 delete[] v;
00285 v = 0;
00286 sz = 0;
00287 }
00288
00291 inline void allocate(const int s) {
00292 VOL_TEST_SIZE(s);
00293 delete[] v;
00294 v = new int[sz = s];
00295 }
00296
00298 inline void swap(VOL_ivector& w) {
00299 std::swap(v, w.v);
00300 std::swap(sz, w.sz);
00301 }
00302
00304 VOL_ivector& operator=(const VOL_ivector& v);
00306 VOL_ivector& operator=(const int w);
00307 };
00308
00309
00310
00311 class VOL_primal {
00312 public:
00313
00314 double value;
00315
00316 double viol;
00317
00318 VOL_dvector x;
00319
00320 VOL_dvector v;
00321
00322 VOL_primal(const int psize, const int dsize) : x(psize), v(dsize) {}
00323 VOL_primal(const VOL_primal& primal) :
00324 value(primal.value), viol(primal.viol), x(primal.x), v(primal.v) {}
00325 ~VOL_primal() {}
00326 inline VOL_primal& operator=(const VOL_primal& p) {
00327 if (this == &p)
00328 return *this;
00329 value = p.value;
00330 viol = p.viol;
00331 x = p.x;
00332 v = p.v;
00333 return *this;
00334 }
00335
00336
00337
00338
00339
00340 inline void cc(const double alpha, const VOL_primal& p) {
00341 value = alpha * p.value + (1.0 - alpha) * value;
00342 x.cc(alpha, p.x);
00343 v.cc(alpha, p.v);
00344 }
00345
00346 void find_max_viol(const VOL_dvector& dual_lb,
00347 const VOL_dvector& dual_ub);
00348 };
00349
00350
00351
00352 class VOL_dual {
00353 public:
00354
00355 double lcost;
00356
00357 double xrc;
00358
00359
00360 VOL_dvector u;
00361
00362 VOL_dual(const int dsize) : u(dsize) { u = 0.0;}
00363 VOL_dual(const VOL_dual& dual) :
00364 lcost(dual.lcost), xrc(dual.xrc), u(dual.u) {}
00365 ~VOL_dual() {}
00366 inline VOL_dual& operator=(const VOL_dual& p) {
00367 if (this == &p)
00368 return *this;
00369 lcost = p.lcost;
00370 xrc = p.xrc;
00371 u = p.u;
00372 return *this;
00373 }
00374
00375 void step(const double target, const double lambda,
00376 const VOL_dvector& dual_lb, const VOL_dvector& dual_ub,
00377 const VOL_dvector& v);
00378 double ascent(const VOL_dvector& v, const VOL_dvector& last_u) const;
00379 void compute_xrc(const VOL_dvector& pstarx, const VOL_dvector& primalx,
00380 const VOL_dvector& rc);
00381
00382 };
00383
00384
00385
00386
00387
00388 class VOL_swing {
00389 private:
00390 VOL_swing(const VOL_swing&);
00391 VOL_swing& operator=(const VOL_swing&);
00392 public:
00393 enum condition {green, yellow, red} lastswing;
00394 int lastgreeniter, lastyellowiter, lastrediter;
00395 int ngs, nrs, nys;
00396 int rd;
00397
00398 VOL_swing() {
00399 lastgreeniter = lastyellowiter = lastrediter = 0;
00400 ngs = nrs = nys = 0;
00401 }
00402 ~VOL_swing(){}
00403
00404 inline void cond(const VOL_dual& dual,
00405 const double lcost, const double ascent, const int iter) {
00406 double eps = 1.e-3;
00407
00408 if (ascent > 0.0 && lcost > dual.lcost + eps) {
00409 lastswing = green;
00410 lastgreeniter = iter;
00411 ++ngs;
00412 rd = 0;
00413 } else {
00414 if (ascent <= 0 && lcost > dual.lcost) {
00415 lastswing = yellow;
00416 lastyellowiter = iter;
00417 ++nys;
00418 rd = 0;
00419 } else {
00420 lastswing = red;
00421 lastrediter = iter;
00422 ++nrs;
00423 rd = 1;
00424 }
00425 }
00426 }
00427
00428 inline double
00429 lfactor(const VOL_parms& parm, const double lambda, const int iter) {
00430 double lambdafactor = 1.0;
00431 double eps = 5.e-4;
00432 int cons;
00433
00434 switch (lastswing) {
00435 case green:
00436 cons = iter - VolMax(lastyellowiter, lastrediter);
00437 if (parm.printflag & 4)
00438 printf(" G: Consecutive Gs = %3d\n\n", cons);
00439 if (cons >= parm.greentestinvl && lambda < 2.0) {
00440 lastgreeniter = lastyellowiter = lastrediter = iter;
00441 lambdafactor = 2.0;
00442 if (parm.printflag & 2)
00443 printf("\n ---- increasing lamda to %g ----\n\n",
00444 lambda * lambdafactor);
00445 }
00446 break;
00447
00448 case yellow:
00449 cons = iter - VolMax(lastgreeniter, lastrediter);
00450 if (parm.printflag & 4)
00451 printf(" Y: Consecutive Ys = %3d\n\n", cons);
00452 if (cons >= parm.yellowtestinvl) {
00453 lastgreeniter = lastyellowiter = lastrediter = iter;
00454 lambdafactor = 1.1;
00455 if (parm.printflag & 2)
00456 printf("\n **** increasing lamda to %g *****\n\n",
00457 lambda * lambdafactor);
00458 }
00459 break;
00460
00461 case red:
00462 cons = iter - VolMax(lastgreeniter, lastyellowiter);
00463 if (parm.printflag & 4)
00464 printf(" R: Consecutive Rs = %3d\n\n", cons);
00465 if (cons >= parm.redtestinvl && lambda > eps) {
00466 lastgreeniter = lastyellowiter = lastrediter = iter;
00467 lambdafactor = 0.67;
00468 if (parm.printflag & 2)
00469 printf("\n **** decreasing lamda to %g *****\n\n",
00470 lambda * lambdafactor);
00471 }
00472 break;
00473 }
00474 return lambdafactor;
00475 }
00476
00477 inline void
00478 print() {
00479 printf("**** G= %i, Y= %i, R= %i ****\n", ngs, nys, nrs);
00480 ngs = nrs = nys = 0;
00481 }
00482 };
00483
00484
00485
00486
00487 class VOL_alpha_factor {
00488 private:
00489 VOL_alpha_factor(const VOL_alpha_factor&);
00490 VOL_alpha_factor& operator=(const VOL_alpha_factor&);
00491 public:
00492 double lastvalue;
00493
00494 VOL_alpha_factor() {lastvalue = -DBL_MAX;}
00495 ~VOL_alpha_factor() {}
00496
00497 inline double factor(const VOL_parms& parm, const double lcost,
00498 const double alpha) {
00499 if (alpha < parm.alphamin)
00500 return 1.0;
00501 register const double ll = VolAbs(lcost);
00502 const double x = ll > 10 ? (lcost-lastvalue)/ll : (lcost-lastvalue);
00503 lastvalue = lcost;
00504 return (x <= 0.01) ? parm.alphafactor : 1.0;
00505 }
00506 };
00507
00508
00509
00510
00511
00512
00513 class VOL_vh {
00514 private:
00515 VOL_vh(const VOL_vh&);
00516 VOL_vh& operator=(const VOL_vh&);
00517 public:
00518 double hh;
00519 double norm;
00520 double vh;
00521 double asc;
00522
00523 VOL_vh(const double alpha,
00524 const VOL_dvector& dual_lb, const VOL_dvector& dual_ub,
00525 const VOL_dvector& v, const VOL_dvector& vstar,
00526 const VOL_dvector& u);
00527 ~VOL_vh(){}
00528 };
00529
00530
00531
00532
00533
00534
00535
00536 class VOL_indc {
00537 private:
00538 VOL_indc(const VOL_indc&);
00539 VOL_indc& operator=(const VOL_indc&);
00540 public:
00541 double v2;
00542 double vu;
00543 double vabs;
00544 double asc;
00545
00546 public:
00547 VOL_indc(const VOL_dvector& dual_lb, const VOL_dvector& dual_ub,
00548 const VOL_primal& primal, const VOL_primal& pstar,
00549 const VOL_dual& dual);
00550 ~VOL_indc() {}
00551 };
00552
00553
00554
00561 class VOL_user_hooks {
00562 public:
00563 virtual ~VOL_user_hooks() {}
00564 public:
00565
00570 virtual int compute_rc(const VOL_dvector& u, VOL_dvector& rc) = 0;
00571
00580 virtual int solve_subproblem(const VOL_dvector& dual, const VOL_dvector& rc,
00581 double& lcost, VOL_dvector& x, VOL_dvector& v,
00582 double& pcost) = 0;
00589 virtual int heuristics(const VOL_problem& p,
00590 const VOL_dvector& x, double& heur_val) = 0;
00591 };
00592
00593
00594
00603 class VOL_problem {
00604 private:
00605 VOL_problem(const VOL_problem&);
00606 VOL_problem& operator=(const VOL_problem&);
00607 void set_default_parm();
00608
00609 public:
00613 VOL_problem();
00616 VOL_problem(const char *filename);
00618 ~VOL_problem();
00620
00626 int solve(VOL_user_hooks& hooks, const bool use_preset_dual = false);
00628
00629 private:
00633 double alpha_;
00635 double lambda_;
00636
00637
00638 union {
00640 int iter_;
00641 double __pad0;
00642 };
00644
00645 public:
00646
00650 double value;
00652 VOL_dvector dsol;
00654 VOL_dvector psol;
00656 VOL_dvector viol;
00658
00662 VOL_parms parm;
00664 int psize;
00666 int dsize;
00669 VOL_dvector dual_lb;
00672 VOL_dvector dual_ub;
00674
00675 public:
00679 int iter() const { return iter_; }
00681 double alpha() const { return alpha_; }
00683 double lambda() const { return lambda_; }
00685
00686 private:
00690 void read_params(const char* filename);
00691
00693 int initialize(const bool use_preset_dual);
00694
00696 void print_info(const int iter,
00697 const VOL_primal& primal, const VOL_primal& pstar,
00698 const VOL_dual& dual);
00699
00702 double readjust_target(const double oldtarget, const double lcost) const;
00703
00711 double power_heur(const VOL_primal& primal, const VOL_primal& pstar,
00712 const VOL_dual& dual) const;
00714 };
00715
00716 #endif