MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/util/tree.h
Go to the documentation of this file.
00001 /************************************************************************
00002  * MechSys - Open Library for Mechanical Systems                        *
00003  * Copyright (C) 2005 Dorival M. Pedroso, Raúl D. D. Farfan             *
00004  *                                                                      *
00005  * This program is free software: you can redistribute it and/or modify *
00006  * it under the terms of the GNU General Public License as published by *
00007  * the Free Software Foundation, either version 3 of the License, or    *
00008  * any later version.                                                   *
00009  *                                                                      *
00010  * This program is distributed in the hope that it will be useful,      *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
00013  * GNU General Public License for more details.                         *
00014  *                                                                      *
00015  * You should have received a copy of the GNU General Public License    *
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>  *
00017  ************************************************************************/
00018 
00019 #ifndef MECHSYS_TREE_H
00020 #define MECHSYS_TREE_H
00021 
00022 // STL
00023 #include <stdlib.h> // for calloc
00024 #include <cstdio>
00025 
00026 // iGraph
00027 extern "C"
00028 {
00029     #include <src/igraph.h>
00030 }
00031 
00032 // MechSys
00033 #include <mechsys/util/array.h>
00034 #include <mechsys/util/fatal.h>
00035 #include <mechsys/util/numstreams.h>
00036 
00037 
00038 namespace Util
00039 {
00040 
00041 class Tree
00042 {
00043 public:
00044     // Constructors
00045     Tree (Array<int> const & NodesPairs, bool Directed=false) : _directed(Directed) { _init_graph(NodesPairs,Directed); _init_path(); } 
00046 
00047     // Destructor
00048     ~Tree ();
00049 
00050     // Set methods
00051     void Reset   (Array<int> const & NodesPairs, bool Directed=false); 
00052     void DelEdge (int LeftNodeID, int RightNodeID);                    
00053 
00054     // Get methods
00055     size_t nEdges    () const { return igraph_ecount (&_graph); }             
00056     size_t GetEdge   (int LeftNodeID, int RightNodeID) const;                 
00057     void   GetNodes  (size_t i, int & LeftNodeID, int & RightNodeID) const;   
00058     void   ShortPath (size_t FromNodeID, size_t ToNodeID, Array<int> & Path); 
00059 
00060     // Methods
00061     void GetClusters (Array< Array<int> > & Clusters, bool Strong=true) const;
00062     void WriteDOT    (char const * FileKey) const;
00063 
00064     // Operators
00065     void operator= (Tree const & Other); 
00066 
00067 private:
00068     // Data
00069     bool                _directed;
00070     igraph_vector_t     _edges; 
00071     igraph_t            _graph; 
00072     igraph_vs_t         _anode; 
00073     igraph_es_t         _epair; 
00074     igraph_vector_ptr_t _path;  
00075 
00076     // Methods
00077     void _init_graph (Array<int> const & NodesPairs, bool Directed);
00078     void _init_path  ();
00079 
00080 }; // class Tree
00081 
00082 
00084 
00085 
00086 /* public */
00087 
00088 inline Tree::~Tree()
00089 {
00090     for (int i=0; i<igraph_vector_ptr_size(&_path); ++i)
00091     {
00092         igraph_vector_destroy (static_cast<igraph_vector_t*>(VECTOR(_path)[i]));
00093         free                  (VECTOR(_path)[i]);
00094     }
00095     igraph_vs_destroy         (&_anode);
00096     igraph_es_destroy         (&_epair);
00097     igraph_vector_ptr_destroy (&_path);
00098     igraph_vector_destroy     (&_edges);
00099     igraph_destroy            (&_graph);
00100 }
00101 
00102 inline void Tree::Reset (Array<int> const & NodesPairs, bool Directed)
00103 {
00104     igraph_vector_destroy (&_edges);
00105     igraph_destroy        (&_graph);
00106     _init_graph           (NodesPairs, Directed);
00107 }
00108 
00109 inline void Tree::DelEdge (int LeftNodeID, int RightNodeID)
00110 {
00111     igraph_es_pairs_small (&_epair, IGRAPH_DIRECTED, LeftNodeID, RightNodeID, /*flag*/-1);
00112     igraph_delete_edges   (&_graph, _epair);
00113 }
00114 
00115 inline void Tree::GetNodes (size_t i, int & LeftNodeID, int & RightNodeID) const
00116 {
00117     igraph_integer_t left;
00118     igraph_integer_t right;
00119     igraph_edge (&_graph, i, &left, &right);
00120     LeftNodeID  = left;
00121     RightNodeID = right;
00122 }
00123 
00124 inline size_t Tree::GetEdge (int LeftNodeID, int RightNodeID) const
00125 {
00126     igraph_integer_t eid;
00127     igraph_get_eid (&_graph, &eid, LeftNodeID, RightNodeID, /*directed*/1);
00128     return eid;
00129 }
00130 
00131 inline void Tree::ShortPath (size_t FromNodeID, size_t ToNodeID, Array<int> & Path)
00132 {
00133     igraph_vs_vector_small    (&_anode, ToNodeID, /*flag*/-1);
00134     igraph_get_shortest_paths (&_graph, &_path, FromNodeID, _anode, IGRAPH_ALL);
00135     size_t npaths = igraph_vector_ptr_size(&_path);
00136     if (npaths>1) throw new Fatal("Tree::ShortPath: There are (%d) more than one shortest path",npaths);
00137     size_t path_sz = igraph_vector_size(static_cast<igraph_vector_t*>(VECTOR(_path)[0]));
00138     Path.Resize(path_sz);
00139     for (size_t i=0; i<path_sz; ++i)
00140         Path[i] = VECTOR(*static_cast<igraph_vector_t*>(VECTOR(_path)[0]))[i];
00141 }
00142 
00143 inline void Tree::GetClusters (Array< Array<int> > & Clusters, bool Strong) const
00144 {
00145     igraph_vector_t membership, csize;
00146     igraph_vector_init (&membership, 0);
00147     igraph_vector_init (&csize,      0);
00148     igraph_integer_t no;
00149     if (_directed && Strong) igraph_clusters (&_graph, &membership, &csize, &no, IGRAPH_STRONG);
00150     else                     igraph_clusters (&_graph, &membership, &csize, &no, IGRAPH_WEAK);
00151 
00152     Clusters.Resize (no);
00153     int sz = igraph_vector_size(&membership);
00154     for (int i=0; i<sz; ++i)
00155     {
00156         int cluster_id = VECTOR(membership)[i];
00157         Clusters[cluster_id].Push (i);
00158     }
00159 
00160     //std::cout << "no = " << no << std::endl;
00161     //std::cout << "sz = " << sz << std::endl;
00162 }
00163 
00164 inline void Tree::WriteDOT (char const * FileKey) const
00165 {
00166     String fkey(FileKey);
00167     fkey.append(".dot");
00168     FILE * file = fopen(fkey.CStr(),"w");
00169     if (file!=NULL)
00170     {
00171         igraph_write_graph_dot (&_graph, file);
00172         //igraph_write_graph_graphml (&_graph, file);
00173         fclose(file);
00174     }
00175     else throw new Fatal("Tree::WriteDOT: Could not open file <%s>",fkey.CStr());
00176 }
00177 
00178 // Operators
00179 
00180 inline void Tree::operator= (Tree const & Other)
00181 {
00182     Array<int> nodes_pairs;
00183     nodes_pairs.Resize(Other.nEdges()*2);
00184     size_t k = 0;
00185     for (size_t i=0; i<Other.nEdges(); ++i)
00186     {
00187         int lef, rig;
00188         Other.GetNodes (i, lef, rig);
00189         nodes_pairs[k  ] = lef;
00190         nodes_pairs[k+1] = rig;
00191         k += 2;
00192     }
00193     Reset (nodes_pairs);
00194 }
00195 
00196 
00197 /* private */
00198 
00199 inline void Tree::_init_graph (Array<int> const & NodesPairs, bool Directed)
00200 {
00201     igraph_vector_init (&_edges, NodesPairs.Size());
00202     for (size_t i=0; i<NodesPairs.Size(); ++i)
00203         VECTOR(_edges)[i] = NodesPairs[i];
00204     igraph_create (&_graph, &_edges, /*nVerts=auto*/0, /*Directed*/Directed);
00205 }
00206 
00207 inline void Tree::_init_path ()
00208 {
00209     igraph_vector_ptr_init (&_path, 1);
00210     for (int i=0; i<igraph_vector_ptr_size(&_path); ++i)
00211     {
00212         VECTOR(_path)[i] = calloc (1, sizeof(igraph_vector_t));
00213         igraph_vector_init (static_cast<igraph_vector_t*>(VECTOR(_path)[i]), 0);
00214     }
00215 }
00216 
00217 
00218 /* Output */
00219 
00220 std::ostream & operator<< (std::ostream & os, Util::Tree const & T)
00221 {
00222     for (size_t i=0; i<T.nEdges(); ++i)
00223     {
00224         int lef, rig;
00225         T.GetNodes (i, lef, rig);
00226         os << i << ":(" << lef << ", " << rig << ") ";
00227     }
00228     return os;
00229 }
00230 
00231 
00232 }; // namespace Util
00233 
00234 #endif // MECHSYS_TREE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines