LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiMinimumSpanningTree.h

00001 /*
00002  * Copyright (C) 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*--------------------------------------------------------------------
00025  * project ....: LTI-Lib: Image Processing and Computer Vision Library
00026  * file .......: ltiMinimumSpanningTree.h
00027  * authors ....: Jens Paustenbach
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 8.4.2003
00030  * revisions ..: $Id: ltiMinimumSpanningTree.h,v 1.8 2006/02/08 12:36:45 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_MINIMUM_SPANNING_TREE_H_
00034 #define _LTI_MINIMUM_SPANNING_TREE_H_
00035 
00036 #include "ltiFunctor.h"
00037 #include "ltiL2Distance.h"
00038 #include "ltiWeightedGraph.h"
00039 
00040 namespace lti {
00041 
00042   /**
00043    * This class computes minimum spanning trees.  There are two ways
00044    * two compute a minimum spanning trees.  Either reduce a given
00045    * weighted graph to its minimum spanning tree or compute the
00046    * minimum spanning tree direct from a given data set.  If you only
00047    * want to reduce a weighted graph, just use the apply methods.  If
00048    * you want to compute the tree from a given data set (keys and
00049    * values), there a three possibilities.
00050    * -# The keys (data points) are elements of a std::vector
00051    *    Then use the apply method of this class.
00052    * -# A matrix where each row represents one key (data point). Use the 
00053    *    class minimumSpanningTreeOfKeyValuetype
00054    * -# A matrix where each element represents one key (data point).
00055    *    In this case use the class minimumSpanningTreeOfKeytype
00056    *
00057    * A minimum spanning tree has the following template types:
00058    * - \a K: the key used for building the MST
00059    * - \a V: the value or data contained in each node of the tree
00060    *   default is int for an id.
00061    * - \a Distantor: policy class for the calculation of the distance
00062    *   between two keys in the tree (see below). Default is the square
00063    *   of the L2 distance lti::l2SquareDistantor.
00064    *
00065    * The Distantor must implement the operator() which takes two
00066    * arguments of type K and calculates their distance. It must define
00067    * a type Distantor::distance_type which is also the return type of
00068    * the operator. See lti::l2SquareDistantor for an example.
00069    */
00070   template <class K, class V=int, class Distantor=l2SquareDistantor<K> >
00071   class minimumSpanningTree : public functor {
00072   public:
00073 
00074     /**
00075      * return type of a call to the distantor, Distantor::distance_type
00076      */
00077     typedef typename Distantor::distance_type distance_type;
00078 
00079     /**
00080      * the parameters for the class minimumSpanningTree
00081      */
00082     class parameters : public functor::parameters {
00083     public:
00084       /**
00085        * default constructor
00086        */
00087       parameters() : functor::parameters() {
00088         
00089         nbNeighbors = 7;
00090         useCompleteGraph = false;
00091       }
00092 
00093       /**
00094        * copy constructor
00095        * @param other the parameters object to be copied
00096        */
00097       parameters(const parameters& other) : functor::parameters() {
00098         copy(other);
00099       }
00100 
00101       /**
00102        * destructor
00103        */
00104       ~parameters() {
00105       }
00106 
00107       /**
00108        * returns name of this type
00109        */
00110       const char* getTypeName() const {
00111         return "minimumSpanningTree<K,V,Distantor>::parameters";
00112       }
00113 
00114       /**
00115        * copy the contents of a parameters object
00116        * @param other the parameters object to be copied
00117        * @return a reference to this parameters object
00118        */
00119       parameters& copy(const parameters& other) {
00120 # ifndef _LTI_MSC_6
00121         // MS Visual C++ 6 is not able to compile this...
00122         functor::parameters::copy(other);
00123 # else
00124         // ...so we have to use this workaround.
00125         // Conditional on that, copy may not be virtual.
00126         functor::parameters& (functor::parameters::* p_copy)
00127           (const functor::parameters&) =
00128           functor::parameters::copy;
00129         (this->*p_copy)(other);
00130 # endif
00131 
00132         nbNeighbors = other.nbNeighbors;
00133         useCompleteGraph = other.useCompleteGraph;
00134 
00135         return *this;
00136       }
00137 
00138       /**
00139        * copy the contents of a parameters object
00140        * @param other the parameters object to be copied
00141        * @return a reference to this parameters object
00142        */
00143       parameters& operator=(const parameters& other) {
00144         return copy(other);
00145       }
00146 
00147       /**
00148        * returns a pointer to a clone of the parameters
00149        */
00150       virtual functor::parameters* clone() const {
00151         return new parameters(*this);
00152       }
00153 
00154 #     ifndef _LTI_MSC_6
00155       /**
00156        * write the parameters in the given ioHandler
00157        * @param handler the ioHandler to be used
00158        * @param complete if true (the default) the enclosing begin/end will
00159        *        be also written, otherwise only the data block will be written.
00160        * @return true if write was successful
00161        */
00162       virtual bool write(ioHandler& handler,const bool complete=true) const
00163 #     else
00164         /**
00165          * this function is required by MSVC only, as a workaround for a
00166          * very awful bug, which exists since MSVC V.4.0, and still by
00167          * V.6.0 with all bugfixes (so called "service packs") remains
00168          * there...  This method is also public due to another bug, so please
00169          * NEVER EVER call this method directly: use write() instead
00170          */
00171         bool writeMS(ioHandler& handler,const bool complete=true) const
00172 #     endif
00173       {
00174         bool b = true;
00175         if (complete) {
00176           b = handler.writeBegin();
00177         }
00178 
00179         if (b) {
00180       
00181           lti::write(handler,"nbNeighbors",nbNeighbors);
00182           lti::write(handler,"useCompleteGraph",useCompleteGraph);
00183         }
00184 
00185 # ifndef _LTI_MSC_6
00186         // This is the standard C++ code, which MS Visual C++ 6 is not able to
00187         // compile...
00188         b = b && functor::parameters::write(handler,false);
00189 # else
00190         bool (functor::parameters::* p_writeMS)(ioHandler&,const bool) const =
00191           functor::parameters::writeMS;
00192         b = b && (this->*p_writeMS)(handler,false);
00193 # endif
00194 
00195         if (complete) {
00196           b = b && handler.writeEnd();
00197         }
00198 
00199         return b;
00200       }
00201 
00202 #     ifdef _LTI_MSC_6
00203       /**
00204        * write the parameters in the given ioHandler
00205        * @param handler the ioHandler to be used
00206        * @param complete if true (the default) the enclosing begin/end will
00207        *        be also written, otherwise only the data block will be written.
00208        * @return true if write was successful
00209        */
00210       bool write(ioHandler& handler,
00211                  const bool complete=true) const {
00212         // ...we need this workaround to cope with another really
00213         // awful MSVC bug.
00214         return writeMS(handler,complete);
00215       }
00216 #     endif
00217 
00218 #     ifndef _LTI_MSC_6
00219       /**
00220        * read the parameters from the given ioHandler
00221        * @param handler the ioHandler to be used
00222        * @param complete if true (the default) the enclosing begin/end will
00223        *        be also written, otherwise only the data block will be written.
00224        * @return true if write was successful
00225        */
00226       virtual bool read(ioHandler& handler,const bool complete=true)
00227 #     else
00228         /**
00229          * this function is required by MSVC only, as a workaround for a
00230          * very awful bug, which exists since MSVC V.4.0, and still by
00231          * V.6.0 with all bugfixes (so called "service packs") remains
00232          * there...  This method is also public due to another bug, so please
00233          * NEVER EVER call this method directly: use read() instead
00234          */
00235         bool readMS(ioHandler& handler,const bool complete=true)
00236 #     endif
00237       {
00238         bool b = true;
00239         if (complete) {
00240           b = handler.readBegin();
00241         }
00242 
00243         if (b) {
00244       
00245           lti::read(handler,"nbNeighbors",nbNeighbors);
00246           lti::read(handler,"useCompleteGraph",useCompleteGraph);
00247         }
00248 
00249 # ifndef _LTI_MSC_6
00250         // This is the standard C++ code, which MS Visual C++ 6 is not able to
00251         // compile...
00252         b = b && functor::parameters::read(handler,false);
00253 # else
00254         bool (functor::parameters::* p_readMS)(ioHandler&,const bool) =
00255           functor::parameters::readMS;
00256         b = b && (this->*p_readMS)(handler,false);
00257 # endif
00258 
00259         if (complete) {
00260           b = b && handler.readEnd();
00261         }
00262 
00263         return b;
00264       }
00265 
00266       // ------------------------------------------------
00267       // the parameters
00268       // ------------------------------------------------
00269 
00270       /**
00271        * The number of neighboring points each point is connected with,
00272        * before minimization
00273        */
00274       int nbNeighbors;
00275 
00276       /** 
00277        * If true, first a complete graph of the input data is computed, 
00278        * for searching the minimum spanning tree. If false an approximation 
00279        * is used of the complete graph is used. In most cases this approxiation
00280        * leads to the correct minimum spanning tree.
00281        * default is false.
00282        */
00283       bool useCompleteGraph;
00284 
00285     };
00286 
00287     /**
00288      * default constructor
00289      */
00290     minimumSpanningTree();
00291 
00292     /**
00293      * Construct a functor using the given parameters
00294      */
00295     minimumSpanningTree(const parameters& par);
00296 
00297     /**
00298      * copy constructor
00299      * @param other the object to be copied
00300      */
00301     minimumSpanningTree(const minimumSpanningTree& other);
00302 
00303     /**
00304      * destructor
00305      */
00306     virtual ~minimumSpanningTree();
00307 
00308     /**
00309      * returns the name of this type ("minimumSpanningTree")
00310      */
00311     virtual const char* getTypeName() const;
00312 
00313     /**
00314      * Computes the minimum spanning tree from the given data. The resulting
00315      * tree is returned in this graph.
00316      */
00317     virtual bool apply(const std::vector<K>& src,
00318                        const std::vector<V>& datas,
00319                        weightedGraph<K,V,distance_type>& graph) const;
00320 
00321     /**
00322      * Computes the minimum spanning tree from the given Graph. The resulting
00323      * tree is returned in graph dest.
00324      */
00325     virtual bool apply(
00326                        const weightedGraph<K,V,distance_type>& src,
00327                        weightedGraph<K,V,distance_type>& dest) const;
00328 
00329     /**
00330      * Computes the minimum spanning tree from the given Graph. The resulting
00331      * tree is returned in this graph.
00332      */
00333     virtual bool apply(weightedGraph<K,V,distance_type>& srcDest) const;
00334 
00335     /**
00336      * copy data of "other" functor.
00337      * @param other the functor to be copied
00338      * @return a reference to this functor object
00339      */
00340     minimumSpanningTree& copy(const minimumSpanningTree& other);
00341 
00342     /**
00343      * alias for copy member
00344      * @param other the functor to be copied
00345      * @return a reference to this functor object
00346      */
00347     minimumSpanningTree& operator=(const minimumSpanningTree& other);
00348 
00349     /**
00350      * returns a pointer to a clone of this functor.
00351      */
00352     virtual functor* clone() const;
00353 
00354     /**
00355      * returns used parameters
00356      */
00357     const parameters& getParameters() const;
00358 
00359   protected:
00360 
00361     /**
00362      * The value type of the key type.
00363      */
00364     typedef typename K::value_type key_value_type;
00365 
00366     /**
00367      * the type of a node of the weightedGraph used in the MST
00368      */
00369     typedef typename weightedGraph<K,V,distance_type>::node node_type;
00370 
00371     /**
00372      * Distantor
00373      */
00374     Distantor distantor;
00375 
00376     /**
00377      * Builds up a graph that can be used for computing the minimum spanning
00378      * tree. This graph is not complete. But in most cases the edges that 
00379      * this graph contains, are all edges that are needed for finding the 
00380      * correct minimum spanning tree.
00381      * The advantage of this version is that searching for the minimum 
00382      * spanning tree will be much faster.
00383      * For this tree all points are connected with their neighbors. The 
00384      * number of neighbors it is connected to can be set by the parameter
00385      * nbNeighbors. After that it is guaranteed that the graph is a 
00386      * connected graph.
00387      */
00388     bool buildGraph(const std::vector<K>& src,
00389                     const std::vector<V>& datas,
00390                     weightedGraph<K,V,distance_type>& graph) const;
00391 
00392     /**
00393      * Builds a complete graph of the input data.
00394      */
00395     bool buildCompleteGraph(const std::vector<K>& src,
00396                             const std::vector<V>& datas,
00397                             weightedGraph<K,V,distance_type>& graph) const;
00398 
00399 
00400   };
00401 }
00402 
00403 #include "ltiMinimumSpanningTree_template.h"
00404 
00405 #endif

Generated on Sat Apr 10 15:25:52 2010 for LTI-Lib by Doxygen 1.6.1