shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/graph.hpp
Go to the documentation of this file.
00001 
00002 /********************************************
00003   Graph Representation using adjacency list.
00004 
00005   Assumptions:
00006   ! No loops (= edge starting and ending on same vertex)
00007   ! No edge exists if the vertices do not exist
00008 
00009   Angelos Mantzaflaris, GALAAD, INRIA
00010 *********************************************/
00011 
00012 #pragma once
00013 
00014 # include <stack>
00015 # include <realroot/Seq.hpp>
00016 
00017 # define NODESTACK std::stack<gNode<T> *>
00018 # define Viewer viewer<axel, K>
00019 
00020 
00021 namespace mmx {
00022 namespace shape {
00023 
00024 template<class T> class Graph;
00025 template<class T> class GraphDfsIter;
00026 
00027 
00029 // gNode
00031 template<class T>
00032 class gNode
00033 {
00034 
00035   friend class Graph<T>;
00036   friend class GraphDfsIter<T>;
00037   
00038 private:
00039   T data;
00040   gNode<T>* vlist; // the next node of the node list
00041   gNode<T>* next;  // the next neighbor of this node
00042   gNode<T>* me;    // pointer to next appeareance of node
00043   gNode<T>* start; // pointer to vlist appeareance of node
00044   
00045   int m_status;
00046   int m_aux;
00047   
00048 public:
00049   gNode(){ };
00050   
00051   gNode(T val)
00052     {
00053       this->data =val; //node data
00054       this->vlist=NULL;//next node in list
00055       this->next =NULL;//next neighbor of node
00056       this->me   =this;//next occurance of this node
00057       this->start=this;//pointer to this node on the node list
00058       this->m_status =2009;
00059       this->m_aux    =0;
00060     }   
00061   
00062   inline T get_data() {return this->data;};
00063   //void operator<<(T& v) {this->push_vertex(v);};
00064   
00066   inline bool adj(T& v) {
00067     
00068     gNode<T>* t;
00069     t= this->next;
00070     
00071     while(t!=NULL)
00072     {
00073       if(t->vlist->data==v)
00074         return true;
00075       t=t->next;
00076     }
00077     return false;
00078   };
00079   
00081   inline void status(int i)
00082     {
00083       this->start->m_status=i;
00084     };
00085   
00087   inline int status()
00088     {
00089       return this->start->m_status;
00090     };
00091   
00093   inline void aux(int i)
00094     {
00095       this->start->m_aux=i;
00096     };
00097   
00099   inline int aux()
00100     {
00101       return this->start->m_aux;
00102     };
00103   
00104 };
00105   
00106   
00107   
00109 // Graph
00111 template<class T>
00112 class Graph
00113 {
00114   friend class GraphDfsIter<T>;
00115   typedef void (*func)(gNode<T> *);
00116   typedef bool (*test_node)(gNode<T> *);
00117   
00118 private:
00119   gNode<T>* head; //a pointer to the head node
00120   unsigned nvertices, nedges;
00121   //bool directed;
00122   
00123 public:
00124   
00125   // Initialize empty graph
00126   Graph()
00127     {
00128       nvertices=nedges=0;
00129       head=NULL;
00130     }
00131   
00132   void vertex_list ( Seq<T> & v) const ;
00133   void edge_list   ( Seq<T> & e) const ;
00134   Seq<T> neighbors( T e);
00135   
00136   gNode<T>* push_vertex(T val, int i=0);
00137   void push_edge(T v_val,T e_val);
00138   inline        void push_uedge(T v_val,T e_val)
00139     {push_edge(v_val,e_val); push_edge(e_val,v_val);};
00140 
00141   
00142   inline unsigned nbv() const { return nvertices;};
00143   inline unsigned nbe() const { return nedges;   };
00144 
00145   inline T        next(T val)   const ;
00146   inline bool     member(T val) const ;
00147   
00148   void delete_edge(T v_val,T e_val);
00149   void delete_vertex(T val);
00150   
00151   // dfs: apply function fp to nodes
00152   void dfs(func fp);
00153   void dfs_walk(gNode<T> * s, func fp);
00154 
00155   // dfs: return (pointer to) first node that satisfies bool fp
00156   gNode<T>* dfs( test_node fp );
00157   
00158   // dfs: fill "out" with the nodes in visited order
00159   void dfs(Seq<T> & out);
00160   void dfs_walk(gNode<T> * s, Seq<T> & out);
00161   
00162   // set node t as the head of the list (thus dfs starts from this node)
00163   bool set_start_node(T& val);
00164   bool set_start_node(T& v_val,T& e_val);
00165   gNode<T> * get_start_node();
00166   
00167   GraphDfsIter<T> * createIterator() const;
00168   
00169   
00171   void print()
00172     {
00173       std::cout<< "Graph: "<< std::endl;
00174       gNode<T> *s, *t=head;
00175       while(t!=NULL)
00176       {
00177         std::cout<< t->data<<" ===> ";
00178         s=t->next;
00179         while(s!=NULL)
00180         {   std::cout<< s->data<<", "; s=s->next;}
00181         std::cout<< std::endl;
00182         t=t->vlist;
00183       }
00184       std::cout<< std::endl;
00185     }
00186 
00187   
00188 private:
00189   
00190   static void discover(gNode<T> * v);
00191   
00192 };
00193   
00194   
00196 template<class T>
00197 class GraphDfsIter
00198 {
00199   const Graph<T> *g;
00200   gNode<T> * current, * next_start; 
00201     NODESTACK q;
00202   
00203 public:
00204   
00205   GraphDfsIter(const Graph<T> s)
00206     {
00207       g = &s;
00208     }
00209   
00210   void first()
00211     {
00212       current = g->head;
00213       next_start=current->vlist;
00214       
00215       gNode<T>* t=current;
00216       while(t!=NULL)// Mark all as not visited
00217       {
00218         t->status(-1);
00219         t=t->vlist;
00220       }
00221       current->status(0);
00222     }
00223 
00224   bool isLast()
00225     {
00226 
00227       if ( q.empty() )
00228       {
00229         
00230         while( next_start!=NULL)
00231         {
00232           if ( next_start->status()==-1) 
00233           {
00234             next_start->status(0);
00235             q.push(next_start); 
00236             next_start=next_start->vlist;
00237             break;
00238           }
00239           next_start=next_start->vlist;
00240         }
00241       }
00242 
00243         if (next_start==NULL)
00244           return true;
00245         else
00246           return false;
00247     }
00248   
00249   void next()
00250     {
00251       
00252       if ( q.empty() )
00253       {
00254         
00255         while( next_start!=NULL)
00256         {
00257           if ( next_start->status()==-1) 
00258           {
00259             next_start->status(0);
00260             q.push(next_start); 
00261             next_start=next_start->vlist;
00262             break;
00263           }
00264           next_start=next_start->vlist;
00265         }
00266         
00267         if (next_start==NULL)// Finished
00268         {
00269           current= NULL; //isDone
00270           return;
00271         }
00272         
00273       }
00274       
00275       // q not empty
00276       current= q.top();
00277       q.pop();
00278       
00279       gNode<T>* t=current;       
00280       while(t->next!=NULL)
00281       {
00282         if ( t->next->status() == -1 )
00283         {
00284           t->next->status(0); // mark as visited 
00285           q.push(t->next->start); 
00286         }
00287         t=t->next;
00288       }
00289       
00290       return;
00291     }
00292     
00293   bool isDone()
00294     {
00295       return current == NULL;
00296     }
00297   
00298   gNode<T> * currentItem()
00299     {
00300       return current;
00301     }
00302 };
00303   
00304 template<class T>
00305 GraphDfsIter<T> *Graph<T>::createIterator() const
00306 {
00307   return new GraphDfsIter<T>(this);
00308 }
00309 
00311 template<class T>
00312  gNode<T>* Graph<T>::push_vertex(T val,int i)// i: sets aux parameter
00313 {
00314  gNode<T>* temp=new gNode<T>(val);
00315  temp->aux(i);
00316 
00317    nvertices++;
00318    if(head==NULL)
00319     {
00320      head=temp;
00321      head->me=temp;
00322      return temp;
00323     }
00324 
00325    gNode<T>* t=head;
00326    while(t->vlist!=NULL)
00327     t=t->vlist;
00328 
00329    t->vlist=temp;
00330    temp->start=temp;
00331    temp->me=temp;
00332    return temp;
00333 }
00334 
00336 template<class T>
00337 void Graph<T>::push_edge(T v_val,T e_val)
00338 {
00339   if(head==NULL)
00340     return;
00341   nedges++;
00342   
00343   gNode<T>* t=head;
00344   
00345   while(t!=NULL) //find vertex v
00346   {
00347      if(t->data==v_val)
00348      {  
00349        gNode<T>* temp=new gNode<T>(e_val);
00350        
00351        while(t->next!=NULL)
00352          t=t->next;
00353        t->next=temp;// add e to v's neighbors
00354        
00355        t=head;//update node info
00356        while(t!=NULL)
00357        {
00358          if(t->data==e_val)
00359          {
00360            temp->me=t->me;
00361            t->me=temp;               
00362            //temp->vlist=t->vlist;
00363            temp->start=t;
00364          }
00365          t=t->vlist;
00366        }
00367        
00368        return;
00369      }
00370      t=t->vlist;
00371   }
00372 }
00373 
00375 template<class T>
00376 void Graph<T>::vertex_list( Seq<T>& v) const 
00377 {
00378   gNode<T>* t= head;
00379   
00380   while(t!=NULL)
00381   {
00382     v << t->data;
00383     t=t->vlist;
00384   }
00385 }
00386 
00387 // i,j are added consecutively in the list iff there is the edge (i,j)
00388 template<class T>
00389 void Graph<T>::edge_list (Seq<T>& e) const 
00390 {
00391   gNode<T>*s, *t=head;
00392   while( t!=NULL)
00393   {
00394     s=t;
00395     while ( s->next!=NULL)
00396     {
00397       e<< t->data << s->next->data ;
00398       s=s->next;
00399     }
00400     t=t->vlist;
00401   }
00402 }
00403 
00404 // Neighbors of vertex v_val
00405 template<class T>
00406 Seq<T> Graph<T>::neighbors ( T v_val)
00407 {
00408     Seq<T> e;
00409     gNode<T>*s, *t=head;
00410     while( t!=NULL)
00411     {
00412       if(t->data==v_val)
00413       {         
00414         s=t;
00415            while ( s->next!=NULL)
00416            {
00417              //e<< t->data << s->next->data ;
00418              e<< s->next->data ;
00419              s=s->next;
00420            }
00421       }
00422       t=t->vlist;
00423     }
00424     return e;
00425 }
00426 
00427 // Returns a neighbor of vertex val
00428 template<class T> inline T
00429 Graph<T>::next(T val) const {
00430   gNode<T> *t=head;
00431   while( t!=NULL){
00432     if(t->data==val)
00433     {   if (t->next==NULL)
00434         std::cout<<"no neighbor!"<<std::endl;
00435       return t->next->data;
00436     }
00437     t=t->vlist;
00438   }
00439   std::cout<< "Node not in graph."<<std::endl;
00440   return NULL;
00441 }
00442 
00443 // true iff val is a node of the graph
00444 template<class T> inline bool
00445 Graph<T>::member(T val) const {
00446   gNode<T> *t=head;
00447   while( t!=NULL)
00448     if(t->data==val)
00449       return true;
00450     else
00451       t=t->vlist;
00452   return false;
00453 }
00454 
00455 
00456 
00457 // call as              dfs( &discover ) to run DFS.
00458 template<class T>
00459 void Graph<T>::discover(gNode<T> * v)
00460 {
00461  //             std::cout<< "m_status="<< t->m_status<<std::endl;
00462 }
00463 
00465 template<class T>
00466 void Graph<T>::delete_edge(T v_val,T e_val)
00467 {
00468   if(head==NULL)
00469     return;
00470   
00471   gNode<T> *s, *t=head;
00472   
00473   while(t!=NULL)
00474   {                  
00475     if(t->data==v_val)         
00476     {                         
00477       s=t;
00478       t=t->next;
00479       while(t!=NULL)
00480       {               
00481         if(t->data==e_val)
00482          {           
00483            s->next=t->next;
00484            t->vlist=NULL; 
00485            delete t;
00486            nedges--;
00487            return;
00488          }
00489         s=t;
00490         t=t->next;
00491       }
00492       return;                                            
00493     }
00494     t=t->vlist;
00495   }
00496   
00497 }
00498 
00500 template<class T>
00501 void Graph<T>::delete_vertex(T v_val)
00502 {
00503   if(head==NULL)
00504     return;
00505   nvertices--;
00506   
00507   gNode<T>* e=head;
00508   
00509   // Delete edges from other vertices lists
00510   while(e!=NULL)
00511      {
00512        delete_edge(e->data,v_val);
00513        e=e->vlist;
00514      }
00515   
00516   // Delete incident edges
00517   e=head;
00518   while(e!=NULL)
00519      {
00520        delete_edge(v_val,e->data);
00521        e=e->vlist;
00522      }
00523   
00524   //Delete Vertex
00525   if(head->data==v_val)
00526   {
00527     gNode<T>* temp=head;
00528     head=head->vlist;
00529     delete temp;
00530     return;
00531   }
00532   
00533   gNode<T>* p1=head->vlist;
00534   gNode<T>* p2=head;
00535   
00536   while(p1!=NULL)
00537   {
00538     if(p1->data==v_val)
00539     {
00540       p2->vlist=p1->vlist;
00541       p1=NULL;
00542       delete p1;
00543       return;
00544     }
00545     p2=p1;
00546     p1=p1->vlist;
00547   }
00548 }
00549 
00550 
00551 template<class T>
00552 gNode<T> * Graph<T>::get_start_node()
00553 {
00554   return head;
00555 }
00556 
00557 template<class T>
00558 bool Graph<T>::set_start_node(T& val)
00559 {
00560   gNode<T>* k=head;
00561   
00562   while(k->vlist!=NULL)  //check that vertex exists
00563   {
00564     if(k->vlist->data==val)
00565       break;
00566     k=k->vlist;
00567   }
00568   if (k->vlist==NULL) return false;
00569   
00570   gNode<T> *u= k->vlist;
00571   k->vlist  = u->vlist;
00572   u->vlist  = this->head;
00573   this->head= u;
00574 }
00575 
00576 template<class T>
00577 bool Graph<T>::set_start_node(T& v_val,T& e_val)
00578 {
00579   gNode<T>* k=this->head->next;
00580   
00581   if (!set_start_node(v_val)) return false;
00582   
00583   while(k->next!=NULL)
00584   {
00585     if(k->next->data==e_val)
00586       break;
00587     k=k->next;
00588   }
00589   if (k->next==NULL) return false;
00590   
00591   gNode<T> *u= k->next;
00592   k->next  = u->next;
00593   u->next  = this->head->next;
00594   this->head->next= u;
00595 }
00596 
00597 
00599 
00601 template<class T>
00602 void Graph<T>::dfs( func fp )
00603 {
00604   gNode<T>* t=head;
00605   
00606   while(t!=NULL)
00607   {
00608     t.status(-1);
00609     t=t->vlist;
00610   }
00611   
00612   t=head;
00613   while(t!=NULL)
00614   {
00615     if (t->status()==-1) dfs_walk(t,fp);
00616     t=t->vlist;
00617   }
00618 }
00619 
00620 template<class T>
00621 void Graph<T>::dfs_walk(gNode<T> * s, func fp)
00622 {
00623   NODESTACK q;
00624   gNode<T> * t;
00625   
00626   q.push(s);
00627   s->status(0);                  // mark as visited
00628   
00629   while ( !q.empty() )
00630   {
00631     t=q.top();
00632     q.pop();
00633     
00634     if (fp!=NULL) (*fp)(t);       // run operation on node
00635     //std::cout<< t->data<<std::endl;
00636     
00637     while(t->next!=NULL)
00638     {
00639       if (t->next->status()==-1)
00640       {
00641         t->status(0); // mark as visited 
00642         q.push(t->next->start); 
00643       }
00644       t=t->next;
00645     }
00646   }
00647 }
00648 
00650 
00652 template<class T>
00653 void Graph<T>::dfs(Seq<T>& out)
00654 {
00655   gNode<T>* t=head;
00656   
00657   while(t!=NULL)
00658   {
00659     t->status(-1);
00660     t=t->vlist;
00661   }
00662   
00663   t=head;
00664   while(t!=NULL)
00665   {
00666     if (t->status()==-1) 
00667       dfs_walk(t,out);
00668     t=t->vlist;
00669   }
00670 }
00671 
00672 template<class T>
00673 void Graph<T>::dfs_walk(gNode<T> * s, Seq<T>& out)
00674 {
00675   NODESTACK q;
00676   gNode<T> * t;
00677   
00678   q.push(s);
00679   
00680   while ( !q.empty() )
00681   {
00682     t=q.top();
00683     q.pop();
00684     if ( t->status()==-1)
00685     {
00686     out<< t->data; // output node data
00687     t->status(0); // mark as visited 
00688     }
00689      while(t->next!=NULL)
00690      {
00691        if ( t->next->status() == -1 )
00692        {
00693          q.push(t->next->start); 
00694        }
00695        t=t->next;
00696      }
00697 
00698   }
00699 }
00700 
00702 
00704 template<class T>
00705 gNode<T>* Graph<T>::dfs( test_node fp )
00706 {
00707   gNode<T>* t=head;
00708   
00709   while(t!=NULL)
00710   {
00711     t->status(-1);
00712     t=t->vlist;
00713   }
00714   
00715   t=head;
00716   while(t!=NULL)
00717   {
00718     if (t->status()==-1) 
00719     {
00720       NODESTACK q;
00721       gNode<T> * s;
00722       
00723       q.push(t);
00724       t->status(0);    // mark as visited
00725       
00726       while ( !q.empty() )
00727       {
00728         s=q.top();
00729         q.pop();
00730         
00731 
00732         if (fp!=NULL)
00733           if ( (*fp)(s) ) // check node
00734             return s;
00735         
00736         while(t->next!=NULL)
00737         {
00738           if (t->next->status()==-1)
00739           {
00740             t->status(0); // mark as visited
00741             q.push(t->next->start); 
00742           }
00743           
00744           t=t->next;
00745         }
00746       }
00747     }
00748     t=t->vlist;
00749   }
00750   
00751   return NULL;
00752 }
00754   
00755 // Function to be passed to the DFS procedure
00756 template<class T>
00757 void write_edge(gNode<T>* v)
00758 {
00759   std::cout<<"Ok"<<std::endl;
00760 }
00761 
00762 template<class O, class V> struct viewer; struct axel;
00763 
00764 template<class K, class T> Viewer&
00765 operator<<(Viewer& out, const Graph<T>& g) {
00766   
00767 
00768   //Seq<T> vertices;
00769 
00770   if (g.nbe()==0) return out;
00771   
00772   Seq<T> edges;
00773   g.edge_list(edges);
00774   
00775   out<<" <curve type=\"mesh\">\n<vect>\nVECT\n";
00776   out<<g.nbe()<<" "
00777     //<<g.nbv()<<" "
00778      <<2*g.nbe()<<" "
00779      <<g.nbe()<<"\n";
00780   
00781   for(unsigned i=0; i<g.nbe();i+=2) out<<"2 ";//
00782   out<<"\n";
00783   
00784   // for(unsigned i=0; i<g.nbv();i++) out<<"1 ";
00785   // out<<"\n";
00786   for(unsigned i=0; i<g.nbe();i+=2) out<<"1 ";//
00787   out<<"\n";
00788 
00789   //g.dfs( vertices );
00790   //print edges
00791   // unsigned i;
00792   // for (i=1;i<vertices.size(); i++)
00793   // {
00794   //            out <<vertices[i-1]->x()<<" "<<vertices[i-1]->y()  <<" 0 "
00795   //                            <<vertices[i]->x()  <<" "<<vertices[i]->y()<<" 0 "
00796   //                            <<"\n";
00797   // }
00798   //            out <<vertices[i-1]->x()<<" "<<vertices[i-1]->y()  <<" 0 "
00799   //                            <<vertices[0]->x()  <<" "<<vertices[0]->y()<<" 0 "
00800   //                            <<"\n";
00801   
00802       
00803   //print edges
00804   for (unsigned i=0;i<edges.size(); i+=2)
00805     {
00806       out <<edges[i]->x()  <<" "<<edges[i]->y()  <<" 0 "
00807           <<edges[i+1]->x()<<" "<<edges[i+1]->y()<<" 0 "
00808           <<"\n";
00809     }
00810   
00811   
00812   for(unsigned i=0; i<g.nbe();i++) 
00813     out<< "0.314 0.979 1 1\n";
00814   
00815   out<<" </vect>\n </curve>\n";
00816   
00817   return out;
00818 }
00819 
00820 
00821 } ; // namespace shape
00822 } ; // namespace mmx
00823 
00824 #undef NODESTACK
00825 #undef Viewer