tpl_matgraph.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 
00044 # ifndef TPL_MAT_GRAPH_H
00045 # define TPL_MAT_GRAPH_H
00046 
00047 # include <tpl_graph.H>
00048 # include <dyn_sort_utils.H>
00049 
00050 using namespace Aleph;
00051 
00052 namespace Aleph 
00053 {
00054 
00055       template <typename GT> inline static 
00056   typename GT::Node * get_node(DynArray<typename GT::Node *> nodes, 
00057                                const long &                  i)
00058   {
00059 
00060     if (i >= nodes.size())
00061       throw std::out_of_range("Index of node out of range");
00062 
00063     return nodes.access(i);
00064   }
00065       template <typename GT>
00066   inline static long index_of_node(DynArray<typename GT::Node *> nodes,
00067                                    const long &                  n,
00068                                    typename GT::Node *           p) 
00069   {
00070     return Aleph::binary_search<typename GT::Node*>(nodes, p, 0, n - 1);
00071   }
00072   inline static long index_array(const long & i, const long & j, const long & n) 
00073 
00074   {
00075     if (i >= n or j >= n)
00076       throw std::out_of_range("Matrix index out of range");
00077 
00078     return i + j*n;
00079   }
00080 
00081       template <typename Entry>
00082   inline static Entry * read_matrix(const DynArray<Entry> & mat,
00083                                     const long &            i, 
00084                                     const long &            j, 
00085                                     const long &            n)
00086   {
00087     const long index = index_array(i, j, n);
00088 
00089     if (not mat.exist(index))
00090       return NULL;
00091 
00092     return &const_cast<Entry&>(mat.access(index));
00093   }
00094       template <typename Entry>
00095   inline static void write_matrix(DynArray<Entry> & mat,
00096                                   const long &      i, 
00097                                   const long &      j, 
00098                                   const long &      n, 
00099                                   const Entry &     entry)
00100   {
00101     mat[index_array(i, j, n)] = entry;
00102   }
00103 
00153       template <typename GT>
00154   class Map_Matrix_Graph
00155   {
00156     public:
00158     typedef GT List_Graph_Type;
00159 
00161     typedef typename GT::Node_Type Node_Type;
00162 
00164     typedef typename GT::Arc_Type Arc_Type;
00165 
00167     typedef typename GT::Node Node;
00168 
00170     typedef typename GT::Arc Arc;
00171 
00172   private:
00173 
00174     DynArray<Node*> nodes;
00175     GT * lgraph;
00176     mutable size_t num_nodes;
00177     struct Mat_Entry
00178     {
00179       Arc * arc;
00180 
00181       Mat_Entry(Arc * __arc = NULL) : arc(__arc) { /* empty */ }
00182     };
00183     DynArray<Mat_Entry> mat;
00184 
00185   public:
00186 
00188     Map_Matrix_Graph(GT & g);
00189 
00191     Map_Matrix_Graph(Map_Matrix_Graph & mat);
00193     inline Map_Matrix_Graph & operator = (Map_Matrix_Graph & mat);
00194 
00204     inline Map_Matrix_Graph & operator = (GT & g);
00217     inline Node * operator () (const long & i) const;
00232     inline long operator () (Node * node) const;
00252     inline Arc * operator () (Node * src_node, Node * tgt_node) const;
00268     inline Arc * operator () (const long & i, const long & j) const;  
00270     GT & get_list_graph() { return *lgraph; }
00273     const size_t & get_num_nodes() const { return num_nodes; }
00276     void copy_list_graph(GT & g);
00277   };
00278 
00279       template <class GT>
00280   typename GT::Node * Map_Matrix_Graph<GT>::operator () (const long & i) const
00281   {
00282     return get_node <GT> (nodes, i);
00283   }
00284       template <class GT>
00285   long Map_Matrix_Graph<GT>::operator () (typename GT::Node * node) const
00286   {
00287     return index_of_node <GT> (nodes, num_nodes, node);
00288   }
00289       template <class GT>
00290   typename GT::Arc * Map_Matrix_Graph<GT>::operator () (const long & i, 
00291                                                         const long & j) const
00292   { 
00293     Mat_Entry * mat_entry = read_matrix<Mat_Entry>(mat, i, j, num_nodes); 
00294 
00295     if (mat_entry == NULL)
00296       return NULL;
00297 
00298     return mat_entry->arc;
00299   } 
00300 
00301       template <class GT>
00302   typename GT::Arc * Map_Matrix_Graph<GT>::operator () (Node * src_node, 
00303                                                         Node * tgt_node) const
00304   { 
00305     Mat_Entry * mat_entry = 
00306       read_matrix<Mat_Entry>(mat, 
00307                              index_of_node<GT>(nodes, num_nodes, src_node), 
00308                              index_of_node<GT>(nodes, num_nodes, tgt_node), 
00309                              num_nodes); 
00310 
00311     if (mat_entry == NULL)
00312       return NULL;
00313 
00314     return mat_entry->arc;
00315   } 
00316       template <class GT>
00317   Map_Matrix_Graph<GT>::Map_Matrix_Graph(GT & g) 
00318     : lgraph(&g), num_nodes(g.get_num_nodes())
00319   {
00320     copy_list_graph(g);
00321   }
00322       template <class GT>
00323   Map_Matrix_Graph<GT>::Map_Matrix_Graph
00324       (Map_Matrix_Graph<GT>::Map_Matrix_Graph & mat) 
00325   {
00326     copy_list_graph(*(mat.lgraph));
00327   }
00328 
00329       template <class GT>
00330   Map_Matrix_Graph<GT>& Map_Matrix_Graph<GT>::operator = (Map_Matrix_Graph & mat)
00331   {
00332     if (this == &mat)
00333       return *this;
00334 
00335     copy_list_graph(*(mat.lgraph));
00336 
00337     return *this;
00338   }
00339 
00340       template <class GT>
00341   Map_Matrix_Graph<GT> & Map_Matrix_Graph<GT>::operator = (GT & g)
00342   {
00343     copy_list_graph(g);
00344   }
00345       template <class GT>
00346   void Map_Matrix_Graph<GT>::copy_list_graph(GT & g)
00347   {
00348         // copiar atributos
00349     lgraph    = &g;
00350     num_nodes = g.get_num_nodes();
00351 
00352     nodes.cut(); // limpiar arreglos dinámicos de contenidos anteriores
00353     mat.cut();
00354 
00355          // copiar los nodos de g hacia el arreglo nodes[]
00356     int i = 0;
00357     for (typename GT::Node_Iterator it(g); it.has_current(); it.next(), ++i)
00358       nodes[i] = it.get_current_node();
00359 
00360     quicksort(nodes); // ordenar nodes de modo que se soporte la búsqueda binaria
00361 
00362         // Para todos los arcos de g
00363     for (typename GT::Node_Iterator nit(g); nit.has_current(); nit.next())
00364     {
00365       Node * src = nit.get_current_node();
00366 
00367       const long src_idx = index_of_node<GT>(nodes, num_nodes, src);
00368 
00369           // para cada arco de src escribirlo en la matriz mat
00370       for (typename GT::Node_Arc_Iterator ait(src); ait.has_current(); ait.next())
00371         {
00372           Arc * arc = ait.get_current_arc();
00373 
00374           Node * tgt = g.get_connected_node(arc, src);
00375             
00376           const long tgt_idx = index_of_node<GT>(nodes, num_nodes, tgt);
00377 
00378           write_matrix<Mat_Entry>(mat, src_idx, tgt_idx, num_nodes, arc);
00379         }
00380     }
00381   }
00382 
00412       template <typename GT>
00413   class Matrix_Graph
00414   {
00415 
00416     public:
00417 
00419     typedef GT List_Graph_Type;
00420 
00423     typedef typename GT::Node_Type Node_Type;
00424 
00427     typedef typename GT::Arc_Type Arc_Type;
00428 
00430     typedef typename GT::Node Node;
00431 
00433     typedef typename GT::Arc Arc;
00434 
00435   private:
00436 
00437     DynArray<Node_Type> nodes;
00438     DynArray<Arc_Type>  arcs;
00439     mutable size_t      n;
00440     mutable Arc_Type Null_Value;
00441     void copy(Matrix_Graph & mat)
00442     {
00443 
00444       if (this == &mat)
00445         return;
00446 
00447       n          = mat.n;           // copiar atributos
00448       Null_Value = mat.Null_value;
00449 
00450       nodes.cut();                  // limpiar memoria de arreglos dinámicos
00451       arcs.cut();
00452 
00453       arcs.set_default_initial_value(Null_Value);
00454       
00455       for (int i = 0; i < n; ++i) // recorrer mat[i,j] y copiarla a nodes[], arcs[] 
00456         {
00457           nodes[i] = mat.nodes[i];
00458 
00459           for (int j = 0; j < n; ++j)
00460             {
00461               const long mat_index = index_array(i, j, n);
00462 
00463               if (not arcs.exist(mat_index))
00464                 continue;
00465 
00466               arcs.touch(mat_index) = mat.arcs.access(mat_index);
00467             }
00468         }
00469     }
00470 
00471     void copy(GT & g)
00472     {
00473       n = g.get_num_nodes();
00474 
00475       DynArray<typename GT::Node *> ptr; // arreglo temporal 
00476       
00477       int i = 0;
00478       for (typename GT::Node_Iterator it(g); it.has_current(); it.next(), ++i)
00479         ptr[i] = it.get_current_node();
00480 
00481       quicksort(ptr); // ordenar por si se requiere relación con Map_Matrix_Graph
00482 
00483       arcs.set_default_initial_value(Null_Value); 
00484 
00485       for (i = 0; i < n; ++i) // coloca contenidos de ptr[] en nodes[]
00486         {
00487           typename GT::Node * src = ptr[i];
00488 
00489           nodes[i] = src->get_info();
00490 
00491           for (typename GT::Node_Arc_Iterator it(src); 
00492                it.has_current(); it.next())
00493             {
00494               typename GT::Arc * arc = it.get_current_arc();
00495 
00496               typename GT::Node * tgt = it.get_tgt_node();
00497 
00498               const long j = index_of_node<GT>(ptr, n, tgt);
00499 
00500               const long mat_index = index_array(i, j, n);
00501 
00502               arcs[mat_index] = arc->get_info();
00503             }
00504         }
00505     }
00506 
00507   public:
00508 
00510     const size_t & get_num_nodes() const { return n; }
00512     const Arc_Type & null_value() const { return Null_Value; }
00529     Matrix_Graph(GT & g, const Arc_Type & null) : Null_Value(null)
00530     {
00531       copy(g);
00532     }
00541     Matrix_Graph(Matrix_Graph & mat) 
00542     {
00543       copy(mat);
00544     }
00557     Matrix_Graph & operator = (Matrix_Graph & mat) 
00558     {
00559       copy(mat);
00560 
00561       return *this;
00562     }
00563 
00577     Matrix_Graph & operator = (GT & g) 
00578     {
00579       copy(g);
00580 
00581       return *this;
00582     }
00599     const Arc_Type & operator () (const long & i, const long & j) const
00600     {
00601       const long mat_index = index_array(i, j, n);
00602 
00603       if (not arcs.exist(mat_index)) // ¿Existe entrada?
00604         return Null_Value; // No ==> no hay arco
00605 
00606       return arcs.access(mat_index);      
00607     }
00617     Node_Type & operator () (const long & i) const
00618     {
00619       if (i >= n)
00620         throw std::out_of_range("node index out of range");
00621 
00622       return const_cast<Node_Type &>(nodes.access(i));
00623     }
00624 
00641     Arc_Type & operator () (const long & i, const long & j) 
00642     {
00643       const long mat_index = index_array(i, j, n);
00644 
00645       return arcs.touch(mat_index);
00646     }
00647   };
00648 
00675       template <typename GT, typename __Entry_Type>
00676   class Ady_Mat
00677   {
00678 
00679   public:
00680 
00682     typedef GT List_Graph_Type;
00683 
00685     typedef __Entry_Type Entry_Type;
00686 
00689     typedef typename GT::Node_Type Node_Type;
00690 
00693     typedef typename GT::Arc_Type Arc_Type;
00694 
00696     typedef typename GT::Node Node;
00697 
00699     typedef typename GT::Arc Arc;
00700 
00701   private:
00702 
00703     GT *                 lgraph;
00704     DynArray<Node*>      nodes;
00705     DynArray<Entry_Type> mat;
00706     mutable size_t       num_nodes;
00707     mutable Entry_Type   Null_Value;
00708     void test_same_graph(Ady_Mat & mat)
00709     {
00710       if (lgraph == mat.lgraph)
00711         return;
00712 
00713       throw std::domain_error("mat does not refers the same List_Graph than this");
00714     }
00715 
00716     void copy_nodes(GT & g)
00717     {
00718       lgraph     = &g;
00719       num_nodes  = g.get_num_nodes();
00720 
00721       nodes.cut(); // limpiar memoria por los nodos
00722 
00723           // coloca punteros a nodos en el arreglo nodes[]
00724       int i = 0;
00725       for (typename GT::Node_Iterator it(g); it.has_current(); it.next(), ++i)
00726         nodes[i] = it.get_current_node();
00727 
00728       quicksort(nodes); // ordena para luego hacer búsqueda binaria
00729     }
00730 
00731     Ady_Mat & copy(Ady_Mat & mat)
00732     {
00733       if (this == &mat)
00734         return *this;
00735 
00736       test_same_graph(mat);
00737 
00738       Null_Value = mat.Null_Value;
00739 
00740       copy(mat.lgraph);
00741 
00742       return *this;
00743     }
00744 
00745   public:
00746 
00749     Node * operator () (const long & i) const
00750     {
00751       return Aleph::get_node<GT>(nodes, i);
00752     }
00753 
00756     long operator () (Node * node) const
00757     {
00758       return index_of_node<GT>(nodes, num_nodes, node);
00759     }
00760 
00775     Entry_Type & operator () (const long & i, const long & j)
00776     {
00777       return mat.touch(index_array(i, j, num_nodes));
00778     }
00779 
00794     const Entry_Type & operator () (const long & i, const long & j) const
00795     {
00796       const long index = index_array(i, j, num_nodes);
00797 
00798       if (mat.exist(index))
00799         return mat.access(index);
00800         
00801       return Null_Value;
00802     }
00803 
00821     Entry_Type & operator () (Node * src, Node * tgt) 
00822     {
00823       return (*this)(index_of_node <GT> (nodes, num_nodes, src),
00824                      index_of_node <GT> (nodes, num_nodes, tgt));
00825     }
00826 
00844     const Entry_Type & operator () (Node * src, Node * tgt) const
00845     {
00846       return (*this)(index_of_node <GT> (nodes, num_nodes, src),
00847                      index_of_node <GT> (nodes, num_nodes, tgt));
00848     }
00850     GT & get_list_graph() { return *lgraph; }
00851 
00853     const Entry_Type & null_value() const { return Null_Value; }
00854 
00857     const size_t & get_num_nodes() const { return num_nodes; }
00873     Ady_Mat(GT & g) : lgraph(&g), num_nodes(lgraph->get_num_nodes())
00874     {
00875       copy_nodes(g);
00876     }
00891     Ady_Mat(GT & g, const Entry_Type & null) 
00892       : lgraph(&g), num_nodes(lgraph->get_num_nodes()), Null_Value(null)
00893     {
00894       copy_nodes(*lgraph);
00895     }
00897     void set_null_value(const Entry_Type & null)
00898     {
00899       Null_Value = null;
00900     }
00902     Ady_Mat(Ady_Mat & mat) 
00903     {
00904       copy(mat);
00905     }
00929     template <class Operation> void operate_all_arcs_list_graph();
00956     template <class Operation> void operate_all_arcs_list_graph(void * ptr);
00976     template <class Operation> void operate_all_arcs_matrix();
00977 
00999     template <class Operation> void operate_all_arcs_matrix(void * ptr); 
01000   }; 
01001 
01002       template <class GT, typename __Entry_Type>
01003       template <class Operation>
01004   void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_list_graph()
01005   {
01006         // recorrer todos los nodos del grafo
01007     for (typename GT::Node_Iterator nit(*lgraph); nit.has_current(); nit.next())
01008       {
01009         Node * src = nit.get_current_node();
01010 
01011         const long src_idx = // obtener índice del nodo origen
01012           index_of_node<List_Graph_Type>(nodes, num_nodes, src);
01013 
01014             // recorrer todos los arcos del nodo origen
01015         for (typename GT::Node_Arc_Iterator at(src); at.has_current(); at.next())
01016           {
01017             Arc * arc = at.get_current_arc();
01018           
01019             const long tgt_idx = // obtener índice del nodo destino
01020               index_of_node<List_Graph_Type>(nodes, num_nodes, 
01021                                              arc->get_tgt_node());
01022 
01023             Entry_Type & entry = // asegurar acceso a mat(src_idx, tgt_idx)
01024               mat.touch(index_array(src_idx, tgt_idx, num_nodes));
01025 
01026             Operation () (*this, arc, src_idx, tgt_idx, entry);
01027           }
01028       }
01029   }
01030 
01031       template <class GT, typename __Entry_Type>
01032       template <class Operation>
01033   void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_matrix()
01034   {
01035     const long & n = num_nodes;
01036 
01037     for (int s = 0; s < n; ++s)
01038       {
01039         Node * src_node = get_node<GT>(nodes, s);
01040 
01041         for (int t = 0; t < n; ++t)
01042           {
01043             Node * tgt_node = get_node<GT>(nodes, t);
01044 
01045             Entry_Type & entry = mat.touch(index_array(s, t, num_nodes));
01046 
01047             Operation () (*this, src_node, tgt_node, s, t, entry);
01048           }
01049       }
01050   }
01051       template <class GT, typename __Entry_Type>
01052       template <class Operation>
01053   void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_list_graph(void * ptr)
01054   {
01055         // recorrer todos los nodos del grafo
01056     for (typename GT::Node_Iterator nit(*lgraph); nit.has_current(); nit.next())
01057       {
01058         Node * src = nit.get_current_node();
01059 
01060         const long src_idx = // obtener índice del nodo origen
01061           index_of_node<List_Graph_Type>(nodes, num_nodes, src);
01062 
01063             // recorrer todos los arcos del nodo origen
01064         for (typename GT::Node_Arc_Iterator at(src); at.has_current(); at.next())
01065           {
01066             Arc * arc = at.get_current_arc();
01067 
01068             Node * tgt = lgraph->get_tgt_node(arc);
01069           
01070             const long tgt_idx = // obtener índice del nodo destino
01071               index_of_node<List_Graph_Type>(nodes, num_nodes, tgt);
01072 
01073             Entry_Type & entry = // asegurar acceso a mat(src_idx, tgt_idx)
01074               mat.touch(index_array(src_idx, tgt_idx, num_nodes));
01075 
01076             Operation () (*this, arc, src_idx, tgt_idx, entry, ptr);
01077           }
01078       }
01079   }
01080 
01081       template <class GT, typename __Entry_Type>
01082       template <class Operation>
01083   void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_matrix(void * ptr)
01084   {
01085     const long & n = num_nodes;
01086 
01087     for (int s = 0; s < n; ++s)
01088       {
01089         Node * src_node = get_node<GT>(nodes, s);
01090 
01091         for (int t = 0; t < n; ++t)
01092           {
01093             Node * tgt_node = get_node<GT>(nodes, t);
01094 
01095             Entry_Type & entry = mat.touch(index_array(s, t, num_nodes));
01096 
01097             Operation () (*this, src_node, tgt_node, s, t, entry, ptr);
01098           }
01099       }
01100   }
01101 
01121       template <class GT>
01122   class Bit_Mat_Graph
01123   {
01124 
01125   public:
01126 
01128     typedef GT List_Graph_Type;
01129 
01131     typedef typename GT::Node Node;
01132 
01134     typedef typename GT::Arc Arc;
01135 
01136   private:
01137 
01138     BitArray bit_array;
01139     GT *                         lgraph;
01140     DynArray<typename GT::Node*> nodes;
01141     mutable size_t               n;
01142     void copy_list_graph(GT & g)
01143     {
01144       n = g.get_num_nodes();
01145 
01146       nodes.cut(); // liberar memoria 
01147 
01148           // copiar todos los nodos de g al arreglo nodes[]
01149       int i = 0;
01150       for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
01151         nodes[i++] = static_cast<typename GT::Node*>(it.get_current_node());
01152 
01153       quicksort(nodes); // ordenar para luego hacer búsqueda binaria
01154 
01155       bit_array.resize(n*n); // reajustar dimensión al grafo que se asigna
01156 
01157           // recorrer todos los nodos de g para asignar los arcos en bit_array
01158       for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
01159         {
01160           typename GT::Node * src = it.get_current_node();
01161 
01162           const size_t src_idx = // obtener índice de nodo origen
01163             index_of_node<List_Graph_Type>(nodes, n, src);
01164 
01165           for (typename GT::Node_Arc_Iterator jt(src); jt.has_current(); jt.next())
01166             {
01167               typename GT::Node * tgt = jt.get_tgt_node();
01168 
01169               const size_t tgt_idx = // obtener índice de nodo destino
01170                 index_of_node<List_Graph_Type>(nodes, n, tgt);
01171 
01172               bit_array[index_array(src_idx, tgt_idx,n)] = 1;
01173             }
01174         }
01175     }
01176     struct Proxy
01177     {
01178       BitArray & bit_array;
01179 
01180       const size_t bit_index;
01181 
01182       Proxy(Bit_Mat_Graph & __bitmat, const long & i, const long & j)
01183         : bit_array(__bitmat.bit_array), bit_index(index_array(i, j, __bitmat.n))
01184       {
01185         // empty
01186       }
01187 
01188       Proxy& operator = (const Proxy & proxy)
01189       {
01190         bit_array[bit_index] = proxy.bit_array[proxy.bit_index];
01191       }
01192       
01193       Proxy& operator = (const int & i)
01194       {
01195         bit_array[bit_index] = i;
01196 
01197         return *this;
01198       }
01199 
01200       operator int () const
01201       {
01202         return bit_array[bit_index];
01203       }
01204     };
01205 
01206   public: 
01207 
01209     const size_t & get_num_nodes() const { return n; }
01211     Bit_Mat_Graph() : lgraph(NULL) { /* empty */ }
01212 
01215     Bit_Mat_Graph(GT & g) : lgraph(&g) 
01216     {
01217       copy_list_graph(g);
01218     }
01219 
01221     Bit_Mat_Graph(const Bit_Mat_Graph & bitmat)
01222       : bit_array(bitmat.bit_array), lgraph(bitmat.lgraph), 
01223         nodes(bitmat.nodes), n(bitmat.n)
01224     {
01225       // empty
01226     }
01227 
01229     Bit_Mat_Graph(const size_t & dim) 
01230       : bit_array(dim*dim), lgraph(NULL),
01231         nodes(dim), n(dim)
01232     {
01233      /* empty */ 
01234     }
01237     void set_list_graph(GT & g)
01238     {
01239       lgraph = &g;
01240 
01241       copy_list_graph(g);
01242     }
01243 
01246     GT * get_list_graph() { return lgraph; }
01248     Bit_Mat_Graph & operator = (const Bit_Mat_Graph & bitmat)
01249     {
01250       if (this == &bitmat)
01251         return *this;
01252 
01253       lgraph    = bitmat.lgraph;
01254       bit_array = bitmat.bit_array;
01255 
01256       return *this;
01257     }
01258 
01260     Bit_Mat_Graph & operator = (GT & g)
01261     {
01262       if (&g == lgraph)
01263         return *this;
01264 
01265       copy_list_graph(g);
01266 
01267       return *this;
01268     }
01271     Node * operator () (const long & i) const
01272     {
01273 
01274       if (lgraph == NULL)
01275         throw std::domain_error("There is no a List_Graph object");
01276 
01277       return Aleph::get_node<GT>(nodes, i);
01278     }
01279 
01282     long operator () (Node * node) const
01283     {
01284 
01285       if (lgraph == NULL)
01286         throw std::domain_error("There is no a List_Graph object");
01287 
01288       return index_of_node<GT>(nodes, n, node);
01289     }
01290     Proxy operator () (const long & i, const long & j)
01291     {
01292       return Proxy(*this, i, j);
01293     }
01294 
01295     Proxy operator () (const long & i, const long & j) const
01296     {
01297       return Proxy(const_cast<Bit_Mat_Graph&>(*this), i, j);
01298     }
01299 
01300     Proxy operator () (Node * src_node, Node * tgt_node) 
01301     {
01302       if (lgraph == NULL)
01303         throw std::domain_error("There is no a List_Graph object");
01304 
01305       return Proxy(*this, index_of_node<GT>(nodes, n, src_node), 
01306                    index_of_node<GT>(nodes, n, tgt_node)); 
01307     }
01308 
01309     Proxy operator () (Node * src_node, Node * tgt_node) const
01310     {
01311       if (lgraph == NULL)
01312         throw std::domain_error("There is no a List_Graph object");
01313 
01314       return Proxy(*this, index_of_node<GT>(nodes, n, src_node), 
01315                    index_of_node<GT>(nodes, n, tgt_node)); 
01316     }
01317   };
01318 
01319 } // end namespace Aleph
01320 
01321 # endif // TPL_MAT_GRAPH_H
01322 

Leandro R. León