tpl_graph.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_GRAPH_H
00045 # define TPL_GRAPH_H
00046 
00047 # include <memory>
00048 # include <bitArray.H>
00049 # include <tpl_dynArray.H>
00050 # include <tpl_sort_utils.H>
00051 # include <tpl_dynMapTree.H>
00052 # include <tpl_dynDlist.H>
00053 # include <tpl_treapRk.H>
00054 
00132 # define NODE_BITS(p)            ((p)->control_bits)
00133 
00137 # define NODE_COUNTER(p)         ((p)->counter)
00138 
00146 # define IS_NODE_VISITED(p, bit) (NODE_BITS(p).get_bit(bit))
00147 
00151 # define NODE_COOKIE(p)          ((p)->cookie) 
00152 
00156 # define ARC_COUNTER(p)          ((p)->counter)
00157 
00161 # define ARC_BITS(p)             ((p)->control_bits)
00162 
00169 # define IS_ARC_VISITED(p, bit)  (ARC_BITS(p).get_bit(bit))
00170 
00174 # define ARC_COOKIE(p)           ((p)->cookie) 
00175 
00176 using namespace Aleph;
00177 
00178 namespace Aleph {
00179 
00180 template <typename Node_Info> class Graph_Node; 
00181 
00182 template <typename Arc_Info> class Graph_Arc; 
00183 
00184 class Arc_Node;
00185 
00186 template <typename GT> class Path;
00187 
00188 template <typename __Graph_Node, typename __Graph_Arc> class List_Graph;
00189 
00190 template <typename __Graph_Node, typename __Graph_Arc> class List_Digraph;
00191 
00192 template <typename GT> class Mat_Graph;
00193 
00194 template <typename MT, typename Entry_Info, typename Copy> class Ady_MaT;
00195 
00196 static const long No_Visited = 0; // nodo o arco no ha sido visitado
00197 
00199 enum Graph_Bits 
00200 {
00201   Depth_First,   
00202   Breadth_First, 
00203   Test_Cycle,    
00204   Is_Acyclique,  
00205   Test_Path,     
00206   Find_Path,     
00207   Kruskal,       
00208   Prim,          
00209   Dijkstra,      
00210   Euler,         
00211   Hamilton,      
00212   Spanning_Tree, 
00213   Build_Subtree, 
00214   Convert_Tree,  
00215   Cut,           
00216   Min,           
00217 
00218   Num_Bits_Graph 
00219 
00220 };
00235 class Bit_Fields
00236 {
00237 
00238 public:
00239 
00240   unsigned int depth_first    : 1; 
00241   unsigned int breadth_first  : 1; 
00242   unsigned int test_cycle     : 1; 
00243   unsigned int is_acyclique   : 1; 
00244   unsigned int test_path      : 1; 
00245   unsigned int find_path      : 1; 
00246   unsigned int kruskal        : 1; 
00247   unsigned int prim           : 1; 
00248   unsigned int dijkstra       : 1; 
00249   unsigned int euler          : 1; 
00250   unsigned int hamilton       : 1; 
00251   unsigned int spanning_tree  : 1; 
00252   unsigned int build_subtree  : 1; 
00253   unsigned int convert_tree   : 1; 
00254   unsigned int cut            : 1; 
00255   unsigned int min            : 1; 
00256 
00258   Bit_Fields() 
00259     : depth_first(0), breadth_first(0), test_cycle(0), find_path(0), 
00260       kruskal(0), prim(0), dijkstra(0), euler(0), hamilton(0), 
00261       spanning_tree(0), build_subtree(0), convert_tree(0), cut(0), min(0)
00262   { /* empty */ }
00263   
00274   bool get_bit(const int & bit) const 
00275 
00276     throw(std::exception, std::out_of_range)
00277 
00278   {
00279     switch (bit)
00280       {
00281       case Aleph::Depth_First:   return depth_first;
00282       // ...
00283 
00284       case Aleph::Breadth_First: return breadth_first;
00285       case Aleph::Test_Cycle:    return test_cycle;
00286       case Aleph::Is_Acyclique:  return is_acyclique;
00287       case Aleph::Test_Path:     return test_path;
00288       case Aleph::Find_Path:     return find_path;
00289       case Aleph::Kruskal:       return kruskal;
00290       case Aleph::Prim:          return prim;
00291       case Aleph::Dijkstra:      return dijkstra;
00292       case Aleph::Euler:         return euler;
00293       case Aleph::Hamilton:      return hamilton;
00294       case Aleph::Spanning_Tree: return spanning_tree;
00295       case Aleph::Build_Subtree: return build_subtree;
00296       case Aleph::Convert_Tree:  return convert_tree;
00297       case Aleph::Cut:           return cut;
00298       case Aleph::Min:           return min;
00299       default:
00300         throw std::out_of_range("bit number out of range");
00301 
00302       }
00303   }
00316   void set_bit(const int & bit, const int & value) 
00317     {
00318 
00319       I(value == 0 or value == 1);
00320 
00321       switch (bit)
00322         {
00323         case Aleph::Depth_First:   depth_first   = value; break;
00324           // ...
00325 
00326         case Aleph::Breadth_First: breadth_first = value; break;
00327         case Aleph::Test_Cycle:    test_cycle    = value; break;
00328         case Aleph::Is_Acyclique:  is_acyclique  = value; break;
00329         case Aleph::Test_Path:     test_path     = value; break;
00330         case Aleph::Find_Path:     find_path     = value; break;
00331         case Aleph::Kruskal:       kruskal       = value; break;
00332         case Aleph::Prim:          prim          = value; break;
00333         case Aleph::Dijkstra:      dijkstra      = value; break;
00334         case Aleph::Euler:         euler         = value; break;
00335         case Aleph::Hamilton:      hamilton      = value; break;
00336         case Aleph::Spanning_Tree: spanning_tree = value; break;
00337         case Aleph::Build_Subtree: build_subtree = value; break;
00338         case Aleph::Convert_Tree:  convert_tree  = value; break;
00339         case Aleph::Cut:           cut           = value; break;
00340         case Aleph::Min:           min           = value; break;
00341         default:
00342           throw std::out_of_range("bit number out of range");
00343 
00344        }
00345     }
00347   void reset(const int & bit) { set_bit(bit, 0); }
00348 
00350   void reset()
00351   {
00352     depth_first   = 0; 
00353     breadth_first = 0; 
00354     test_cycle    = 0; 
00355     is_acyclique  = 0; 
00356     test_path     = 0; 
00357     find_path     = 0; 
00358     kruskal       = 0; 
00359     prim          = 0; 
00360     dijkstra      = 0; 
00361     euler         = 0; 
00362     hamilton      = 0; 
00363     spanning_tree = 0; 
00364     build_subtree = 0; 
00365     convert_tree  = 0;
00366     cut           = 0;
00367     min           = 0;
00368   }
00369 };
00406     template <typename Node_Info> 
00407 class Graph_Node : public Dlink
00408 {
00409 
00410 public:
00411 
00413   typedef Graph_Node Node;
00415   typedef Node_Info Node_Type; 
00416   friend class Arc_Node;
00417   Node_Info  node_info;
00419   Node_Info & get_info() { return node_info;} 
00420   size_t       num_arcs; 
00421 
00430   Graph_Node() : num_arcs(0), counter(No_Visited), cookie(NULL) { /* empty */ }
00431 
00445   Graph_Node(const Node_Info & info) 
00446     : node_info(info), num_arcs(0), counter(No_Visited), cookie(NULL) 
00447   { 
00448     /* empty */ 
00449   }
00450 
00466   Graph_Node(Graph_Node * node) 
00467     : node_info(node->get_info()), num_arcs(0), counter(No_Visited), cookie(NULL)
00468   { 
00469     /* empty */ 
00470   }
00472   Bit_Fields control_bits;
00473   long counter;
00474   void *     cookie; 
00475   Dlink arc_list; 
00476 };
00513     template <typename Arc_Info> 
00514 class Graph_Arc : public Dlink    
00515 {
00516 
00517 public:
00518 
00520   typedef Graph_Arc Arc; 
00522   typedef Arc_Info Arc_Type;
00523   Arc_Info   arc_info;
00525   Bit_Fields control_bits;
00526   long counter;
00527   void *     cookie; 
00528   void *     src_node; // nodo origen
00529   void *     tgt_node; // nodo destino
00530   Arc_Node * src_arc_node; // puntero al Arc_Node del nodo fuente
00531   Arc_Node * tgt_arc_node; // puntero al Arc_Node del nodo destino
00533   Arc_Info & get_info() { return arc_info; }
00534   void * get_connected_node(void * node) 
00535   {
00536     return src_node == node ? tgt_node : src_node;
00537   }
00538 
00539   Graph_Arc() 
00540     : counter(No_Visited), cookie(NULL),
00541       src_node(NULL), tgt_node(NULL), src_arc_node(NULL), tgt_arc_node(NULL)
00542   { 
00543     /* empty */ 
00544   }
00545 
00546   Graph_Arc(const Arc_Info & info) 
00547     : arc_info(info), counter(No_Visited), cookie(NULL),
00548       src_node(NULL), tgt_node(NULL), src_arc_node(NULL), tgt_arc_node(NULL)
00549   { 
00550     /* empty */ 
00551   }
00552   Graph_Arc(void * src, void * tgt, const Arc_Info & data) 
00553     : arc_info(data), counter(No_Visited), cookie(NULL),
00554       src_node(src), tgt_node(tgt), src_arc_node(NULL), tgt_arc_node(NULL)
00555   { 
00556     // empty
00557   }
00558 };
00559 struct Arc_Node : public Dlink
00560 {
00561   void * arc;
00562   Arc_Node() : arc(NULL) { /* empty */ }
00563   Arc_Node(void * __arc) : arc(__arc) { /* empty */ }
00564 };
00581     template <typename GT> 
00582 class Path
00583 {
00584   
00585   public:
00586 
00588     typedef typename GT::Node_Type Node_Type;
00590     typedef typename GT::Arc_Type Arc_Type;
00591   GT *                g;
00592 
00593   private:
00594 
00595     typedef typename GT::Node Node;
00596     typedef typename GT::Arc Arc;
00597   struct Path_Desc
00598   {
00599     Node * node; // nodo origen
00600     Arc *  arc;  // arco adyacente
00601 
00602     Path_Desc(Node * _node = NULL, Arc * _arc = NULL) : node(_node), arc(_arc) {}
00603   };
00604   DynDlist<Path_Desc> list;
00606   GT & get_graph() { return *g; }
00607 
00608   public:
00609 
00611   bool inside_graph(GT & gr) const { return g == &gr; }
00616   Path(GT & _g) : g(&_g) { /* empty */ }
00618   Path() : g(NULL) { /* empty */ }
00625   void init(Node * start_node)
00626   {
00627     list.append(Path_Desc(start_node));
00628   }
00636   Path(GT & _g, Node * start_node) : g(&_g)
00637   {
00638     init(start_node);
00639   }
00651   void set_graph(GT & __g, Node * start_node = NULL)
00652   {
00653     clear_path();
00654 
00655     g = &__g;
00656 
00657     if (start_node == NULL)
00658       return;
00659 
00660     init(start_node);
00661   }
00663   const long & size() const { return list.size(); }
00665   bool is_empty() const { return list.is_empty(); }
00667   void clear_path()
00668   {
00669     while (not list.is_empty())
00670       list.remove_first();
00671   }
00673   Path(const Path & path) : g(path.g), list(path.list) { /* empty */ }
00674 
00676   Path & operator = (const Path & path)
00677   {
00678 
00679     if (this == &path)
00680       return *this;
00681 
00682     clear_path();
00683 
00684     g = path.g;
00685     list = path.list;
00686 
00687     return *this;
00688   }
00716   void append(Arc * arc)
00717   {
00718 
00719     if (list.is_empty())
00720       throw std::domain_error("path is empty");
00721 
00722     Path_Desc & last_path_desc = list.get_last(); // ultimo elemento de list
00723 
00724     if (not g->node_belong_to_arc(arc, last_path_desc.node))
00725       throw std::invalid_argument("last node in path does "
00726                                   "not incide on arc");
00727 
00728     last_path_desc.arc = arc;
00729 
00730     list.append(Path_Desc(g->get_connected_node(arc, last_path_desc.node)));
00731   }
00759   void append(Node * node)
00760   {
00761     if (list.is_empty())
00762       {
00763         init(node);
00764         return;
00765       }
00766 
00767     Node * last_node = get_last_node();
00768 
00769     Arc * arc = g->search_arc(last_node, node); // busque arco last_node-node
00770 
00771     if (arc == NULL)
00772       throw std::domain_error("There is no arc connecting node");
00773 
00774 
00775     append(arc);
00776   }
00803   void insert(Arc * arc)
00804   {
00805     if (list.is_empty())
00806       throw std::domain_error("path is empty");
00807 
00808     Path_Desc & first_path_desc = list.get_first(); // ultimo elemento de list
00809 
00810     if (not g->node_belong_to_arc(arc, first_path_desc.node))
00811       throw std::invalid_argument("first node in path does "
00812                                   "not incide on arc");
00813 
00814     first_path_desc.arc = arc;
00815 
00816     list.insert(Path_Desc(g->get_connected_node(arc, first_path_desc.node)));
00817   }
00845   void insert(Node * node)
00846   {
00847     if (list.is_empty())
00848       {
00849         init(node);
00850         
00851         return;
00852       }
00853 
00854     Node * first_node = get_first_node();
00855 
00856     Arc * arc = g->search_arc(first_node, node); // busque arco last_node-node
00857 
00858     if (arc == NULL)
00859       throw std::domain_error("There is no arc connecting node");
00860 
00861     insert(arc);
00862   }
00864   Node * get_first_node() { return list.get_first().node; }
00866   Node * get_last_node() { return list.get_last().node; }
00868   Arc * get_first_arc() { return list.get_first().arc; }
00870   Arc * get_last_arc()
00871   {
00872 
00873     if (list.is_unitarian())
00874       throw std::domain_error("Path with only a node (without any arc");
00875 
00876     typename DynDlist<Path_Desc>::Iterator it(list);
00877     it.reset_last();
00878     it.prev();
00879 
00880     return it.get_current().arc; 
00881   }
00883   bool is_cycle() const { return get_first_node() == get_last_node(); }
00885   void remove_last_node()
00886   {
00887     list.remove_last();
00888     list.get_last().arc = NULL;
00889   }
00891   void remove_first_node()
00892   {
00893     list.remove_first();
00894   }
00896   void swap(Path & path)
00897   {
00898     Aleph::swap(g, path.g);
00899     list.swap(path.list);
00900   }
00906   class Iterator : public DynDlist<Path_Desc>::Iterator
00907   {
00908 
00909   public:
00910 
00911      // ...
00912 
00914     Iterator() { /* empty */ }
00915 
00917     Iterator(Path & path) : DynDlist<Path_Desc>::Iterator(path.list) { }
00918 
00920     Iterator(const Iterator & it) : DynDlist<Path_Desc>::Iterator(it) { }
00921       
00923     Iterator & operator = (const Iterator & it) 
00924     {
00925       DynDlist<Path_Desc>::Iterator::operator = (it);
00926       return *this;
00927     }
00928 
00931     Node * get_current_node() { return this->get_current().node; }
00932 
00935     Arc * get_current_arc() 
00936     { 
00937 
00938       if (this->is_in_last())
00939         throw std::overflow_error("Path iterator is in last node of path");
00940 
00941       return this->get_current().arc; 
00942     }
00943   };
00949   template <class Operation> void operate_on_nodes()
00950   {
00951     for (Iterator it(*this); it.has_current(); it.next())
00952       Operation () (it.get_current_node());
00953   }
00959   template <class Operation> void operate_on_arcs()
00960   {
00961     for (Iterator it(*this); it.has_current(); it.next())
00962       Operation () (it.get_current_arc());
00963   }
00974   template <class Operation> void operate_on_nodes(void * ptr)
00975   {
00976     for (Iterator it(*this); it.has_current(); it.next())
00977       Operation(ptr) (it.get_current_node());
00978   }
00979 
00990   template <class Operation> void operate_on_arcs(void * ptr)
00991   {
00992     for (Iterator it(*this); it.has_current(); it.next())
00993       Operation(ptr) (it.get_current_arc());
00994   }
00995 }; 
00996     template <class GT> inline 
00997 bool find_path_depth_first(GT&                 g, 
00998                            typename GT::Node * start_node, 
00999                            typename GT::Node * end_node,
01000                            Path<GT> &          path);
01001     template <class GT> inline static bool 
01002 __find_path_depth_first(GT&                 g,  
01003                         typename GT::Node * curr_node, // nodo actual
01004                         typename GT::Arc *  curr_arc,  // arco procedencia
01005                         typename GT::Node * end_node,  // nodo destino
01006                         Path<GT> &          curr_path) // camino actual
01007 {
01008   if (curr_node == end_node) // ¿se alcanzó nodo final?
01009     {     // sí, terminar añadir el arco y terminar
01010       curr_path.append(curr_arc);
01011 
01012       return true;
01013     }
01014 
01015   if (IS_NODE_VISITED(curr_node, Find_Path)) // ¿No ha sido visitado?
01016     return false; // sí ==> desde él no hay camino
01017 
01018   curr_path.append(curr_arc); // añadir curr_arc al camino
01019 
01020   NODE_BITS(curr_node).set_bit(Find_Path, true); // marcar nodo
01021 
01022       // buscar recursivamente a través de arcos de curr_node
01023   for (typename GT::Node_Arc_Iterator i(curr_node); i.has_current(); i.next())
01024     {
01025       typename GT::Arc * next_arc = i.get_current_arc();
01026       
01027       if (IS_ARC_VISITED(next_arc, Find_Path))
01028         continue; // ya se pasó por este arco 
01029 
01030       ARC_BITS(next_arc).set_bit(Find_Path, true); // marcar arco
01031 
01032       typename GT::Node * next_node = i.get_tgt_node(); 
01033 
01034           // continuamos exploración en profundidad desde next_node
01035       if (__find_path_depth_first <GT> (g, next_node, next_arc, 
01036                                         end_node, curr_path))
01037 
01038         {
01039           I(curr_path.get_last_node() == end_node);
01040 
01041         return true; // se encontró camino, terminar retornando true
01042 
01043         }
01044 
01045     }
01046       // no se encontró camino por curr_arc ==> eliminarlo de path
01047   curr_path.remove_last_node();
01048 
01049   return false;
01050 }
01073     template <class GT> inline 
01074 bool find_path_depth_first(GT&                 g, 
01075                            typename GT::Node * start_node, 
01076                            typename GT::Node * end_node,
01077                            Path<GT> &          path)
01078 {
01079 
01080   if (not path.inside_graph(g))
01081     throw std::invalid_argument("Path does not belong to graph");
01082 
01083   path.clear_path();     // limpiamos path
01084   path.init(start_node); // insertamos nodo origen
01085 
01086   g.reset_bit_nodes(Find_Path);
01087   g.reset_bit_arcs(Find_Path); 
01088 
01089   NODE_BITS(start_node).set_bit(Find_Path, true); // marcar start_node visitado
01090 
01091       // explorar recursivamente cada arco de start_node
01092   for (typename GT::Node_Arc_Iterator i(start_node); i.has_current(); i.next())
01093     {
01094       typename GT::Arc * arc = i.get_current_arc();
01095 
01096           // marcar arco como visitado
01097       ARC_BITS(arc).set_bit(Find_Path, true); 
01098 
01099       typename GT::Node * next_node = i.get_tgt_node();
01100 
01101       if (IS_NODE_VISITED(next_node, Find_Path))
01102         continue; 
01103 
01104       if (__find_path_depth_first(g, next_node, arc, end_node, path))
01105         return true;
01106     }
01107   return false;
01108 }
01137     template <typename __Graph_Node, typename __Graph_Arc>
01138 class List_Graph
01139 {
01140 
01141 public:
01142 
01143   
01144   public:
01145 
01147   typedef __Graph_Node             Node;      
01149   typedef __Graph_Arc              Arc;       
01151   typedef typename Node::Node_Type Node_Type; 
01153   typedef typename Arc::Arc_Type   Arc_Type;
01154 
01155 private:
01156 
01157   struct Reset_Node
01158   {
01159     void operator () (List_Graph&, Node * node)
01160     {
01161       node->control_bits.reset();
01162       node->counter = 0;
01163       node->cookie = NULL;
01164     }
01165   };
01166   struct Reset_Arc
01167   {
01168     void operator () (List_Graph&, Arc * arc)
01169     {
01170       arc->control_bits.reset();
01171       arc->counter = 0;
01172       arc->cookie = NULL;
01173     }
01174   };
01175   Dlink  node_list; // lista de nodos
01176   size_t num_nodes; // cantidad de nodos
01177 
01178   Dlink  arc_list;  // lista de arcos
01179   size_t num_arcs;  // cantidad de arcos
01180   static Node * dlink_to_node(Dlink * p)
01181   {
01182     return static_cast<Node*>(p);
01183   }
01184   static Arc * dlink_to_arc(Dlink * p)
01185   {
01186     return static_cast<Arc*>(p);
01187   }
01188   static Arc_Node * dlink_to_arc_node(Dlink * p)
01189   {
01190     return static_cast<Arc_Node*>(p);
01191   }
01192   static Arc * void_to_arc(Arc_Node * arc_node)
01193   {
01194     return static_cast<Arc*>(arc_node->arc); 
01195   }
01196 
01197   protected:
01198 
01199     bool digraph;
01200 
01201   private:
01202 
01203       template <class Cmp>
01204   struct Cmp_Arc
01205   {
01206     bool operator () (Dlink * d1, Dlink * d2) const
01207     {
01208       Arc * arc1 = dlink_to_arc(d1); // convertir dlink d1 de arco a Arc
01209       Arc * arc2 = dlink_to_arc(d2); // convertir dlink d2 de arco a Arc
01210 
01211           // al tener dos arcos invocamos a Cmp
01212       return Cmp () (arc1, arc2);
01213     }
01214   };
01215 
01216 public:
01217 
01219   bool is_digraph() const;
01220   void verify_graphs(List_Graph & g);
01237   inline Node * insert_node(Node * node);
01250   inline Node * insert_node(const Node_Type & node_info);
01259   inline void remove_node(Node * node);
01269   inline Node * get_first_node();
01271   inline const size_t & get_num_nodes() const;
01294        template <class Equal>
01295   Node * search_node(const Node_Type & node_info);
01311   Node * search_node(const Node_Type & node_info);
01314   bool node_belong_to_graph(Node * node);
01335        template <class Equal>
01336   Node * search_node(void * ptr);
01342   template <class Operation> void operate_on_nodes()
01343   {
01344     for (Node_Iterator itor(*this); itor.has_current(); itor.next())
01345       Operation () (*this, itor.get_current_node());
01346   }
01347 
01360   template <class Operation> void operate_on_nodes(void * ptr)
01361   {
01362     for (Node_Iterator itor(*this); itor.has_current(); itor.next())
01363       Operation () (*this, itor.get_current_node(), ptr);
01364   }
01373   inline Node * get_src_node(Arc * arc);
01374 
01383   inline Node * get_tgt_node(Arc * arc);
01395   inline Node * get_connected_node(Arc * arc, Node * node);
01404   inline bool node_belong_to_arc(Arc * arc, Node * node) const;
01427   inline Arc * insert_arc(Node *                src_node, 
01428                           Node *                tgt_node, 
01429                           const typename Arc::Arc_Type & arc_info);
01440   inline void remove_arc(Arc * arc);
01456   inline Arc * get_first_arc();
01462   template <class Compare> inline void sort_arcs();
01464   inline const size_t & get_num_arcs() const;
01471   inline const size_t & get_num_arcs(Node * node) const;
01494         template <class Equal>
01495   Arc * search_arc(const Arc_Type & arc_info);
01496 
01512   Arc * search_arc(const Arc_Type & arc_info);
01515   bool arc_belong_to_graph(Arc * arc);
01516   Arc * search_arc(Node * src_node, Node * tgt_node);
01537       template <class Equal>
01538   Arc * search_arc(void * ptr);
01544   template <class Operation> void operate_on_arcs()
01545   {
01546     for (Arc_Iterator itor(*this); itor.has_current(); itor.next())
01547       Operation () (*this, itor.get_current_arc());
01548   }
01549 
01562   template <class Operation> void operate_on_arcs(void * ptr)
01563   {
01564     for (Arc_Iterator itor(*this); itor.has_current(); itor.next())
01565       Operation () (*this, itor.get_current_arc(), ptr);
01566   }
01567 
01575   template <class Operation> void operate_on_arcs(Node * node)
01576   {
01577     for (Node_Arc_Iterator it(node); it.has_current(); it.next())
01578       Operation () (*this, it.get_current_arc());
01579   }
01580 
01594   template <class Operation> void operate_on_arcs(Node * node, void * ptr)
01595   {
01596     for (Node_Arc_Iterator it(node); it.has_current(); it.next())
01597       Operation () (*this, it.get_current_arc(), ptr);
01598   }
01599 
01606   inline Bit_Fields & get_control_bits(Node * node);
01612   inline void reset_bit(Node * node, const int & bit);
01619   inline void set_bit(Node * node, const int & bit, const int & value);
01620   inline Bit_Fields & get_control_bits(Arc * arc);
01626   inline void reset_bit(Arc * arc, const int & bit);
01633   inline void set_bit(Arc * arc, const int & bit, const int & value);
01638   void reset_bit_nodes(const int & bit)
01639   {
01640     for (Node_Iterator itor(*this); itor.has_current(); itor.next())
01641       reset_bit(itor.get_current_node(), bit);
01642   }
01647   void reset_bit_arcs(const int & bit)
01648   {
01649     for (Arc_Iterator itor(*this); itor.has_current(); itor.next())
01650       reset_bit(itor.get_current_arc(), bit);
01651   }
01657   inline long & get_counter(Node * node);
01662   inline void reset_counter(Node * node);
01668   inline long & get_counter(Arc * arc);
01673   inline void reset_counter(Arc * arc);
01675   void reset_counter_nodes()
01676   {
01677     for (Node_Iterator itor(*this); itor.has_current(); itor.next())
01678       reset_counter(itor.get_current_node());
01679   }
01681   void reset_counter_arcs()
01682   {
01683     for (Arc_Iterator itor(*this); itor.has_current(); itor.next())
01684       reset_counter(itor.get_current_arc());
01685   }
01691   inline void *& get_cookie(Node * node);
01697   inline void *& get_cookie(Arc * arc);
01699   void reset_cookie_nodes()
01700   {
01701     for (Node_Iterator itor(*this); itor.has_current(); itor.next())
01702       itor.get_current_node().cookie = NULL;
01703   }
01705   void reset_cookie_arcs()
01706   {
01707     for (Arc_Iterator itor(*this); itor.has_current(); itor.next())
01708       itor.get_current_arc().cookie = NULL;
01709   }
01729   static void map_nodes(Node * p, Node * q);
01730 
01750   static void map_arcs(Arc * p, Arc * q);
01755   inline void reset_node(Node * node);
01756 
01761   inline void reset_arc(Arc * arc);
01763   void reset_nodes()
01764   {
01765     operate_on_nodes <Reset_Node> ();
01766   }
01768   void reset_arcs()
01769   {
01770     operate_on_arcs <Reset_Arc> ();
01771   }
01772   inline List_Graph();
01783   inline List_Graph(const List_Graph & g);
01795   inline List_Graph& operator = (List_Graph & g);
01798   inline virtual ~List_Graph();
01810   inline List_Graph(List_Digraph<Node, Arc> & g);
01824   inline List_Graph & operator = (List_Digraph<Node, Arc> & g);
01841   void copy_graph(List_Graph & src_graph, const bool cookie_map = false);
01844   inline void clear_graph();
01851   class Node_Iterator : public Dlink::Iterator
01852   {
01853 
01854   public:
01855 
01856     Node_Iterator() { /* empty */ }
01857     Node_Iterator(List_Graph & _g);
01858     Node_Iterator(const Node_Iterator & it); 
01859     Node_Iterator & operator = (const Node_Iterator & it);
01861     Node * get_current_node(); 
01862   };
01870   class Node_Arc_Iterator : public Dlink::Iterator
01871   {
01872     Node * src_node; 
01873 
01874   public:
01875 
01877     inline Node_Arc_Iterator();
01879     inline Node_Arc_Iterator(Node * _src_node);
01881     inline Node_Arc_Iterator(const Node_Arc_Iterator & it);
01883     inline Node_Arc_Iterator & operator = (const Node_Arc_Iterator & it);
01885     inline Arc * get_current_arc();
01887     inline Node * get_tgt_node();
01888     Arc_Node * get_current_arc_node() 
01889     {
01890       return dlink_to_arc_node(get_current());
01891     }
01892   };
01900   class Arc_Iterator : public Dlink::Iterator
01901   {
01902 
01903   public:
01904 
01905     Arc_Iterator() { /* empty */ }
01906     Arc_Iterator(List_Graph & _g);
01907     Arc_Iterator(const Arc_Iterator & it);
01908     Arc_Iterator & operator = (const Arc_Iterator & it);
01910     Arc * get_current_arc();
01911   };
01912 };
01929     template <typename Node_Info, typename Arc_Info>
01930 class List_Digraph : public List_Graph<Node_Info, Arc_Info>
01931 {
01932 
01933 public:
01934 
01935   List_Digraph();
01936   List_Digraph(const List_Digraph & dg);
01937   List_Digraph & operator = (List_Digraph & dg);
01938 };
01954     template <class GT>
01955 void invert_digraph(GT & sg, GT & rg)
01956 {
01957 
01958   if (not sg.is_digraph())
01959     throw std::domain_error("sg is not a digraph");
01960 
01961   if (not rg.is_digraph())
01962     throw std::domain_error("rg is not a digraph");
01963 
01964   rg.clear_graph();
01965   sg.reset_nodes();
01966 
01967       // recorrer todos los arcos del digrafo sg
01968   for (typename GT::Arc_Iterator it(sg); it.has_current(); it.next())
01969     {
01970       typename GT::Arc * arc = it.get_current();
01971 
01972       typename GT::Node * ssrc = sg.get_src_node(arc); // procesar nodo origen
01973       typename GT::Node * rsrc = NODE_COOKIE(ssrc);
01974       if (rsrc == NULL) // ¿ya está creado ssrc en rg?
01975         {     // no == crearlo, insertarlo y mapearlo
01976            auto_ptr<typename GT::Node> rsrc_auto(new typename GT::Node(ssrc));
01977 
01978           sg.insert_node(rsrc_auto.get());
01979           GT::map_nodes(ssrc, rsrc_auto.get());
01980           rsrc = rsrc_auto.release(); 
01981         }
01982 
01983       typename GT::Node * stgt = sg.get_tgt_node(arc); // procesar nodo destino
01984       typename GT::Node * rtgt = NODE_COOKIE(stgt);
01985       if (rtgt == NULL) // ¿ya está creado ssrc en rg?
01986         {     // no == crearlo, insertarlo y mapearlo
01987            auto_ptr<typename GT::Node> rtgt_auto(new typename GT::Node(stgt));
01988 
01989           sg.insert_node(rtgt_auto.get());
01990           GT::map_nodes(stgt, rtgt_auto.get());
01991           rtgt = rtgt_auto.release(); 
01992         }
01993 
01994       rg.insert_arc(rtgt, rsrc, arc->get_info());
01995     }
01996 }
01997    template <typename Node, typename Arc>
01998 const size_t & List_Graph<Node, Arc>::get_num_nodes() const 
01999 {
02000   return num_nodes; 
02001 }
02002    template <typename Node, typename Arc>
02003 const size_t & List_Graph<Node, Arc>::get_num_arcs() const 
02004 {
02005   return num_arcs; 
02006 }
02007    template <typename Node, typename Arc>
02008 Node * List_Graph<Node, Arc>::get_first_node() 
02009 {
02010 
02011   if (num_nodes == 0)
02012     throw std::range_error("Graph has not nodes");
02013 
02014   return dlink_to_node(node_list.get_next());
02015 }
02016 
02017    template <typename Node, typename Arc>
02018 Arc * List_Graph<Node, Arc>::get_first_arc() 
02019 {
02020 
02021   if (get_num_arcs() == 0)
02022     throw std::range_error("Graph has not arcs");
02023 
02024   return dlink_to_arc(arc_list.get_next());
02025 }
02026    template <typename Node, typename Arc>
02027 List_Graph<Node, Arc>::Node_Iterator::Node_Iterator(List_Graph<Node, Arc> & _g)
02028   : Dlink::Iterator(&_g.node_list)
02029 {
02030   // empty
02031 }
02032 
02033    template <typename Node, typename Arc>
02034 List_Graph<Node, Arc>::Node_Iterator::Node_Iterator
02035    (const List_Graph<Node, Arc>::Node_Iterator & it)
02036      : Dlink::Iterator(it)
02037 {
02038   // empty
02039 }
02040 
02041    template <typename Node, typename Arc>
02042 typename List_Graph<Node, Arc>::Node_Iterator & 
02043 List_Graph<Node, Arc>::Node_Iterator::operator = 
02044    (const typename List_Graph<Node, Arc>::Node_Iterator & it) 
02045 {
02046   Dlink::Iterator::operator = (it);
02047       
02048   return *this;
02049 }
02050 
02051     template <typename Node, typename Arc>
02052 Node * List_Graph<Node, Arc>::Node_Iterator::get_current_node() 
02053 {
02054   return dlink_to_node(get_current()); 
02055 }
02056    template <typename Node, typename Arc>
02057 List_Graph<Node, Arc>::Arc_Iterator::Arc_Iterator(List_Graph<Node, Arc> & _g) 
02058   : Dlink::Iterator(&_g.arc_list)
02059 {
02060   // empty
02061 }
02062 
02063    template <typename Node, typename Arc>
02064 List_Graph<Node, Arc>::Arc_Iterator::Arc_Iterator
02065    (const List_Graph<Node, Arc>::Arc_Iterator::Arc_Iterator & it) 
02066      : Dlink::Iterator(it)
02067 {
02068   // empty
02069 }
02070 
02071        template <typename Node, typename Arc>
02072    typename List_Graph<Node, Arc>::Arc_Iterator & 
02073 List_Graph<Node, Arc>::Arc_Iterator::operator = 
02074        (const List_Graph<Node, Arc>::Arc_Iterator & it) 
02075 {
02076   Dlink::Iterator::operator = (it);
02077 
02078   return *this;
02079 }
02080 
02081    template <typename Node, typename Arc>
02082 Arc * List_Graph<Node, Arc>::Arc_Iterator::get_current_arc() 
02083 {
02084   return dlink_to_arc(get_current()); 
02085 }
02086     template <typename Node, typename Arc>
02087     template <class Equal>
02088 Node * List_Graph<Node, Arc>::search_node
02089       (const typename Node::Node_Type & node_info)
02090 {
02091   for (Node_Iterator itor(*this); itor.has_current(); itor.next())
02092     {
02093       Node * current_node = itor.get_current_node();
02094         
02095       if (Equal() (current_node->get_info(), node_info))
02096         return current_node;
02097     }
02098   return NULL;
02099 }
02100     template <typename Node, typename Arc>
02101 Node * List_Graph<Node, Arc>::search_node
02102   (const typename Node::Node_Type & node_info)
02103 {
02104   return search_node<Aleph::equal_to<typename Node::Node_Type> >(node_info);
02105 }
02106 
02107     template <typename Node, typename Arc>
02108 bool List_Graph<Node, Arc>::node_belong_to_graph(Node * node)
02109 {
02110   for (Node_Iterator itor(*this); itor.has_current(); itor.next())
02111     {
02112       Node * current_node = itor.get_current_node();
02113         
02114       if (current_node == node)
02115         return true;
02116     }
02117 
02118   return false;
02119 }
02120 
02121     template <typename Node, typename Arc>
02122     template <class Equal>
02123 Node * List_Graph<Node, Arc>::search_node(void * ptr)
02124 {
02125   for (Node_Iterator itor(*this); itor.has_current(); itor.next())
02126     {
02127       Node * curr_node = itor.get_current_node();
02128         
02129       if (Equal () (curr_node, ptr))
02130         return curr_node;
02131     }
02132 
02133   return NULL;
02134 }
02135     template <typename Node, typename Arc>
02136     template <class Equal>
02137     Arc *
02138  List_Graph<Node, Arc>::search_arc(const typename Arc::Arc_Type & arc_info)
02139 {
02140   for (Arc_Iterator it(*this); it.has_current(); it.next())
02141     {
02142       Arc * current_arc = it.get_current_arc();
02143         
02144       if (Equal() (current_arc->get_info(), arc_info))
02145         return current_arc;
02146     }    
02147   return NULL; 
02148 }
02149 
02150    template <typename Node, typename Arc>
02151 bool List_Graph<Node, Arc>::arc_belong_to_graph(Arc * arc) 
02152 {
02153   for (Arc_Iterator it(*this); it.has_current(); it.next())
02154     if (it.get_current_arc() == arc)
02155       return true;
02156 
02157   return false;
02158 }
02159 
02160    template <typename Node, typename Arc> 
02161    Arc * 
02162 List_Graph<Node, Arc>::search_arc(const typename Arc::Arc_Type & arc_info)
02163 {
02164   return search_arc<Aleph::equal_to<Arc_Type> >(arc_info);
02165 }
02166 
02167     template <typename Node, typename Arc>
02168     template <class Equal>
02169 Arc * List_Graph<Node, Arc>::search_arc(void * ptr)
02170 {
02171   for (Arc_Iterator itor(*this); itor.has_current(); itor.next())
02172     {
02173       Arc * curr_arc = itor.get_current_node();
02174         
02175       if (Equal () (curr_arc, ptr))
02176         return curr_arc;
02177     }
02178 
02179   return NULL;
02180 }
02181    template <typename Node, typename Arc>
02182 Node * List_Graph<Node, Arc>::get_src_node(Arc * arc) 
02183 {
02184   return static_cast<Node*>(arc->src_node); 
02185 }
02186    template <typename Node, typename Arc>
02187 Node * List_Graph<Node, Arc>::get_tgt_node(Arc * arc) 
02188 { 
02189   return static_cast<Node*>(arc->tgt_node); 
02190 }
02191    template <typename Node, typename Arc>
02192 bool List_Graph<Node, Arc>::node_belong_to_arc(Arc *  arc, 
02193                                                Node * node) const
02194 {
02195   return node == arc->src_node or node == arc->tgt_node;
02196 }
02197    template <typename Node, typename Arc>
02198 Node * List_Graph<Node, Arc>::get_connected_node(Arc * arc, Node * node) 
02199 {
02200   return static_cast<Node*>(arc->get_connected_node(node));
02201 }
02202    template <typename Node, typename Arc>
02203 void List_Graph<Node, Arc>::verify_graphs(List_Graph<Node, Arc> & g)
02204 {
02205   if (digraph and not g.digraph)
02206     throw std::domain_error("List_Graph and List_Digraph combined");
02207 }
02208    template <typename Node, typename Arc>
02209 bool List_Graph<Node, Arc>::is_digraph() const { return digraph; }
02210    template <typename Node, typename Arc>
02211 List_Graph<Node, Arc>::Node_Arc_Iterator::Node_Arc_Iterator() : src_node(NULL) 
02212 {
02213   /* empty */ 
02214 }
02215 
02216    template <typename Node, typename Arc>
02217 List_Graph<Node, Arc>::Node_Arc_Iterator::Node_Arc_Iterator(Node * _src_node) 
02218   : Dlink::Iterator(&(_src_node->arc_list)), src_node(_src_node)
02219 {
02220   // empty
02221 }
02222 
02223    template <typename Node, typename Arc>
02224 List_Graph<Node, Arc>::Node_Arc_Iterator::Node_Arc_Iterator
02225    (const List_Graph<Node, Arc>::Node_Arc_Iterator& it) 
02226      : Dlink::Iterator(it), src_node(it.src_node) 
02227 { 
02228   // empty 
02229 }
02230             
02231     template <typename Node, typename Arc>
02232   typename List_Graph<Node, Arc>::Node_Arc_Iterator & 
02233 List_Graph<Node, Arc>::Node_Arc_Iterator::operator = 
02234    (const Node_Arc_Iterator& it) 
02235 {
02236   Dlink::Iterator::operator = (it);
02237 
02238   src_node = it.src_node;
02239 
02240   return *this;
02241 }
02242 
02243    template <typename Node, typename Arc>
02244 Arc * List_Graph<Node, Arc>::Node_Arc_Iterator::get_current_arc() 
02245 {
02246   return static_cast<Arc*>(get_current_arc_node()->arc);
02247 }
02248 
02249    template <typename Node, typename Arc>
02250 Node * List_Graph<Node, Arc>::Node_Arc_Iterator::get_tgt_node() 
02251 { 
02252   return static_cast<Node*>(get_current_arc()->get_connected_node(src_node));
02253 }
02254    template <typename Node, typename Arc>
02255 Arc * List_Graph<Node, Arc>::search_arc(Node * src_node, Node * tgt_node) 
02256 {
02257 
02258   I(src_node != NULL and tgt_node != NULL);
02259 
02260   Node_Arc_Iterator itor;
02261     
02262   Node * searched_node;
02263 
02264       // Seleccionar el nodo que contenga menor cantidad de arcos
02265   if (digraph or src_node->num_arcs < tgt_node->num_arcs)
02266     {
02267       searched_node = tgt_node;
02268       itor = Node_Arc_Iterator(src_node);
02269     }
02270   else
02271     {
02272       searched_node = src_node;
02273       itor = Node_Arc_Iterator(tgt_node);
02274     }
02275 
02276       // recorrer lista de arcos del nodo en búsqueda de searched_node 
02277   for (/* nada */; itor.has_current(); itor.next())
02278     if (itor.get_tgt_node() == searched_node)
02279       return itor.get_current_arc();
02280 
02281   return NULL; 
02282 }
02283     template <typename Node, typename Arc>
02284 Node * List_Graph<Node, Arc>::insert_node(Node * node)
02285 {
02286   ++num_nodes;
02287   node_list.append(node);
02288 
02289   return node;
02290 }
02291     template <typename Node, typename Arc>
02292 Node * List_Graph<Node, Arc>::insert_node
02293   (const typename Node::Node_Type & node_info)
02294 {
02295   return insert_node( new Node (node_info) );
02296 }
02297    template <typename Node, typename Arc> Arc * 
02298 List_Graph<Node, Arc>::insert_arc(Node *                         src_node, 
02299                                   Node *                         tgt_node, 
02300                                   const typename Arc::Arc_Type & arc_info)
02301 {
02302       // paso (1): apartar memoria para Arc e iniciar
02303   auto_ptr<Arc> arc ( new Arc  ); // apartar memoria para arco 
02304   arc->src_node   = src_node;     // Iniciar sus campos
02305   arc->tgt_node   = tgt_node;
02306   arc->get_info() = arc_info;
02307           
02308       // paso (3) (parcial): apartar memoria para el Arc_Node del nodo
02309       // origen src_node  
02310   auto_ptr<Arc_Node> src_arc_node ( new Arc_Node (arc.get()) );
02311       
02312       // Paso (2): si es un grafo ==> apartar memoria para el Arc_Node
02313       // del nodo destino tgt_node
02314   if (not digraph) // si es digrafo ==> no hay que insertar en el otro nodo
02315     {     // inserción en nodo destino 
02316       if (src_node == tgt_node) // verificar si se trata de un ciclo
02317         arc->tgt_arc_node = src_arc_node.get(); /* este es un ciclo */
02318       else
02319         {     // apartar arco nodo para tgt_node 
02320           auto_ptr<Arc_Node> tgt_arc_node ( new Arc_Node (arc.get()) ); 
02321 
02322               // inserción en lista de adyacencia de nodo destino tgt_node
02323           arc->tgt_arc_node = tgt_arc_node.get();    
02324           tgt_node->arc_list.append(tgt_arc_node.get());
02325           tgt_node->num_arcs++;
02326           tgt_arc_node.release(); // desbloquear auto-puntero tgt_arc_node
02327         }
02328     }
02329       // paso (3) (resto) inserción en lista de adyacencia de nodo
02330       // origen src_node 
02331   arc->src_arc_node = src_arc_node.get();
02332   src_node->arc_list.append(src_arc_node.get());
02333   src_node->num_arcs++;
02334 
02335       // Paso (4) insertar arco en lista de arcos del grafo 
02336   arc_list.append(arc.get());
02337   ++num_arcs;
02338 
02339       // desbloquear auto-punteros y terminar
02340   src_arc_node.release(); // desbloquear tgt_arc_node
02341 
02342   return arc.release();   // desbloquear arc
02343 }
02344    template <typename Node, typename Arc>
02345 void List_Graph<Node, Arc>::remove_arc(Arc * arc)
02346 {
02347       // paso (1): eliminación del Arc_node del nodo origen src_node
02348   Node * src_node = get_src_node(arc); 
02349   Arc_Node * src_arc_node = arc->src_arc_node;
02350   src_arc_node->del();   // desenlaza src_node de la lista de nodos
02351   src_node->num_arcs--;  // decrementa contador de arcos de src_node
02352   delete src_arc_node;   // entrega memoria
02353 
02354   if (not digraph) 
02355     {     // eliminación arco en nodo destino 
02356       Node * tgt_node = get_tgt_node(arc); 
02357 
02358       if (src_node != tgt_node) // verificar eliminación de ciclo 
02359         {  // paso (2): eliminación del Arc_node del nodo destino tgt_node
02360           Arc_Node * tgt_arc_node = arc->tgt_arc_node;
02361           tgt_arc_node->del(); 
02362           tgt_node->num_arcs--;
02363           delete tgt_arc_node;
02364         }
02365     }
02366       // eliminación de arco del grafo 
02367   arc->del(); // desenlazar arc de la lista de arcos del grafo
02368   --num_arcs;
02369   delete arc;
02370 }
02371    template <typename Node, typename Arc>
02372 void List_Graph<Node, Arc>::remove_node(Node * node)
02373 {
02374       // Eliminar todos los arcos adyacentes a node
02375   while (not node->arc_list.is_empty()) // repita mientras aún hayan arcos
02376     {     // obtener el Arc_Node
02377       Arc_Node * arc_node = dlink_to_arc_node(node->arc_list.get_next());
02378 
02379       Arc * arc = void_to_arc(arc_node); // obtener el arco
02380 
02381       remove_arc(arc); // eliminarlo del grafo
02382     }
02383       // en este punto el nodo ya no tiene arcos
02384 
02385   node->del(); // desenlazar nodo de lista de nodos del grafo
02386   --num_nodes;
02387 
02388   delete node; 
02389 }
02390    template <typename Node, typename Arc>
02391 void List_Graph<Node, Arc>::clear_graph()
02392 {
02393       // recorrer cada nodo del grafo a través de la lista de nodos
02394   for (Dlink::Iterator node_itor(&node_list); node_itor.has_current(); )
02395     {     // obtener nodo a borrar
02396       Node * p = dlink_to_node(node_itor.get_current()); 
02397 
02398           // avanzar antes de borrar para que iterador permanezca consistente
02399       node_itor.next();
02400 
02401       remove_node(p); // eliminarlo del grafo
02402     }
02403 
02404   I(num_nodes == 0 and num_arcs == 0);
02405 
02406 }
02407    template <typename Node, typename Arc>
02408 void List_Graph<Node, Arc>::map_nodes(Node * p, Node * q)
02409 {
02410 
02411   I(p != NULL and q != NULL);
02412 
02413   if (NODE_COOKIE(p) == NULL)
02414     {
02415       NODE_COOKIE(p) = q;
02416       NODE_COOKIE(q) = p;
02417       return;
02418     }
02419 
02420   NODE_COOKIE(q) = NODE_COOKIE(p);
02421   NODE_COOKIE(p) = q;
02422 }
02423 
02424    template <typename Node, typename Arc>
02425 void List_Graph<Node, Arc>::map_arcs(Arc * p, Arc * q)
02426 {
02427 
02428   I(p != NULL and q != NULL);
02429 
02430   if (ARC_COOKIE(p) == NULL)
02431     {
02432       ARC_COOKIE(p) = q;
02433       ARC_COOKIE(q) = p;
02434       return;
02435     }
02436 
02437   ARC_COOKIE(q) = ARC_COOKIE(p);
02438   ARC_COOKIE(p) = q;
02439 }
02440    template <typename Node, typename Arc>
02441 void List_Graph<Node, Arc>::copy_graph(List_Graph<Node, Arc> & src_graph,
02442                                        const bool              cookie_map)
02443 {
02444 
02445   IG(not is_digraph() and src_graph.is_digraph(), 
02446      is_digraph() != src_graph.is_digraph());
02447 
02448   verify_graphs(src_graph);
02449 
02450   try
02451     {
02452 
02453       clear_graph(); // limpiar this antes de copiar
02454 
02455       DynMapAvlTree<Node*, Node*> mapping_table;  
02456 
02457           // Fase (1): recorrer nodos de grafo src_graph e insertar copia en this
02458       for (Node_Iterator it(src_graph); it.has_current(); it.next())
02459         {
02460           Node * src_node = it.get_current_node(); 
02461 
02462           auto_ptr<Node> tgt_node(new Node(src_node)); // hacer una copia
02463 
02464           mapping_table.insert(src_node, tgt_node.get()); // insertar en mapeo
02465 
02466           Node * tgt = tgt_node.release();
02467 
02468           insert_node(tgt); // insertarla en grafo destino
02469 
02470           if (cookie_map)
02471             map_nodes(src_node, tgt);
02472         }
02473 
02474       I(get_num_nodes() == src_graph.get_num_nodes());
02475 
02476           // fase (2): para cada arco de src_graph, crear en this un
02477           // arco que conecte a los nodos mapeados de mapping_table
02478           // insertados en la fase anterior 
02479       for (Arc_Iterator it(src_graph); it.has_current(); it.next())
02480         {
02481           Arc * src_arc = it.get_current_arc();
02482 
02483               // obtener imágenes de nodos en el grafo destino 
02484           Node * src_node = mapping_table[src_graph.get_src_node(src_arc)]; 
02485           Node * tgt_node = mapping_table[src_graph.get_tgt_node(src_arc)];
02486 
02487               // insertar arco en grafo destino
02488           Arc * tgt_arc = insert_arc(src_node, tgt_node, src_arc->get_info()); 
02489           
02490           if (cookie_map)
02491             map_arcs(src_arc, tgt_arc);
02492         }
02493 
02494       I(get_num_arcs() == src_graph.get_num_arcs());
02495     }
02496   catch (...)
02497     {     // Si ocurre excepción se limpia this 
02498       clear_graph(); 
02499       throw;
02500     }
02501 
02502 }
02503    template <typename Node, typename Arc>
02504 List_Graph<Node, Arc>::List_Graph() : num_nodes(0), num_arcs(0), digraph(false)
02505 {
02506   /* empty */ 
02507 }
02508     template <typename Node, typename Arc>
02509 List_Digraph<Node, Arc>::List_Digraph() 
02510 {
02511   List_Graph<Node, Arc>::digraph = true;
02512 }
02513    template <typename Node, typename Arc>
02514 List_Graph<Node, Arc>::List_Graph(const List_Graph<Node, Arc> & g) 
02515   : num_nodes(0), num_arcs(0), digraph(false)
02516 {
02517   copy_graph(const_cast<List_Graph<Node, Arc> &>(g));
02518 }
02519    template <typename Node, typename Arc>
02520 List_Digraph<Node, Arc>::List_Digraph
02521    (const List_Digraph<Node, Arc>::List_Digraph & dg) 
02522      : List_Graph<Node, Arc>(dg)
02523 {
02524   List_Graph<Node, Arc>::digraph = true; 
02525 }
02526 
02527    template <typename Node, typename Arc>
02528 List_Graph<Node, Arc> & List_Graph<Node, Arc>::operator = 
02529   (List_Graph<Node, Arc> & g)
02530 {
02531   if (this == &g)
02532     return *this;
02533 
02534   copy_graph(const_cast<List_Graph<Node, Arc> &>(g));
02535 
02536   return *this;
02537 }
02538 
02539    template <typename Node, typename Arc>
02540 List_Digraph<Node, Arc> & List_Digraph<Node, Arc>::operator = 
02541    (List_Digraph<Node, Arc>::List_Digraph & dg)
02542 {
02543   return List_Graph<Node, Arc>::operator = (dg);
02544 }
02545    template <typename Node, typename Arc>
02546 List_Graph<Node, Arc>::~List_Graph() 
02547 {
02548   clear_graph(); 
02549 }
02550    template <typename Node, typename Arc>
02551    template <class Compare>
02552 void List_Graph<Node, Arc>::sort_arcs()
02553 {
02554   mergesort < Cmp_Arc <Compare> > (arc_list);
02555 }
02556    template <typename Node, typename Arc>
02557 const size_t & List_Graph<Node, Arc>::get_num_arcs(Node * node) const 
02558 {
02559   return node->num_arcs; 
02560 }
02561 
02562    template <typename Node, typename Arc>
02563 void List_Graph<Node, Arc>::reset_bit(Node * node, const int & bit) 
02564 {
02565   node->control_bits.reset(bit); 
02566 }
02567 
02568    template <typename Node, typename Arc>
02569 Bit_Fields & List_Graph<Node, Arc>::get_control_bits(Node * node)
02570 {
02571   return node->control_bits; 
02572 }
02573 
02574    template <typename Node, typename Arc>
02575 void List_Graph<Node, Arc>::set_bit(Node *      node,
02576                                     const int & bit, 
02577                                     const int & value) 
02578 {
02579   node->control_bits.set_bit(bit, value);
02580 }
02581 
02582    template <typename Node, typename Arc>
02583 long & List_Graph<Node, Arc>::get_counter(Node * node) 
02584 {
02585   return node->counter; 
02586 }
02587 
02588    template <typename Node, typename Arc>
02589 void List_Graph<Node, Arc>::reset_counter(Node * node)
02590 {
02591   node->counter = No_Visited; 
02592 }
02593 
02594    template <typename Node, typename Arc>
02595 void *& List_Graph<Node, Arc>::get_cookie(Node * node) 
02596 {
02597   return node->cookie; 
02598 }
02599 
02600    template <typename Node, typename Arc>
02601 void List_Graph<Node, Arc>::reset_node(Node * node)
02602 {
02603   node->control_bits.reset(); 
02604   node->counter = 0;
02605   node->cookie  = NULL;
02606 }
02607    template <typename Node, typename Arc>
02608 void List_Graph<Node, Arc>::reset_bit(Arc * arc, const int & bit) 
02609 {
02610   arc->control_bits.reset(bit); 
02611 }
02612 
02613    template <typename Node, typename Arc>
02614 Bit_Fields & List_Graph<Node, Arc>::get_control_bits(Arc * arc) 
02615 {
02616   return arc->control_bits; 
02617 }
02618 
02619    template <typename Node, typename Arc>
02620 void List_Graph<Node, Arc>::set_bit(Arc *       arc, 
02621                                     const int & bit, 
02622                                     const int & value) 
02623 {
02624   arc->control_bits.set_bit(bit, value);
02625 }
02626 
02627    template <typename Node, typename Arc>
02628 long & List_Graph<Node, Arc>::get_counter(Arc * arc) 
02629 {
02630   return arc->counter; 
02631 }
02632 
02633    template <typename Node, typename Arc>
02634 void List_Graph<Node, Arc>::reset_counter(Arc * arc) 
02635 {
02636   arc->counter = No_Visited; 
02637 }
02638 
02639    template <typename Node, typename Arc>
02640 void *& List_Graph<Node, Arc>::get_cookie(Arc * arc) 
02641 {
02642   return arc->cookie; 
02643 }
02644 
02645    template <typename Node, typename Arc>
02646 void List_Graph<Node, Arc>::reset_arc(Arc * arc)
02647 {
02648   arc->control_bits.reset(); 
02649   arc->counter = 0;
02650   arc->cookie  = NULL;
02651 }
02652 
02653 } // end namespace Aleph
02654 
02655 # endif /* TPL_GRAPH_H */
02656 

Leandro R. León