Open
Graph Drawing
Framework

 v.2012.05
 

StressMajorizationSimple.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00042 #ifdef _MSC_VER
00043 #pragma once
00044 #endif
00045 
00046 #ifndef OGDF_STRESS_MAJORIZATION_H
00047 #define OGDF_STRESS_MAJORIZATION_H
00048 
00049 
00050 #include <ogdf/module/LayoutModule.h>
00051 #include <ogdf/basic/Array2D.h>
00052 #include <ogdf/basic/tuples.h>
00053 
00054 
00055 namespace ogdf {
00056 
00057 
00058     class OGDF_EXPORT GraphCopyAttributes;
00059     class OGDF_EXPORT GraphCopy;
00060 
00061 
00064 
00094 class OGDF_EXPORT  StressMajorization : public LayoutModule
00095 {
00096 public:
00097     typedef Tuple2<double, double> dpair;
00098     
00101     enum Scaling {
00102         scInput,           
00103         scUserBoundingBox, 
00104         scScaleFunction,    
00105         scScaleAdaptive    
00106     };
00107     
00108     enum Constraints {
00109         cRadial = 0x0001,   //radial level depending on some centrality measure
00110         cUpward = 0x0002  //level depending on edge direction
00111     };
00112     
00114      StressMajorization() : m_tolerance(0.001),
00115                             m_ltolerance(0.0001),
00116                             m_baseRadius(50.0),
00117                             m_computeMaxIt(true),
00118                             m_K(5.0),
00119                             m_desLength(0.0),
00120                             m_distFactor(2.0),
00121                             m_useLayout(false),
00122                             m_radiiStyle(0),m_radiusFactor(1.1),
00123                             m_radial(false),
00124                             m_gItBaseVal(50),
00125                             m_gItFactor(16),
00126                             m_numSteps(300),
00127                             m_itFac(0.0),
00128                             m_constraints(cUpward),
00129                             m_upward(false)
00130                          {
00131                             m_maxLocalIt = m_maxGlobalIt = maxVal;
00132                          }
00133                          
00135     ~ StressMajorization() {}
00136     
00140     void call(GraphAttributes& GA); 
00144     void call(GraphAttributes& GA, const EdgeArray<double>& eLength); 
00145     
00147     void setIterations(int i) { if (i > 0) m_numSteps = i;}
00148     
00150     void setGraphSizeIterationFactor(double d) {if (DIsGreaterEqual(d, 0.0)) m_itFac = d; }
00151         
00154     void setStopTolerance(double s) {m_tolerance = s;}
00155     
00157     void setUseLayout(bool b) {m_useLayout = b;}
00158     bool useLayout() {return m_useLayout;}
00159     
00163     int maxLocalIterations() const {
00164         return m_maxLocalIt;
00165     }
00166     void setGlobalIterationFactor(int i) {if (i>0) m_gItFactor = i;}
00167     int maxGlobalIterations() const {
00168         return m_maxGlobalIt;
00169     }
00171     void setMaxGlobalIterations(int i) {
00172         if (i>0)
00173             m_maxGlobalIt = i;
00174     }
00176     void setMaxLocalIterations(int i) {
00177         if (i>0)
00178             m_maxLocalIt = i;
00179     }
00181     void computeMaxIterations(bool b)
00182     {
00183         m_computeMaxIt = b;
00184     }
00185     //We could add some noise to the computation
00186     // Returns the current setting of nodes.
00187     //bool noise() const {
00188     //  return m_noise;
00189     //}
00190     // Sets the parameter noise to \a on.
00191     //void noise(bool on) {
00192     //  m_noise = on;
00193     //}
00195     void radial(bool b) {m_radial = b;}
00197     void upward(bool b) {m_upward = b;}
00198     
00199 protected:
00201     void doCall(GraphAttributes& GA, const EdgeArray<double>& eLength, bool simpleBFS);
00202 
00203         //radius on level \a level, (1 denotes first level)
00204         double radius(int level) 
00205         { 
00206             if (m_radiiStyle == 0) return m_baseRadius*level;
00207             else 
00208             {
00209                 double rad = m_baseRadius;
00210                 for (int i = 1; i < level; i++)
00211                 {
00212                     rad*= m_radiusFactor;
00213                 }
00214                 rad+=m_baseRadius;
00215                 return rad;
00216             }
00217         }
00218     
00219     //radius of a specific node, depending on its level
00220     double radius(node v)
00221     {
00222         return m_radii[v];
00223     }
00224     //computes radii for all nodes based on closeness and saves them in \a m_radii
00225     void computeRadii(const Graph& G, const NodeArray< NodeArray<double> >& distances, double diameter);
00226 
00228     bool finished(double maxdelta)
00229     { 
00230         if (m_prevEnergy == startVal) //first step
00231         {
00232           m_prevEnergy = maxdelta;
00233           return false;
00234         }
00235           
00236         double diff = m_prevEnergy - maxdelta; //energy difference
00237         if (diff < 0.0) diff = -diff;
00238 #ifdef OGDF_DEBUG
00239         cout << "Finished(): maxdelta: "<< maxdelta<<" diff/prev: "<<diff / m_prevEnergy<<"\n";
00240 #endif
00241         //check if we want to stop
00242         bool done = ((maxdelta < m_tolerance) || (diff / m_prevEnergy) < m_tolerance);
00243         
00244         m_prevEnergy = maxdelta;   //save previous energy level 
00245         m_prevLEnergy =  startVal; //reset energy level for local node decision
00246         
00247         return done;        
00248     }//finished
00250     bool finishedNode(double deltav)
00251     {
00252         if (m_prevLEnergy == startVal) 
00253         {
00254           m_prevLEnergy = deltav;
00255           return deltav == 0.0;//<m_ltolerance; //locally stable
00256         }
00257 #ifdef OGDF_DEBUG
00258         cout << "Local delta: "<<deltav<<"\n";
00259 #endif
00260         double diff = m_prevLEnergy - deltav;
00261         //check if we want to stop
00262         bool done = (deltav == 0.0 || (diff / m_prevLEnergy) < m_ltolerance);
00263         
00264         m_prevLEnergy = deltav; //save previous energy level
00265         
00266         return done;
00267     }//finishedNode
00270     void adaptLengths(const Graph& G,
00271                   const GraphAttributes& GA,
00272                   const EdgeArray<double>& eLengths, 
00273                   EdgeArray<double>& adaptedLengths);
00275     void shufflePositions(GraphAttributes& GA);
00278     dpair computeParDer(node m, 
00279                     node u,
00280                     GraphAttributes& GA, 
00281                     NodeArray< NodeArray<double> >& ss,
00282                     NodeArray< NodeArray<double> >& dist);
00284     dpair computeParDers(node v, 
00285                      GraphAttributes& GA,
00286                      NodeArray< NodeArray<double> >& ss, 
00287                      NodeArray< NodeArray<double> >& dist);
00289     void initialize(GraphAttributes& GA,
00290                     const EdgeArray<double>& eLength,
00291                     NodeArray< NodeArray<double> >& oLength,
00292                     NodeArray< NodeArray<double> >& weights,
00293                     double & maxDist,
00294                     bool simpleBFS);
00296     void mainStep(GraphAttributes& GA,
00297                 NodeArray< NodeArray<double> >& oLength,
00298                 NodeArray< NodeArray<double> >& weights,
00299                 const double maxDist);
00302     void scale(GraphAttributes& GA);
00303     
00304 private:
00307     double m_tolerance;  
00308     double m_ltolerance;  
00309     int m_maxGlobalIt;   
00310     int m_maxLocalIt;   
00311     bool m_computeMaxIt; 
00312 
00313     double m_K; 
00314     double m_prevEnergy; 
00315     double m_prevLEnergy;
00316     double m_zeroLength; 
00317 
00318     double m_desLength; 
00319     double m_distFactor; //introduces some distance for scaling in case BFS is used
00320     
00321     bool m_useLayout; 
00322     
00323     int m_constraints; //constraints bit pattern
00324     
00325     bool m_radial; 
00326     
00328     bool m_upward;
00329     int m_radiiStyle; 
00330 
00331 
00332 
00333     NodeArray<double> m_radii; 
00334     double m_baseRadius; 
00335     int m_numSteps;     
00336     double m_itFac;     
00337     double m_radiusFactor; 
00338     int m_gItBaseVal; 
00339     int m_gItFactor;  
00340     
00341     
00342     double allpairsspBFS(const Graph& G, NodeArray< NodeArray<double> >& distance, 
00343         NodeArray< NodeArray<double> >& weights);
00344     double allpairssp(const Graph& G, const EdgeArray<double>& eLengths, 
00345         NodeArray< NodeArray<double> >& distance, NodeArray< NodeArray<double> >& weights,
00346         const double threshold = DBL_MAX);
00347         
00348     static const double startVal;
00349     static const double minVal;
00350     static const double desMinLength; 
00351 
00352     static const int maxVal = INT_MAX; 
00353     
00354 };// StressMajorization
00355 
00356 //Things that potentially could be added
00357 //  //! Returns the page ratio.
00358 //    double pageRatio() { return m_pageRatio; }
00359 //
00360 //  //! Sets the page ration to \a x.
00361 //    void pageRatio(double x) { m_pageRatio = x; }
00362 //
00363 //  //! Returns the current scaling method.
00364 //  Scaling scaling() const {
00365 //      return m_scaling;
00366 //  }
00367 //
00368 //  //! Sets the method for scaling the inital layout to \a sc.
00369 //  void scaling(Scaling sc) {
00370 //      m_scaling = sc;
00371 //  }
00372 //
00373 //  //! Returns the current scale function factor.
00374 //  double scaleFunctionFactor() const {
00375 //      return m_scaleFactor;
00376 //  }
00377 //
00378 //  //! Sets the scale function factor to \a f.
00379 //  void scaleFunctionFactor(double f) {
00380 //      m_scaleFactor = f;
00381 //  }
00382 //
00383 //  //! Sets the user bounding box (used if scaling method is scUserBoundingBox).
00384 //  void userBoundingBox(double xmin, double ymin, double xmax, double ymax) {
00385 //      m_bbXmin = xmin;
00386 //      m_bbYmin = ymin;
00387 //      m_bbXmax = xmax;
00388 //      m_bbYmax = ymax;
00389 //  }
00390 
00391 
00392 } // end namespace ogdf
00393 
00394 
00395 #endif