• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/programs/MTGL/mtgl/VolVolume.h

00001 /*  _________________________________________________________________________
00002  *
00003  *  MTGL: The MultiThreaded Graph Library
00004  *  Copyright (c) 2008 Sandia Corporation.
00005  *  This software is distributed under the BSD License.
00006  *  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00007  *  the U.S. Government retains certain rights in this software.
00008  *  For more information, see the README file in the top MTGL directory.
00009  *  _________________________________________________________________________
00010  */
00011 
00012 // This code is licensed under the Common Public License
00013 // It originated from COIN-OR
00014 
00015 // Copyright (C) 2000, International Business Machines
00016 // Corporation and others.  All Rights Reserved.
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 // When VOL_DEBUG is 1, we check vector indices
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    This class contains the parameters controlling the Volume Algorithm
00082 */
00083 struct VOL_parms {
00084   /** initial value of lambda */
00085   double lambdainit;
00086   /** initial value of alpha */
00087   double alphainit;
00088   /** minimum value for alpha */
00089   double alphamin;
00090   /** when little progress is being done, we multiply alpha by alphafactor */
00091   double alphafactor;
00092 
00093   /** initial upper bound of the value of an integer solution */
00094   double ubinit;
00095 
00096   /** accept if max abs viol is less than this */
00097   double primal_abs_precision;
00098   /** accept if abs gap is less than this */
00099   double gap_abs_precision;
00100   /** accept if rel gap is less than this */
00101   double gap_rel_precision;
00102   /** terminate if best_ub - lcost < granularity */
00103   double granularity;
00104 
00105   /** terminate if the relative increase in lcost through
00106       <code>ascent_check_invl</code> steps is less than this */
00107   double minimum_rel_ascent;
00108   /** when to check for sufficient relative ascent the first time */
00109   int ascent_first_check;
00110   /** through how many iterations does the relative ascent have to reach a
00111       minimum */
00112   int ascent_check_invl;
00113 
00114   /** maximum number of iterations  */
00115   int maxsgriters;
00116 
00117   /** controls the level of printing.
00118       The flag should the the 'OR'-d value of the following options:
00119       <ul>
00120       <li> 0 - print nothing
00121       <li> 1 - print iteration information
00122       <li> 2 - add lambda information
00123       <li> 4 - add number of Red, Yellow, Green iterations
00124       </ul>
00125       Default: 3
00126   */
00127   int printflag;
00128   /** controls how often do we print */
00129   int printinvl;
00130   /** controls how often we run the primal heuristic */
00131   int heurinvl;
00132 
00133   /** how many consecutive green iterations are allowed before changing
00134       lambda */
00135   int greentestinvl;
00136   /** how many consecutive yellow iterations are allowed before changing
00137       lambda */
00138   int yellowtestinvl;
00139   /** how many consecutive red iterations are allowed before changing
00140       lambda */
00141   int redtestinvl;
00142 
00143   /** number of iterations before we check if alpha should be decreased */
00144   int alphaint;
00145 
00146   /** name of file for saving dual solution */
00147   char* temp_dualfile;
00148 };
00149 
00150 //############################################################################
00151 
00152 /** vector of doubles. It is used for most vector operations.
00153 
00154     Note: If <code>VOL_DEBUG</code> is <code>#defined</code> to be 1 then each
00155     time an entry is accessed in the vector the index of the entry is tested
00156     for nonnegativity and for being less than the size of the vector. It's
00157     good to turn this on while debugging, but in final runs it should be
00158     turned off (beause of the performance hit).
00159 */
00160 class VOL_dvector {
00161 public:
00162   /** The array holding the vector */
00163   double* v;
00164   /** The size of the vector */
00165   int sz;
00166 
00167 public:
00168   /** Construct a vector of size s. The content of the vector is undefined. */
00169   VOL_dvector(const int s)
00170   {
00171     VOL_TEST_SIZE(s);
00172     v = new double[sz = s];
00173   }
00174   /** Default constructor creates a vector of size 0. */
00175   VOL_dvector() : v(0), sz(0) {}
00176   /** Copy constructor makes a replica of x. */
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       //std::copy(x.v, x.v + sz, v);
00189     }
00190   }
00191   /** The destructor deletes the data array. */
00192   ~VOL_dvector()
00193   {
00194     delete[] v;
00195   }
00196 
00197   /** Return the size of the vector. */
00198   inline int size() const {return sz;}
00199 
00200   /** Return a reference to the <code>i</code>-th entry. */
00201   inline double& operator[](const int i)
00202   {
00203     VOL_TEST_INDEX(i, sz);
00204     return v[i];
00205   }
00206 
00207   /** Return the <code>i</code>-th entry. */
00208   inline double operator[](const int i) const
00209   {
00210     VOL_TEST_INDEX(i, sz);
00211     return v[i];
00212   }
00213 
00214   /** Delete the content of the vector and replace it with a vector of length
00215       0. */
00216   inline void clear()
00217   {
00218     delete[] v;
00219     v = 0;
00220     sz = 0;
00221   }
00222   /** Convex combination. Replace the current vector <code>v</code> with
00223       <code>v = (1-gamma) v + gamma w</code>. */
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 /*****  Original; non-MTA friendly
00237       double * p_v = v - 1;
00238       const double * p_w = w.v - 1;
00239       const double * const p_e = v + sz;
00240       const double one_gamma = 1.0 - gamma;
00241       while ( ++p_v != p_e ){
00242          *p_v = one_gamma * (*p_v) + gamma * (*++p_w);
00243       }
00244 *****/
00245   }
00246 
00247   /** delete the current vector and allocate space for a vector of size
00248       <code>s</code>. */
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   /** swaps the vector with <code>w</code>. */
00257   inline void swap(VOL_dvector& w)
00258   {
00259     std::swap(v, w.v);
00260     std::swap(sz, w.sz);
00261   }
00262 
00263   /** Copy <code>w</code> into the vector. */
00264   VOL_dvector& operator=(const VOL_dvector& w);
00265   /** Replace every entry in the vector with <code>w</code>. */
00266   VOL_dvector& operator=(const double w);
00267 };
00268 
00269 //-----------------------------------------------------------------------------
00270 /** vector of ints. It's used to store indices, it has similar
00271     functions as VOL_dvector.
00272 
00273     Note: If <code>VOL_DEBUG</code> is <code>#defined</code> to be 1 then each
00274     time an entry is accessed in the vector the index of the entry is tested
00275     for nonnegativity and for being less than the size of the vector. It's
00276     good to turn this on while debugging, but in final runs it should be
00277     turned off (beause of the performance hit).
00278 */
00279 class VOL_ivector {
00280 public:
00281   /** The array holding the vector. */
00282   int* v;
00283   /** The size of the vector. */
00284   int sz;
00285 public:
00286   /** Construct a vector of size s. The content of the vector is undefined. */
00287   VOL_ivector(const int s)
00288   {
00289     VOL_TEST_SIZE(s);
00290     v = new int[sz = s];
00291   }
00292   /** Default constructor creates a vector of size 0. */
00293   VOL_ivector() : v(0), sz(0) {}
00294   /** Copy constructor makes a replica of x. */
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       //std::copy(x.v, x.v + sz, v);
00307     }
00308   }
00309   /** The destructor deletes the data array. */
00310   ~VOL_ivector()
00311   {
00312     delete [] v;
00313   }
00314 
00315   /** Return the size of the vector. */
00316   inline int size() const { return sz; }
00317   /** Return a reference to the <code>i</code>-th entry. */
00318   inline int& operator[](const int i)
00319   {
00320     VOL_TEST_INDEX(i, sz);
00321     return v[i];
00322   }
00323 
00324   /** Return the <code>i</code>-th entry. */
00325   inline int operator[](const int i) const
00326   {
00327     VOL_TEST_INDEX(i, sz);
00328     return v[i];
00329   }
00330 
00331   /** Delete the content of the vector and replace it with a vector of length
00332       0. */
00333   inline void clear()
00334   {
00335     delete[] v;
00336     v = 0;
00337     sz = 0;
00338   }
00339 
00340   /** delete the current vector and allocate space for a vector of size
00341       <code>s</code>. */
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   /** swaps the vector with <code>w</code>. */
00350   inline void swap(VOL_ivector& w)
00351   {
00352     std::swap(v, w.v);
00353     std::swap(sz, w.sz);
00354   }
00355 
00356   /** Copy <code>w</code> into the vector. */
00357   VOL_ivector& operator=(const VOL_ivector& v);
00358   /** Replace every entry in the vector with <code>w</code>. */
00359   VOL_ivector& operator=(const int w);
00360 };
00361 
00362 //############################################################################
00363 // A class describing a primal solution. This class is used only internally
00364 class VOL_primal {
00365 public:
00366   // objective value of this primal solution
00367   double value;
00368   // the largest of the v[i]'s
00369   double viol;
00370   // primal solution
00371   VOL_dvector x;
00372   // v=b-Ax, for the relaxed constraints
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   // convex combination. data members in this will be overwritten
00390   // convex combination between two primal solutions
00391   // x <-- alpha x + (1 - alpha) p.x
00392   // v <-- alpha v + (1 - alpha) p.v
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   // find maximum of v[i]
00400   void find_max_viol(const VOL_dvector& dual_lb,
00401                      const VOL_dvector& dual_ub);
00402 };
00403 
00404 //-----------------------------------------------------------------------------
00405 // A class describing a dual solution. This class is used only internally
00406 class VOL_dual {
00407 public:
00408   // lagrangian value
00409   double lcost;
00410   // reduced costs * (pstar-primal)
00411   double xrc;
00412   // this information is only printed
00413   // dual vector
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   // dual step
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 /* here we check whether an iteration is green, yellow or red. Also according
00444    to this information we decide whether lambda should be changed */
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 /* alpha should be decreased if after some number of iterations the objective
00554    has increased less that 1% */
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 /* here we compute the norm of the conjugate direction -hh-, the norm of the
00581    subgradient -norm-, the inner product between the subgradient and the
00582    last conjugate direction -vh-, and the inner product between the new
00583    conjugate direction and the subgradient */
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 /* here we compute different parameter to be printed. v2 is the square of
00603    the norm of the subgradient. vu is the inner product between the dual
00604    variables and the subgradient. vabs is the maximum absolute value of
00605    the violations of pstar. asc is the inner product between the conjugate
00606    direction and the subgradient */
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 /** The user hooks should be overridden by the user to provide the
00627     problem specific routines for the volume algorithm. The user
00628     should derive a class ...
00629 
00630     for all hooks: return value of -1 means that volume should quit
00631 */
00632 class VOL_user_hooks {
00633 public:
00634   virtual ~VOL_user_hooks() {}
00635 public:
00636   // for all hooks: return value of -1 means that volume should quit
00637   /** compute reduced costs
00638       @param u (IN) the dual variables
00639       @param rc (OUT) the reduced cost with respect to the dual values
00640   */
00641   virtual int compute_rc(const VOL_dvector& u, VOL_dvector& rc) = 0;
00642 
00643   /** Solve the subproblem for the subgradient step.
00644       @param dual (IN) the dual variables
00645       @param rc (IN) the reduced cost with respect to the dual values
00646       @param lcost (OUT) the lagrangean cost with respect to the dual values
00647       @param x (OUT) the primal result of solving the subproblem
00648       @param v (OUT) b-Ax for the relaxed constraints
00649       @param pcost (OUT) the primal objective value of <code>x</code>
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   //DEPRECATED
00656 /*    virtual int solve_subproblem_with_mask(const VOL_dvector& dual, const VOL_dvector& rc, */
00657 /*                              double& lcost, VOL_dvector& x, VOL_dvector& v, */
00658 /*                              double& pcost, int **load_balance_masks, */
00659 /*                              int *load_balance_totals, */
00660 /*                              int **load_balance_parallelize_flags,     */
00661 /*                              int num_load_balance_masks) = 0; */
00662 
00663 
00664 
00665 /** Starting from the primal vector x, run a heuristic to produce
00666        an integer solution
00667        @param x (IN) the primal vector
00668        @param heur_val (OUT) the value of the integer solution (return
00669        <code>DBL_MAX</code> here if no feas sol was found
00670    */
00671   virtual int heuristics(const VOL_problem& p,
00672                          const VOL_dvector& x, double& heur_val, double lb) = 0;
00673 
00674 /** Starting from a initial set of lagrange multipliers in user memory, load
00675        them into Vol's data structures.
00676        @param u  (OUT) the initial dual vector
00677    */
00678   virtual void init_u(VOL_dvector& u) = 0;
00679 
00680 
00681 };
00682 
00683 //#############################################################################
00684 
00685 /** This class holds every data for the Volume Algorithm and its
00686     <code>solve</code> method must be invoked to solve the problem.
00687 
00688     The INPUT fields must be filled out completely before <code>solve</code>
00689     is invoked. <code>dsol</code> have to be filled out if and only if the
00690     last argument to <code>solve</code> is <code>true</code>.
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   // ############ INPUT fields ########################
00699 public:
00700   /**@name Constructors and destructor */
00701   //@{
00702   /** Default constructor. */
00703   VOL_problem();
00704   /** Create a a <code>VOL_problem</code> object and read in the parameters
00705       from <code>filename</code>. */
00706   VOL_problem(const char* filename);
00707   /** Destruct the object. */
00708   ~VOL_problem();
00709   //@}
00710 
00711   /**@name Method to solve the problem. */
00712   //@{
00713   /** Solve the problem using the <code>hooks</code>. Any information needed
00714       in the hooks must be stored in the structure <code>user_data</code>
00715       points to. */
00716   int solve(VOL_user_hooks& hooks, const bool use_preset_dual = false);
00717   /* int solve_with_mask(VOL_user_hooks& hooks, int **load_balance_masks, int *load_balance_totals,  */
00718 /*                     int **load_balance_parallelize_flags, int num_load_balance_masks, const bool use_preset_dual = false); */
00719 
00720 
00721 
00722   //@}
00723 
00724 private:
00725   /**@name Internal data (may be inquired for) */
00726   //@{
00727   /** value of alpha */
00728   double alpha_;
00729   /** value of lambda */
00730   double lambda_;
00731   // This union is here for padding (so that data members would be
00732   // double-aligned on x86 CPU
00733   union {
00734     /** iteration number */
00735     int iter_;
00736     double __pad0;
00737   };
00738   //@}
00739 
00740 public:
00741 
00742   /**@name External data (containing the result after solve) */
00743   //@{
00744   /** final lagrangian value (OUTPUT) */
00745   double value;
00746   /** final dual solution (INPUT/OUTPUT) */
00747   VOL_dvector dsol;
00748   /** final primal solution (OUTPUT) */
00749   VOL_dvector psol;
00750   /** violations (b-Ax) for the relaxed constraints */
00751   VOL_dvector viol;
00752   //@}
00753 
00754   /**@name External data (may be changed by the user before calling solve) */
00755   //@{
00756   /** The parameters controlling the Volume Algorithm (INPUT) */
00757   VOL_parms parm;
00758   /** length of primal solution (INPUT) */
00759   int psize;
00760   /** length of dual solution (INPUT) */
00761   int dsize;
00762   /** lower bounds for the duals (if 0 length, then filled with -inf) (INPUT)
00763    */
00764   VOL_dvector dual_lb;
00765   /** upper bounds for the duals (if 0 length, then filled with +inf) (INPUT)
00766    */
00767   VOL_dvector dual_ub;
00768   //@}
00769 
00770   VOL_dvector* cur_u;
00771 
00772 public:
00773   /**@name Methods returning final data */
00774   //@{
00775   /** returns the iteration number */
00776   int    iter() const { return iter_; }
00777   /** returns the value of alpha */
00778   double alpha() const { return alpha_; }
00779   /** returns the value of lambda */
00780   double lambda() const { return lambda_; }
00781   //@}
00782 
00783 private:
00784   /**@name Private methods used internally */
00785   //@{
00786   /** Read in the parameters from the file <code>filename</code>. */
00787   void read_params(const char* filename);
00788 
00789   /** initializes duals, bounds for the duals, alpha, lambda */
00790   int initialize(const bool use_preset_dual);
00791 
00792   /** print volume info every parm.printinvl iterations */
00793   void print_info(const int iter,
00794                   const VOL_primal& primal, const VOL_primal& pstar,
00795                   const VOL_dual& dual);
00796 
00797   /** Checks if lcost is close to the target, if so it increases the target.
00798       Close means that we got within 5% of the target. */
00799   double readjust_target(const double oldtarget, const double lcost) const;
00800 
00801   /** Here we decide the value of alpha1 to be used in the convex
00802       combination. The new pstar will be computed as <br>
00803       pstar = alpha1 * pstar + (1 - alpha1) * primal <br>
00804       More details of this are in doc.ps. <br>
00805       IN:  alpha, primal, pstar, dual <br>
00806       @return alpha1
00807   */
00808   double power_heur(const VOL_primal& primal, const VOL_primal& pstar,
00809                     const VOL_dual& dual) const;
00810   //@}
00811 };
00812 
00813 #endif

Generated on Fri Oct 22 2010 11:02:23 for SST by  doxygen 1.7.1