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

ltiWeightedGraph.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 .......: 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  

Generated on Sat Apr 10 15:26:23 2010 for LTI-Lib by Doxygen 1.6.1