latest version v1.9 - last update 10 Apr 2010 |
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 .......: ltiWeightedGraph.h 00027 * authors ....: Jens Paustenbach 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 25.04.2003 00030 * revisions ..: $Id: ltiWeightedGraph.h,v 1.6 2006/02/07 20:46:55 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_WEIGHTED_GRAPH_H_ 00034 #define _LTI_WEIGHTED_GRAPH_H_ 00035 00036 #include "ltiImage.h" 00037 #include "ltiSTLIoInterface.h" 00038 00039 #include <map> 00040 #include <list> 00041 00042 namespace lti { 00043 /** 00044 * Weighted Graph container class. 00045 * This class allows the representation of weighted undirected graphs. 00046 * This class is implemented as template with tree template arguments. 00047 * The first P is the point type, that describes the position of the node. 00048 * This can be a e.g. a dvector or a rgbPixel. Second parameter is D. 00049 * This is the data type of the data a node contains, and third W is 00050 * the type of the weights of the edges between the nodes. 00051 * 00052 * The following code will build this graph: 00053 * 00054 * \code 00055 * #include "ltiWeightedGraph.h" 00056 * #include "ltiL2Distance.h" 00057 * 00058 * double a[]={ 10,10, 12,12, 11,12, 11,11, 10,11, 00059 * 0, 0, 1, 0, 2, 0, 1, 1, 2, 1, 00060 * 10, 0, 12, 0, 11, 0, 11, 1, 10, 1}; 00061 * 00062 * dmatrix data; 00063 * data.useExternData(15,2,a); // don't copy the data, but use it! 00064 * 00065 * l2Distantor<double> distantor; 00066 * weightedGraph<dvector,int,l2Distantor<double>::distance_type> myGraph; 00067 * 00068 * int i,j; 00069 * for (i=0; i<data.rows(); i++) { 00070 * graph.insertNode(data.getRow(i),i); 00071 * } 00072 * 00073 * for (i=0; i<data.rows(); i++) { 00074 * for (i=i+1; j<data.rows(); j++) { 00075 * graph.insertEdge(i,j,distantor(data.getRow(i),data.getRow(j))); 00076 * } 00077 * } 00078 * \endcode 00079 */ 00080 template<class P, class D=int, class W=double> 00081 class weightedGraph : public mathObject { 00082 public: 00083 00084 /** 00085 * the elements of the graph are instances of this class 00086 */ 00087 class node { 00088 public: 00089 00090 /** 00091 * standard constructor 00092 */ 00093 node() { 00094 data = D(0); 00095 point = P(0); 00096 id=0; 00097 } 00098 00099 /** 00100 * copy constructor 00101 */ 00102 node(const node& other) { copy(other); } 00103 00104 /** 00105 * constructor 00106 */ 00107 node(const P& position, const D& value, const int nb) { 00108 data = value; 00109 point = position; 00110 id = nb; 00111 } 00112 00113 /** 00114 * destructor 00115 */ 00116 ~node() { } 00117 00118 /** 00119 * copy the contents of other into this object 00120 */ 00121 node& copy(const node& other) { 00122 data = other.getData(); 00123 point = other.getPoint(); 00124 id = other.getId(); 00125 return *this; 00126 } 00127 00128 // 00129 // data methods 00130 00131 /** 00132 * sets the data that the node contains 00133 */ 00134 void setData(const D& value) { data=value; } 00135 00136 /** 00137 * returns the data, saved in the node 00138 */ 00139 D& getData() { return data; } 00140 00141 /** 00142 * returns the data, saved in the node 00143 */ 00144 const D& getData() const { return data; } 00145 00146 // 00147 // point methods 00148 00149 /** 00150 * sets the position of the node 00151 */ 00152 void setPoint(const P& pos) { point = pos; } 00153 00154 /** 00155 * returns the data, saved in the node 00156 */ 00157 P& getPoint() { return point; } 00158 00159 /** 00160 * returns the data, saved in the node 00161 */ 00162 const P& getPoint() const { return point; } 00163 00164 00165 /** 00166 * returns the id of this node 00167 */ 00168 int getId() const { return id; } 00169 00170 /** 00171 * connects this node with an other node with the given id 00172 */ 00173 void connect(const int id) { 00174 connections.push_back(id); 00175 } 00176 00177 /** 00178 * disconnects this node with an other node with the given id 00179 */ 00180 void disconnect(const int id) { 00181 connections.remove(id); 00182 } 00183 00184 /** 00185 * disconnects this node from all other nodes. 00186 */ 00187 void disconnect() { 00188 connections.clear(); 00189 } 00190 00191 /** 00192 * returns a list with the ids of all with this connected nodes. 00193 */ 00194 const std::list<int>& getConnections() const { 00195 return connections; 00196 } 00197 00198 /** 00199 * Sets the list with the ids of nodes this node is connected to. 00200 */ 00201 void setConnections(std::list<int>& con) { 00202 connections=con; 00203 } 00204 00205 protected: 00206 00207 /** 00208 * the data that the node contains 00209 */ 00210 P point; 00211 00212 /** 00213 * the data that the node contains 00214 */ 00215 D data; 00216 00217 /** 00218 * list with the ids, of all connected nodes 00219 */ 00220 std::list<int> connections; 00221 00222 /** 00223 * the id of this node 00224 */ 00225 int id; 00226 }; // class node 00227 00228 00229 // 00230 // data types 00231 // 00232 00233 /** 00234 * type of the data in the nodes 00235 */ 00236 typedef D value_type; 00237 00238 /** 00239 * type of the point in the nodes 00240 */ 00241 typedef P point_type; 00242 00243 /** 00244 * type of the weight of the edges 00245 */ 00246 typedef W weight_type; 00247 00248 /** 00249 * An edge is identified with the ids of the nodes it connects. 00250 */ 00251 typedef std::pair<int,int> edge; 00252 00253 00254 00255 // 00256 // constructors 00257 // 00258 00259 /** 00260 * default constructor creates an emppty graph; 00261 */ 00262 weightedGraph(); 00263 00264 /** 00265 * create this graph as a copy of another graph 00266 * @param other the tree to be copied. 00267 */ 00268 weightedGraph(const weightedGraph<P,D,W>& other); 00269 00270 /** 00271 * destructor 00272 */ 00273 virtual ~weightedGraph(); 00274 00275 00276 00277 // 00278 // inherited methods 00279 // 00280 00281 /** 00282 * returns the name of this class: "weightedGraph" 00283 */ 00284 const char* getTypeName() const; 00285 00286 /** 00287 * assigment operator. 00288 * copy the contents of <code>other</code> in this %object. 00289 * @param other the source graph to be copied. 00290 */ 00291 weightedGraph<P,D,W>& copy(const weightedGraph<P,D,W>& other); 00292 00293 00294 /** 00295 * create a clone of this graph 00296 * @return a pointer to a copy of this graph 00297 */ 00298 virtual mathObject* clone() const; 00299 00300 00301 00302 // 00303 // general graph methods 00304 // 00305 00306 /** 00307 * returns true if the graph is empty 00308 */ 00309 bool empty() const; 00310 00311 /** 00312 * Clears the graph. All nodes and edges will be removed 00313 */ 00314 void clear(); 00315 00316 /** 00317 * Clears the Edges of the graph. All nodes will be unconnected 00318 */ 00319 void clearEdges(); 00320 00321 00322 00323 // 00324 // node methods 00325 // 00326 00327 /** 00328 * Inserts a node that contains the given data into the tree 00329 * Returns the ID of the new node. 00330 */ 00331 int insertNode(const D& data,const P& point); 00332 00333 /** 00334 * Inserts a node with the specified id and data in the tree 00335 */ 00336 void insertNode(int id, const D& data, const P& point); 00337 00338 /** 00339 * Removes node with given id. All edges from an to this node will also 00340 * be removed. 00341 */ 00342 bool removeNode(int id); 00343 00344 /** 00345 * Fetch pointer to the specified node. 00346 * Return true, if successful. 00347 */ 00348 bool getNode(int id, node* &nodePtr) const; 00349 00350 /** 00351 * Returns the map with the nodes. As key the id of the node is used. 00352 */ 00353 const std::map<int,node*>& getNodes() const; 00354 00355 00356 00357 // 00358 // high level access methods 00359 // 00360 00361 /** 00362 * Fills the node with id with the given data 00363 */ 00364 void setData(const int id, const D& data); 00365 00366 /** 00367 * Fetch data from the specified node 00368 * Returns false, if node doesn't exist, true otherwise 00369 */ 00370 bool getData(const int id, D& data) const; 00371 00372 /** 00373 * Set position of a single node 00374 */ 00375 void setPoint(const int id, const P& pos); 00376 00377 00378 /** 00379 * Fetch position of the specified node 00380 * Returns false, if node doesn't exist, true otherwise 00381 */ 00382 bool getPoint(const int id, P& pos) const; 00383 00384 00385 /** 00386 * Sets the weight of the edge between node with idA and node with idB. 00387 */ 00388 void setWeight(const int idA, const int idB,const W& weight); 00389 00390 /** 00391 * Returns the weight of the edge between node with idA and node with idB. 00392 */ 00393 W getWeight(const int idA, const int idB) const { 00394 // implementation needs to be inline, due to visual c++ template deficiencies 00395 typename std::map<edge, W>::const_iterator it = 00396 edges.find(edge(idA,idB)); 00397 if (it!=edges.end()) { 00398 return it->second; 00399 } else { 00400 return W(0); 00401 } 00402 }; 00403 00404 00405 00406 // 00407 // edge methods 00408 // 00409 00410 /** 00411 * Inserts an edge between node with idA and node with idB into the tree. 00412 */ 00413 void insertEdge(const int idA,const int idB, const W& weight); 00414 00415 /** 00416 * removes the edge between nodes with ids idA and idB 00417 */ 00418 void removeEdge(const int idA, const int idB); 00419 00420 /** 00421 * check, wether two nodes are adjacent (connected) 00422 */ 00423 bool adjacentNodes(const int idA, const int idB) const { 00424 return (edges.find(edge(idA,idB)) != edges.end()); 00425 } 00426 00427 /** 00428 * Returns the map with the edges of the graph. 00429 */ 00430 const std::map<edge,W> getEdges() const { return edges; } 00431 00432 00433 00434 /** 00435 * write the object in the given ioHandler 00436 */ 00437 virtual bool write(ioHandler& handler,const bool complete=true) const; 00438 00439 /** 00440 * read the object from the given ioHandler 00441 */ 00442 virtual bool read(ioHandler& handler,const bool complete=true); 00443 00444 /** 00445 * 00446 */ 00447 void show(image& canvas); 00448 00449 00450 00451 private: 00452 00453 /** 00454 * map with pointers to all nodes in the graph 00455 */ 00456 std::map<int,node*> nodes; 00457 00458 /** 00459 * map with the ids of the connected nodes and the weight of the edge 00460 */ 00461 std::map<edge,W> edges; 00462 00463 /** 00464 * a counter for the id of the nodes 00465 */ 00466 int nodeCounter; 00467 00468 00469 }; 00470 00471 } 00472 #include "ltiWeightedGraph_template.h" 00473 00474 #endif 00475