00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef MTGL_VOLVOLUME_H
00019 #define MTGL_VOLVOLUME_H
00020
00021 #include <cfloat>
00022 #include <algorithm>
00023 #include <cstdio>
00024 #include <cmath>
00025
00026 #ifndef VOL_DEBUG
00027
00028 #define VOL_DEBUG 0
00029 #endif
00030
00031 template <class T> static inline T
00032 VolMax(register const T x, register const T y)
00033 {
00034 return ((x) > (y)) ? (x) : (y);
00035 }
00036
00037 template <class T> static inline T
00038 VolAbs(register const T x)
00039 {
00040 return ((x) > 0) ? (x) : -(x);
00041 }
00042
00043
00044
00045 #if defined(VOL_DEBUG) && (VOL_DEBUG != 0)
00046 #define VOL_TEST_INDEX(i, size) \
00047 { \
00048 if ((i) < 0 || (i) >= (size)) { \
00049 printf("bad VOL_?vector index\n"); \
00050 abort(); \
00051 } \
00052 }
00053 #define VOL_TEST_SIZE(size) \
00054 { \
00055 if (s <= 0) { \
00056 printf("bad VOL_?vector size\n"); \
00057 abort(); \
00058 } \
00059 }
00060 #else
00061 #define VOL_TEST_INDEX(i, size)
00062 #define VOL_TEST_SIZE(size)
00063 #endif
00064
00065
00066
00067 class VOL_dvector;
00068 class VOL_ivector;
00069 class VOL_primal;
00070 class VOL_dual;
00071 class VOL_swing;
00072 class VOL_alpha_factor;
00073 class VOL_vh;
00074 class VOL_indc;
00075 class VOL_user_hooks;
00076 class VOL_problem;
00077
00078
00079
00080
00081
00082
00083 struct VOL_parms {
00084
00085 double lambdainit;
00086
00087 double alphainit;
00088
00089 double alphamin;
00090
00091 double alphafactor;
00092
00093
00094 double ubinit;
00095
00096
00097 double primal_abs_precision;
00098
00099 double gap_abs_precision;
00100
00101 double gap_rel_precision;
00102
00103 double granularity;
00104
00105
00106
00107 double minimum_rel_ascent;
00108
00109 int ascent_first_check;
00110
00111
00112 int ascent_check_invl;
00113
00114
00115 int maxsgriters;
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 int printflag;
00128
00129 int printinvl;
00130
00131 int heurinvl;
00132
00133
00134
00135 int greentestinvl;
00136
00137
00138 int yellowtestinvl;
00139
00140
00141 int redtestinvl;
00142
00143
00144 int alphaint;
00145
00146
00147 char* temp_dualfile;
00148 };
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 class VOL_dvector {
00161 public:
00162
00163 double* v;
00164
00165 int sz;
00166
00167 public:
00168
00169 VOL_dvector(const int s)
00170 {
00171 VOL_TEST_SIZE(s);
00172 v = new double[sz = s];
00173 }
00174
00175 VOL_dvector() : v(0), sz(0) {}
00176
00177 VOL_dvector(const VOL_dvector& x) : v(0), sz(0)
00178 {
00179 sz = x.sz;
00180 if (sz > 0)
00181 {
00182 v = new double[sz];
00183 #pragma mta assert parallel
00184 for (int i = 0; i < sz; i++)
00185 {
00186 v[i] = x.v[i];
00187 }
00188
00189 }
00190 }
00191
00192 ~VOL_dvector()
00193 {
00194 delete[] v;
00195 }
00196
00197
00198 inline int size() const {return sz;}
00199
00200
00201 inline double& operator[](const int i)
00202 {
00203 VOL_TEST_INDEX(i, sz);
00204 return v[i];
00205 }
00206
00207
00208 inline double operator[](const int i) const
00209 {
00210 VOL_TEST_INDEX(i, sz);
00211 return v[i];
00212 }
00213
00214
00215
00216 inline void clear()
00217 {
00218 delete[] v;
00219 v = 0;
00220 sz = 0;
00221 }
00222
00223
00224 inline void cc(const double gamma, const VOL_dvector& w)
00225 {
00226 if (sz != w.sz)
00227 {
00228 printf("bad VOL_dvector sizes\n");
00229 abort();
00230 }
00231 #pragma mta assert parallel
00232 for (int i = 0; i < sz; i++)
00233 {
00234 v[i] = (1 - gamma) * v[i] + gamma * w[i];
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 }
00246
00247
00248
00249 inline void allocate(const int s)
00250 {
00251 VOL_TEST_SIZE(s);
00252 delete[] v;
00253 v = new double[sz = s];
00254 }
00255
00256
00257 inline void swap(VOL_dvector& w)
00258 {
00259 std::swap(v, w.v);
00260 std::swap(sz, w.sz);
00261 }
00262
00263
00264 VOL_dvector& operator=(const VOL_dvector& w);
00265
00266 VOL_dvector& operator=(const double w);
00267 };
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 class VOL_ivector {
00280 public:
00281
00282 int* v;
00283
00284 int sz;
00285 public:
00286
00287 VOL_ivector(const int s)
00288 {
00289 VOL_TEST_SIZE(s);
00290 v = new int[sz = s];
00291 }
00292
00293 VOL_ivector() : v(0), sz(0) {}
00294
00295 VOL_ivector(const VOL_ivector& x)
00296 {
00297 sz = x.sz;
00298 if (sz > 0)
00299 {
00300 v = new int[sz];
00301 #pragma mta assert parallel
00302 for (int i = 0; i < sz; i++)
00303 {
00304 v[i] = x.v[i];
00305 }
00306
00307 }
00308 }
00309
00310 ~VOL_ivector()
00311 {
00312 delete [] v;
00313 }
00314
00315
00316 inline int size() const { return sz; }
00317
00318 inline int& operator[](const int i)
00319 {
00320 VOL_TEST_INDEX(i, sz);
00321 return v[i];
00322 }
00323
00324
00325 inline int operator[](const int i) const
00326 {
00327 VOL_TEST_INDEX(i, sz);
00328 return v[i];
00329 }
00330
00331
00332
00333 inline void clear()
00334 {
00335 delete[] v;
00336 v = 0;
00337 sz = 0;
00338 }
00339
00340
00341
00342 inline void allocate(const int s)
00343 {
00344 VOL_TEST_SIZE(s);
00345 delete[] v;
00346 v = new int[sz = s];
00347 }
00348
00349
00350 inline void swap(VOL_ivector& w)
00351 {
00352 std::swap(v, w.v);
00353 std::swap(sz, w.sz);
00354 }
00355
00356
00357 VOL_ivector& operator=(const VOL_ivector& v);
00358
00359 VOL_ivector& operator=(const int w);
00360 };
00361
00362
00363
00364 class VOL_primal {
00365 public:
00366
00367 double value;
00368
00369 double viol;
00370
00371 VOL_dvector x;
00372
00373 VOL_dvector v;
00374
00375 VOL_primal(const int psize, const int dsize) : x(psize), v(dsize) {}
00376 VOL_primal(const VOL_primal& primal) :
00377 value(primal.value), viol(primal.viol), x(primal.x), v(primal.v) {}
00378 ~VOL_primal() {}
00379 inline VOL_primal& operator=(const VOL_primal& p)
00380 {
00381 if (this == &p) return *this;
00382 value = p.value;
00383 viol = p.viol;
00384 x = p.x;
00385 v = p.v;
00386 return *this;
00387 }
00388
00389
00390
00391
00392
00393 inline void cc(const double alpha, const VOL_primal& p)
00394 {
00395 value = alpha * p.value + (1.0 - alpha) * value;
00396 x.cc(alpha, p.x);
00397 v.cc(alpha, p.v);
00398 }
00399
00400 void find_max_viol(const VOL_dvector& dual_lb,
00401 const VOL_dvector& dual_ub);
00402 };
00403
00404
00405
00406 class VOL_dual {
00407 public:
00408
00409 double lcost;
00410
00411 double xrc;
00412
00413
00414 VOL_dvector u;
00415
00416 VOL_dual(const int dsize) : u(dsize)
00417 {
00418 u = 0.0;
00419 }
00420 VOL_dual(const VOL_dual& dual) :
00421 lcost(dual.lcost), xrc(dual.xrc), u(dual.u) {}
00422 ~VOL_dual() {}
00423 inline VOL_dual& operator=(const VOL_dual& p)
00424 {
00425 if (this == &p) return *this;
00426 lcost = p.lcost;
00427 xrc = p.xrc;
00428 u = p.u;
00429 return *this;
00430 }
00431
00432 void step(const double target, const double lambda,
00433 const VOL_dvector& dual_lb, const VOL_dvector& dual_ub,
00434 const VOL_dvector& v);
00435 double ascent(const VOL_dvector& v, const VOL_dvector& last_u) const;
00436 void compute_xrc(const VOL_dvector& pstarx, const VOL_dvector& primalx,
00437 const VOL_dvector& rc);
00438
00439 };
00440
00441
00442
00443
00444
00445 class VOL_swing {
00446 private:
00447 VOL_swing(const VOL_swing&);
00448 VOL_swing& operator=(const VOL_swing&);
00449 public:
00450 enum condition {green, yellow, red} lastswing;
00451 int lastgreeniter, lastyellowiter, lastrediter;
00452 int ngs, nrs, nys;
00453 int rd;
00454
00455 VOL_swing()
00456 {
00457 lastgreeniter = lastyellowiter = lastrediter = 0;
00458 ngs = nrs = nys = 0;
00459 }
00460 ~VOL_swing(){}
00461
00462 inline void cond(const VOL_dual& dual,
00463 const double lcost, const double ascent, const int iter)
00464 {
00465 double eps = 1.e-3;
00466
00467 if (ascent > 0.0 && lcost > dual.lcost + eps)
00468 {
00469 lastswing = green;
00470 lastgreeniter = iter;
00471 ++ngs;
00472 rd = 0;
00473 }
00474 else
00475 {
00476 if (ascent <= 0 && lcost > dual.lcost)
00477 {
00478 lastswing = yellow;
00479 lastyellowiter = iter;
00480 ++nys;
00481 rd = 0;
00482 }
00483 else
00484 {
00485 lastswing = red;
00486 lastrediter = iter;
00487 ++nrs;
00488 rd = 1;
00489 }
00490 }
00491 }
00492
00493 inline double
00494 lfactor(const VOL_parms& parm, const double lambda, const int iter)
00495 {
00496 double lambdafactor = 1.0;
00497 double eps = 5.e-4;
00498 int cons;
00499
00500 switch (lastswing)
00501 {
00502 case green:
00503 cons = iter - VolMax(lastyellowiter, lastrediter);
00504 if (parm.printflag & 4) printf(" G: Consecutive Gs = %3d\n\n", cons);
00505 if (cons >= parm.greentestinvl && lambda < 2.0)
00506 {
00507 lastgreeniter = lastyellowiter = lastrediter = iter;
00508 lambdafactor = 2.0;
00509 if (parm.printflag & 2)
00510 printf("\n ---- increasing lamda to %g ----\n\n",
00511 lambda * lambdafactor);
00512 }
00513 break;
00514
00515 case yellow:
00516 cons = iter - VolMax(lastgreeniter, lastrediter);
00517 if (parm.printflag & 4) printf(" Y: Consecutive Ys = %3d\n\n", cons);
00518 if (cons >= parm.yellowtestinvl)
00519 {
00520 lastgreeniter = lastyellowiter = lastrediter = iter;
00521 lambdafactor = 1.1;
00522 if (parm.printflag & 2)
00523 printf("\n **** increasing lamda to %g *****\n\n",
00524 lambda * lambdafactor);
00525 }
00526 break;
00527
00528 case red:
00529 cons = iter - VolMax(lastgreeniter, lastyellowiter);
00530 if (parm.printflag & 4) printf(" R: Consecutive Rs = %3d\n\n", cons);
00531 if (cons >= parm.redtestinvl && lambda > eps)
00532 {
00533 lastgreeniter = lastyellowiter = lastrediter = iter;
00534 lambdafactor = 0.67;
00535 if (parm.printflag & 2)
00536 printf("\n **** decreasing lamda to %g *****\n\n",
00537 lambda * lambdafactor);
00538 }
00539 break;
00540 }
00541 return lambdafactor;
00542 }
00543
00544 inline void
00545 print()
00546 {
00547 printf("**** G= %i, Y= %i, R= %i ****\n", ngs, nys, nrs);
00548 ngs = nrs = nys = 0;
00549 }
00550 };
00551
00552
00553
00554
00555 class VOL_alpha_factor {
00556 private:
00557 VOL_alpha_factor(const VOL_alpha_factor&);
00558 VOL_alpha_factor& operator=(const VOL_alpha_factor&);
00559 public:
00560 double lastvalue;
00561
00562 VOL_alpha_factor()
00563 {
00564 lastvalue = -DBL_MAX;
00565 }
00566 ~VOL_alpha_factor() {}
00567
00568 inline double factor(const VOL_parms& parm, const double lcost,
00569 const double alpha)
00570 {
00571 if (alpha < parm.alphamin) return 1.0;
00572 register const double ll = VolAbs(lcost);
00573 const double x = ll > 10 ? (lcost - lastvalue) / ll : (lcost - lastvalue);
00574 lastvalue = lcost;
00575 return (x <= 0.01) ? parm.alphafactor : 1.0;
00576 }
00577 };
00578
00579
00580
00581
00582
00583
00584 class VOL_vh {
00585 private:
00586 VOL_vh(const VOL_vh&);
00587 VOL_vh& operator=(const VOL_vh&);
00588 public:
00589 double hh;
00590 double norm;
00591 double vh;
00592 double asc;
00593
00594 VOL_vh(const double alpha,
00595 const VOL_dvector& dual_lb, const VOL_dvector& dual_ub,
00596 const VOL_dvector& v, const VOL_dvector& vstar,
00597 const VOL_dvector& u);
00598 ~VOL_vh(){}
00599 };
00600
00601
00602
00603
00604
00605
00606
00607 class VOL_indc {
00608 private:
00609 VOL_indc(const VOL_indc&);
00610 VOL_indc& operator=(const VOL_indc&);
00611 public:
00612 double v2;
00613 double vu;
00614 double vabs;
00615 double asc;
00616
00617 public:
00618 VOL_indc(const VOL_dvector& dual_lb, const VOL_dvector& dual_ub,
00619 const VOL_primal& primal, const VOL_primal& pstar,
00620 const VOL_dual& dual);
00621 ~VOL_indc() {}
00622 };
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 class VOL_user_hooks {
00633 public:
00634 virtual ~VOL_user_hooks() {}
00635 public:
00636
00637
00638
00639
00640
00641 virtual int compute_rc(const VOL_dvector& u, VOL_dvector& rc) = 0;
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 virtual int solve_subproblem(const VOL_dvector& dual, const VOL_dvector& rc,
00652 double& lcost, VOL_dvector& x, VOL_dvector& v,
00653 double& pcost) = 0;
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 virtual int heuristics(const VOL_problem& p,
00672 const VOL_dvector& x, double& heur_val, double lb) = 0;
00673
00674
00675
00676
00677
00678 virtual void init_u(VOL_dvector& u) = 0;
00679
00680
00681 };
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 class VOL_problem {
00694 private:
00695 VOL_problem(const VOL_problem&);
00696 VOL_problem& operator=(const VOL_problem&);
00697 void set_default_parm();
00698
00699 public:
00700
00701
00702
00703 VOL_problem();
00704
00705
00706 VOL_problem(const char* filename);
00707
00708 ~VOL_problem();
00709
00710
00711
00712
00713
00714
00715
00716 int solve(VOL_user_hooks& hooks, const bool use_preset_dual = false);
00717
00718
00719
00720
00721
00722
00723
00724 private:
00725
00726
00727
00728 double alpha_;
00729
00730 double lambda_;
00731
00732
00733 union {
00734
00735 int iter_;
00736 double __pad0;
00737 };
00738
00739
00740 public:
00741
00742
00743
00744
00745 double value;
00746
00747 VOL_dvector dsol;
00748
00749 VOL_dvector psol;
00750
00751 VOL_dvector viol;
00752
00753
00754
00755
00756
00757 VOL_parms parm;
00758
00759 int psize;
00760
00761 int dsize;
00762
00763
00764 VOL_dvector dual_lb;
00765
00766
00767 VOL_dvector dual_ub;
00768
00769
00770 VOL_dvector* cur_u;
00771
00772 public:
00773
00774
00775
00776 int iter() const { return iter_; }
00777
00778 double alpha() const { return alpha_; }
00779
00780 double lambda() const { return lambda_; }
00781
00782
00783 private:
00784
00785
00786
00787 void read_params(const char* filename);
00788
00789
00790 int initialize(const bool use_preset_dual);
00791
00792
00793 void print_info(const int iter,
00794 const VOL_primal& primal, const VOL_primal& pstar,
00795 const VOL_dual& dual);
00796
00797
00798
00799 double readjust_target(const double oldtarget, const double lcost) const;
00800
00801
00802
00803
00804
00805
00806
00807
00808 double power_heur(const VOL_primal& primal, const VOL_primal& pstar,
00809 const VOL_dual& dual) const;
00810
00811 };
00812
00813 #endif