00001 /*---------------------------------------------------------------------+ 00002 | Library QgarLib, graphics analysis and recognition | 00003 | Copyright (C) 2002 Qgar Project, LORIA | 00004 | | 00005 | This library is free software; you can redistribute it and/or | 00006 | modify it under the terms of the GNU Lesser General Public | 00007 | License version 2.1, as published by the Free Software Foundation. | 00008 | | 00009 | This library is distributed in the hope that it will be useful, | 00010 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00011 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 00012 | See the GNU Lesser General Public License for more details. | 00013 | | 00014 | The GNU Lesser General Public License is included in the file | 00015 | LICENSE.LGPL, in the root directory of the Qgar packaging. See | 00016 | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. | 00017 | To receive a paper copy, write to the Free Software Foundation, | 00018 | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 00019 | | 00020 | Contact Project Qgar for any information: | 00021 | LORIA - équipe Qgar | 00022 | B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France | 00023 | email: qgar-contact@loria.fr | 00024 | http://www.qgar.org/ | 00025 *---------------------------------------------------------------------*/ 00026 00027 00028 #ifndef __GENKMEANS_H_INCLUDED__ 00029 #define __GENKMEANS_H_INCLUDED__ 00030 00031 00032 /** 00033 * @file GenKMeans.H 00034 * @brief Header file of classes qgar::GenCluster and qgar::GenKMeans. 00035 * 00036 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00037 * @date July 3, 2001 15:57 00038 * @since Qgar 2.1 00039 */ 00040 00041 00042 // For RCS/CVS use: Do not delete 00043 /* $Id: GenKMeans.H,v 1.26 2005/10/14 17:05:46 masini Exp $ */ 00044 00045 00046 00047 // STD 00048 #include <vector> 00049 // QGAR 00050 #include <qgarlib/QgarErrorAlgorithm.H> 00051 00052 00053 00054 namespace qgar 00055 { 00056 00057 00058 /*---------------------------------------------------------------------* 00059 | | 00060 | C L A S S G E N C L U S T E R | 00061 | | 00062 *---------------------------------------------------------------------*/ 00063 00064 /** 00065 * @ingroup TOOL_CLASSIF 00066 * 00067 * @class GenCluster GenKMeans.H 00068 * 00069 * @brief A cluster, as generated by the k-means algorithm implemented 00070 * by class qgar::GenKMeans. 00071 * 00072 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Jan Rendek">Jan Rendek</a> 00073 * @date Apr 2, 2004 08:36 00074 * @since Qgar 2.1.1 00075 */ 00076 template <class T> class GenCluster 00077 { 00078 // ------------------------------------------------------------------- 00079 // T Y P E D E F I N I T I O N S 00080 // ------------------------------------------------------------------- 00081 public: 00082 00083 /** @name Types */ 00084 // ===== 00085 //@{ 00086 00087 /** 00088 * @brief Type of the cluster elements. 00089 */ 00090 typedef T value_type; 00091 00092 /** 00093 * @brief Reference to qgar::GenCluster::value_type. 00094 */ 00095 typedef value_type& reference; 00096 00097 /** 00098 * @brief Constant reference to qgar::GenCluster::value_type. 00099 */ 00100 typedef const value_type& const_reference; 00101 00102 /** 00103 * @brief Pointer to qgar::GenImage::value_type. 00104 */ 00105 typedef value_type* pointer; 00106 00107 /** 00108 * @brief Constant pointer to qgar::GenCluster::value_type. 00109 */ 00110 typedef const value_type* const_pointer; 00111 00112 //@} 00113 00114 // ------------------------------------------------------------------- 00115 // P U B L I C M E M B E R S 00116 // ------------------------------------------------------------------- 00117 public: 00118 00119 /** @name Constructors */ 00120 // ============ 00121 //@{ 00122 00123 /** 00124 * @brief Builds a cluster. 00125 * 00126 * @param elements the elements of the cluster 00127 * @param center the center of the cluster 00128 */ 00129 GenCluster(const std::vector<value_type>& elements, 00130 const_reference center); 00131 00132 /** 00133 * @brief Copy constructor. 00134 * 00135 * @param other the instance to be copied 00136 */ 00137 GenCluster(const GenCluster& other); 00138 00139 //@} 00140 00141 00142 /** @name Operators */ 00143 // ========= 00144 //@{ 00145 00146 /** 00147 * @brief Assignment operator. 00148 * 00149 * @param rhs The rhs part of the assignment 00150 */ 00151 GenCluster& operator=(const GenCluster& rhs); 00152 00153 //@} 00154 00155 00156 /** @name Access */ 00157 // ====== 00158 //@{ 00159 00160 /** 00161 * @brief Retrieves the size of the cluster. 00162 * 00163 * @return The size of the cluster 00164 */ 00165 inline size_t size() const; 00166 00167 /** 00168 * @brief Retrieves the center of the cluster. 00169 * 00170 * @return the center of the cluster 00171 */ 00172 inline const_reference center() const; 00173 00174 /** 00175 * @brief Retrieves the elements composing the cluster. 00176 * 00177 * @return a reference to the vector containing the elements 00178 * of this cluster 00179 */ 00180 inline const std::vector<value_type>& elements() const; 00181 00182 //@} 00183 00184 // ------------------------------------------------------------------- 00185 // P R I V A T E M E M B E R S 00186 // ------------------------------------------------------------------- 00187 private: 00188 00189 /** @name Cluster features */ 00190 // ================ 00191 //@{ 00192 00193 /** 00194 * @brief The center of the cluster. 00195 */ 00196 value_type _center; 00197 00198 /** 00199 * @brief The elements of the cluster. 00200 */ 00201 std::vector<value_type> _elements; 00202 00203 //@} 00204 00205 00206 // ------------------------------------------------------------------- 00207 }; // class GenCluster 00208 00209 00210 00211 00212 00213 /*---------------------------------------------------------------------* 00214 | | 00215 | C L A S S G E N K M E A N S | 00216 | | 00217 *---------------------------------------------------------------------*/ 00218 00219 00220 /** 00221 * @ingroup TOOL_CLASSIF 00222 * 00223 * @class GenKMeans GenKMeans.H "qgarlib/GenKMeans.H" 00224 * 00225 * @brief Template class for partitioning a list of objects of type 00226 * <b>T</b> into a (given) number of clusters using a k-means algorithm. 00227 * 00228 * @warning The class is not supposed to be derived: The destructor 00229 * (as any other function) is not virtual. 00230 * 00231 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00232 * @date July 3, 2001 15:57 00233 * @since Qgar 2.1 00234 */ 00235 template <class T> class GenKMeans 00236 { 00237 // ------------------------------------------------------------------- 00238 // D E F I N I T I O N S 00239 // ------------------------------------------------------------------- 00240 public: 00241 00242 /** @name Types */ 00243 // ===== 00244 //@{ 00245 00246 /** 00247 * @brief Type of the objects to be partitioned. 00248 */ 00249 typedef T value_type; 00250 00251 /** 00252 * @brief Reference to qgar::GenKMeans::value_type. 00253 */ 00254 typedef value_type& reference; 00255 00256 /** 00257 * @brief Constant reference to qgar::GenKMeans::value_type. 00258 */ 00259 typedef const value_type& const_reference; 00260 00261 /** 00262 * @brief Pointer to qgar::GenKMeans::value_type. 00263 */ 00264 typedef value_type* pointer; 00265 00266 /** 00267 * @brief Constant pointer to qgar::GenKMeans::value_type. 00268 */ 00269 typedef const value_type* const_pointer; 00270 00271 //@} 00272 00273 00274 /** @name Signatures */ 00275 // ========== 00276 //@{ 00277 00278 /** 00279 * @brief Signature of the distance function. 00280 */ 00281 typedef double (*DistanceFunction) (const_reference, const_reference); 00282 00283 //@} 00284 00285 00286 // ------------------------------------------------------------------- 00287 // P U B L I C M E M B E R S 00288 // ------------------------------------------------------------------- 00289 public: 00290 00291 00292 /** @name Constructors */ 00293 // ============ 00294 //@{ 00295 00296 /** 00297 * @brief Construct a partition of clusters using a distance function. 00298 * 00299 * @param anObjVect vector of the objects to be partitioned 00300 * @param aDistFunction distance function <b>f(T*,T*)</b> 00301 * @param aClusterCnt number of resulting clusters (default <b>3</b>) 00302 * 00303 * @throw qgar::QgarErrorAlgorithm 00304 * if an error occurred while creating clusters 00305 */ 00306 GenKMeans(const std::vector<value_type>& anObjVect, 00307 DistanceFunction aDistFunction, 00308 int aClusterCnt = 3) 00309 throw(qgar::QgarErrorAlgorithm); 00310 00311 /** 00312 * @brief Construct a partition of clusters of given centers, 00313 * using a distance function. 00314 * 00315 * @param anObjVect vector of the objects to be partitioned 00316 * @param aDistFunction distance function <b>f(T*,T*)</b> 00317 * @param aCenterVector vector of the initial centers of the clusters 00318 * @param aClusterCnt number of resulting clusters (default <b>3</b>) 00319 * 00320 * @throw qgar::QgarErrorAlgorithm 00321 * if an error occurred while creating clusters 00322 */ 00323 GenKMeans(const std::vector<value_type>& anObjVect, 00324 DistanceFunction aDistFunction, 00325 const std::vector<value_type>& aCenterVector, 00326 int aClusterCnt = 3) 00327 throw(qgar::QgarErrorAlgorithm); 00328 00329 //@} 00330 00331 00332 /** @name Destructor */ 00333 // ========== 00334 //@{ 00335 00336 /** 00337 * @brief Destructor. 00338 * 00339 * It is not virtual as the class is not supposed to be derived. 00340 */ 00341 ~GenKMeans(); 00342 00343 //@} 00344 00345 00346 /** @name Access */ 00347 // ====== 00348 //@{ 00349 00350 /** 00351 * @brief Get number of resulting clusters. 00352 */ 00353 inline int clusterCnt() const; 00354 00355 /** 00356 * @brief Get the vector storing the resulting cluster sizes. 00357 */ 00358 inline const std::vector<int>& clusterSizes() const; 00359 00360 /** 00361 *@brief Get the vector storing the resulting cluster centers. 00362 */ 00363 inline const std::vector<const_pointer>& clusterCenters() const; 00364 00365 /** 00366 * @brief Get the vector storing the elements of the clusters. 00367 * 00368 * Each element of the returned vector represents a cluster. 00369 * Each cluster is itself represented by a vector, storing 00370 * pointers to the elements of the cluster. 00371 */ 00372 inline const std::vector< std::vector<const_pointer> >& 00373 accessClusterElts() const; 00374 00375 /** 00376 * @brief Get a copy of the vector storing the elements 00377 * of the clusters. 00378 * 00379 * Each element of the returned vector represents a cluster. 00380 * Each cluster is itself represented by a vector, storing 00381 * pointers to the elements of the cluster. 00382 */ 00383 inline std::vector< std::vector<const_pointer> > 00384 clusterElts() const; 00385 00386 /** 00387 * @brief Get the vector storing the clusters. 00388 * 00389 * Each element of the returned vector represents a cluster. 00390 * Each cluster is represented by an instance of class 00391 * qgar::GenCluster. 00392 */ 00393 const std::vector< GenCluster<value_type> >& 00394 accessClusters() const; 00395 00396 /** 00397 * @brief Get a copy of the vector storing the clusters. 00398 * 00399 * Each element of the returned vector represents a cluster. 00400 * Each cluster is represented by an instance of class 00401 * qgar::GenCluster. 00402 */ 00403 std::vector< GenCluster<value_type> > clusters() const; 00404 00405 //@} 00406 00407 // ------------------------------------------------------------------- 00408 // P R O T E C T E D M E M B E R S 00409 // ------------------------------------------------------------------- 00410 protected: 00411 00412 /** @name Representation of a cluster */ 00413 // =========================== 00414 //@{ 00415 00416 /** 00417 * @brief Number of clusters. 00418 */ 00419 const int _clusterCnt; 00420 00421 /** 00422 * @brief Vector storing the values of the clusters. 00423 * 00424 * Each element of this vector represents a cluster. 00425 * Each cluster is also represented by a vector, storing the pointers 00426 * to the elements of the cluster. 00427 */ 00428 std::vector< std::vector<const_pointer> > _clusterElts; 00429 00430 /** 00431 * @brief Vector of clusters sizes. 00432 */ 00433 std::vector<int> _clusterSizes; 00434 00435 /** 00436 * @brief Vector of cluster centers. 00437 */ 00438 std::vector<const_pointer> _clusterCenters; 00439 00440 /** 00441 * @brief Vector of objects to be partitioned. 00442 */ 00443 std::vector<const_pointer> _objVect; 00444 00445 /** 00446 * @brief Vector storing the final clusters. 00447 * 00448 * Each element of this vector represents a cluster. 00449 * Each cluster is represented by an instance 00450 * of class qgar::GenCluster. 00451 */ 00452 mutable std::vector< GenCluster<value_type> > _clusters; 00453 00454 /** 00455 * @brief The distance function. 00456 */ 00457 const DistanceFunction _distance; 00458 00459 //@} 00460 00461 // ------------------------------------------------------------------- 00462 // P R I V A T E M E M B E R S 00463 // ------------------------------------------------------------------- 00464 private: 00465 00466 /** @name Auxiliaries */ 00467 // =========== 00468 //@{ 00469 00470 /** 00471 * @brief Initialize cluster centers. 00472 * 00473 * Use a given number of the first objects of the given list of objects. 00474 * 00475 * @exception qgar::QgarErrorAlgorithm 00476 */ 00477 void PRIVATEinitCenters() throw(qgar::QgarErrorAlgorithm); 00478 00479 /** 00480 * @brief Distribute objects into clusters. 00481 */ 00482 void PRIVATEdistributeIntoClusters(); 00483 00484 /** 00485 * @brief Compute new cluster centers. 00486 * 00487 * @param aNewCenterVector vector of resulting cluster centers 00488 * 00489 * @exception qgar::QgarErrorAlgorithm 00490 */ 00491 void PRIVATEgetCenters(std::vector<const_pointer>& aNewCenterVector) 00492 throw(qgar::QgarErrorAlgorithm); 00493 00494 /** 00495 * @brief Loop on constructing clusters until getting stable centers. 00496 */ 00497 void PRIVATEgetClusters(); 00498 00499 /** 00500 * @brief Construct the final clusters in <b>_clusters</b> 00501 * from <b>_clustersElts</b>. 00502 */ 00503 void PRIVATEconsFinalClusters(); 00504 00505 //@} 00506 00507 00508 /** @name Disabled */ 00509 // ======== 00510 //@{ 00511 00512 /** 00513 * @brief Disabled copy constructor. 00514 */ 00515 GenKMeans(const GenKMeans&); 00516 00517 /** 00518 * @brief Disabled assignment operator. 00519 */ 00520 GenKMeans& operator=(const GenKMeans&); 00521 00522 //@} 00523 00524 // --------------------------------------------------------------------- 00525 00526 }; // class GenKmeans 00527 00528 00529 } // namespace qgar 00530 00531 00532 00533 00534 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00535 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00536 // I M P L E M E N T A T I O N 00537 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00538 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00539 00540 00541 #include <qgarlib/GenKMeans.TCC> 00542 00543 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00544 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00545 00546 00547 00548 00549 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 00550 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 00551 // H E L P E R S 00552 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 00553 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 00554 00555 00556 namespace qgar 00557 { 00558 00559 00560 /** @name KMeans helper functions */ 00561 // ======================= 00562 //@{ 00563 00564 /** 00565 * @ingroup GLOB_HELPER 00566 * 00567 * @brief Construct a partition of clusters using a distance function. 00568 * 00569 * @param anObjVect vector of objects to be partitioned 00570 * @param aDistFunction distance function <b>f(const T&, const T&)</b> 00571 * @param aClusterCnt number of resulting clusters (default <b>3</b>) 00572 * 00573 * @throw qgar::QgarErrorAlgorithm 00574 * if an error occurred while creating clusters 00575 */ 00576 template <class T> 00577 std::vector< GenCluster<T> > 00578 qgKMeans(const std::vector<T>& anObjVect, 00579 double (*aDistFunction) (const T&, const T&), 00580 int aClusterCnt = 3) 00581 00582 throw (QgarErrorAlgorithm); 00583 00584 00585 /** 00586 * @ingroup GLOB_HELPER 00587 * 00588 * @brief Construct a partition of clusters of given centers, 00589 * using a distance function. 00590 * 00591 * @param anObjVect vector of objects to be partitioned 00592 * @param aDistFunction distance function <b>f(const T&, const T&)</b> 00593 * @param aCenterVector vector of the initial centers of the clusters 00594 * @param aClusterCnt number of resulting clusters (default <b>3</b>) 00595 * 00596 * @throw qgar::QgarErrorAlgorithm 00597 * if an error occurred while creating clusters 00598 */ 00599 template <class T> 00600 std::vector< GenCluster<T> > 00601 qgKMeans(const std::vector<T>& anObjVect, 00602 double (*aDistFunction) (const T&, const T&), 00603 std::vector<T*>& aCenterVector, 00604 int aClusterCnt = 3) 00605 00606 throw (QgarErrorAlgorithm); 00607 00608 //@} 00609 00610 00611 } // namespace qgar 00612 00613 00614 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 00615 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 00616 00617 00618 #endif /* __GENKMEANS_H_INCLUDED__ */