[Lemon-commits] [lemon_svn] alpar: r3 - in hugo/trunk/src: include work

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:36:47 CET 2006


Author: alpar
Date: Sat Dec  6 20:32:27 2003
New Revision: 3

Added:
   hugo/trunk/src/include/graph.h
   hugo/trunk/src/include/oldgraph.h
   hugo/trunk/src/work/
   hugo/trunk/src/work/graphdemo.cc
   hugo/trunk/src/work/makefile

Log:
src/demo/graph.h: a proposal for a graph implementation
src/demo/graphdemo.cc: a simle demo using graph.h


Added: hugo/trunk/src/include/graph.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/include/graph.h	Sat Dec  6 20:32:27 2003
@@ -0,0 +1,381 @@
+// -*-mode: c++; -*-
+#ifndef __GRAPH_H_
+#define __GRAPH_H_
+
+//inline void *operator new(size_t s, void *p) { return p; }
+#include <new>
+
+namespace NEGRO 
+{
+  using namespace std;
+  
+#include "oldgraph.h"
+  
+  template <class N, class E> class Graph : protected OldGraph<N,E>
+  {
+  public:
+    typedef E EdgeType;
+    typedef N NodeType;
+    
+    class EdgePoint
+    {
+    public:
+      NEGRO::EdgePoint e;
+      bool isValid() { return e; }
+    };
+    
+    class InEdgePoint : public EdgePoint {};
+    class OutEdgePoint : public EdgePoint {};
+    class BiEdgePoint : public EdgePoint {};
+    class SymEdgePoint : public EdgePoint {};
+    
+    typedef int NodePoint;
+    
+    class NodeIterator;
+    
+    class EdgeIterator;
+    class InEdgeIterator;
+    class OutEdgeIterator;
+    class BiEdgeIterator;
+    class SymEdgeIterator;
+    class AllEdgeIterator;
+    
+    class FirstAnythingTypeNode;
+
+    friend class NodeIterator;
+    friend class EdgeIterator;
+    friend class InEdgeIterator;
+    friend class OutEdgeIterator;
+    friend class BiEdgeIterator;
+    friend class SymEdgeIterator;
+    friend class AllEdgeIterator;
+    
+    class NodeIterator
+    {
+      Graph<N,E> *G;  //operator*() miatt kell!!!
+      int n;     //nem kellene, ha itt mutato lenne!!
+    public:    
+      
+      NodeIterator() {;} 
+      NodeIterator(const NodeIterator &i) {G=i.G;n=i.n;}
+      
+      NodeIterator &GoNext() { n=G->NextNode(n); return *this;}
+      NodeIterator Next() const { return NodeIterator(*this).GoNext();}
+      NodeIterator &operator++() { return GoNext();} 
+      NodeIterator operator++(int)
+      {NodeIterator tmp(*this); GoNext(); return tmp;}
+      bool isValid() { return n!=INVALID; }
+      
+      N &operator*() const { return G->Data(n); }
+      N *operator->() const { return &G->Data(n); }
+      
+      bool operator==(const NodeIterator &i) const {return n==i.n;}
+      bool operator!=(const NodeIterator &i) const {return n!=i.n;}
+      
+      friend class Graph;
+      friend class EdgeIterator;
+      friend class InEdgeIterator;
+      friend class OutEdgeIterator;
+      friend class BiEdgeIterator;
+      friend class SymEdgeIterator;
+      friend class AllEdgeIterator;
+      friend class FirstAnythingTypeNode;
+
+      //Nem kellene egy:
+      //      static NodeIterator &GetInvalid();  ?
+    };
+    
+    class EdgeIterator
+    {
+      
+      Graph<N,E> *G; //Itt baj van!!!!! operator*() miatt kell!
+      //Ez csak kicsit baj, de:
+      // Meg a From() es To() miatt!!!!!!!!!!
+      
+      NEGRO::EdgePoint e;
+      
+    public:
+      EdgeIterator() {;} //Kell inicializalni? (Nem)
+      EdgeIterator(const EdgeIterator &i) {G=i.G;e=i.e;}
+      
+      // Lehet, hogy ez a ketto nem kell!!!
+      
+      NodeIterator From() const {NodeIterator i;i.G=G;i.n=e->From();return i;}
+      NodeIterator To() const {NodeIterator i;i.G=G;i.n=e->To();return i;}
+      
+      bool isValid() {return e;}
+      E &operator*() const { return G->Data(e); }
+      E *operator->() const { return &G->Data(e); }
+      
+      //operator const OutEdgeIterator ();
+      //operator const InEdgeIterator ();
+      //operator const BiEdgeIterator ();
+      //operator const SymEdgeIterator(); //Ez kerdeses, mit csinal
+      
+      bool operator==(const EdgeIterator &i) const {return e==i.e;}
+      bool operator!=(const EdgeIterator &i) const {return e!=i.e;}
+      
+      friend class Graph;
+      friend class InEdgeIterator;
+      friend class OutEdgeIterator;
+      friend class BiEdgeIterator;
+      friend class SymEdgeIterator;
+      friend class AllEdgeIterator;
+    };
+    
+    class BiEdgeIterator : public EdgeIterator
+    {
+    public:
+      BiEdgeIterator &GoNextIn()  { e=e->NextIn(); return *this;}
+      BiEdgeIterator &GoNextOut() { e=e->NextOut(); return *this;}
+      BiEdgeIterator NextIn() const  {return BiEdgeIterator(*this).GoNextIn();}
+      BiEdgeIterator NextOut() const {return BiEdgeIterator(*this).GoNextOut();}
+      
+      operator InEdgeIterator ()
+      {InEdgeIterator i; i.G=G;i.e=e;return i;}
+      operator OutEdgeIterator ()
+      {OutEdgeIterator i; i.G=G;i.e=e;return i;}
+      //operator const SymEdgeIterator ()
+      
+      friend class Graph;
+    };
+    
+    class InEdgeIterator : public EdgeIterator
+    //Ne a BiEdgeIterator-bol szarmazzon?
+    {
+    public:
+      InEdgeIterator &GoNext() { e=e->NextIn(); return *this;}
+      InEdgeIterator Next() const {return InEdgeIterator(*this).GoNext();}
+      InEdgeIterator &operator++() { return GoNext();}
+      InEdgeIterator operator++(int)
+      {InEdgeIterator tmp(*this); GoNext(); return tmp;}
+      
+      operator const OutEdgeIterator ()
+      {OutEdgeIterator i; i.G=G;i.e=e;return i;}
+      operator const BiEdgeIterator ()
+      {EdgeIterator i; i.G=G;i.e=e;return i;}
+      //      operator const SymEdgeIterator ();
+      
+      NodeIterator Anode() const {return To();}
+      NodeIterator Bnode() const {return From();}
+      
+      friend class Graph;
+    };
+    
+    class OutEdgeIterator : public EdgeIterator
+    {
+    public:
+      OutEdgeIterator &GoNext() { e=e->NextOut(); return *this;}
+      OutEdgeIterator Next() const {return OutEdgeIterator(*this).GoNext();}
+      OutEdgeIterator &operator++() { return GoNext();}
+      OutEdgeIterator operator++(int)
+      {OutEdgeIterator tmp(*this); GoNext(); return tmp;}
+      
+      NodeIterator Anode() const {return From();}
+      NodeIterator Bnode() const {return To();}
+      
+      operator const InEdgeIterator ()
+      {InEdgeIterator i; i.G=G;i.e=e;return i;}
+      operator const BiEdgeIterator ()
+      {BiEdgeIterator i; i.G=G;i.e=e;return i;}
+      //operator const SymEdgeIterator(); 
+      
+      friend class Graph;
+    };
+    
+    class SymEdgeIterator : public EdgeIterator
+    {
+      NodeIterator n;  // Itt ketszer van a G
+      
+    public:
+      SymEdgeIterator &GoNext() { e=e->NextEdge(n.n); return *this;}
+      SymEdgeIterator Next() const {return SymEdgeIterator(*this).GoNext();}
+      SymEdgeIterator &operator++() { return GoNext();}
+      SymEdgeIterator operator++(int)
+      {SymEdgeIterator tmp(*this); GoNext(); return tmp;}
+      
+      NodeIterator Anode() const {return n;}
+      NodeIterator Bnode() const {return n.n==From().n?To():From();}
+      
+      operator const InEdgeIterator ()
+      {InEdgeIterator i; i.G=G;i.e=e;return i;}
+      operator const OutEdgeIterator ()
+      {OutEdgeIterator i; i.G=G;i.e=e;return i;}
+      operator const BiEdgeIterator ()
+      {BiEdgeIterator i; i.G=G;i.e=e;return i;}
+      
+      friend class Graph;
+    };
+    
+    class AllEdgeIterator : public EdgeIterator
+    {
+      NodeIterator n;  // Itt ketszer van a G
+      
+    public:
+      AllEdgeIterator &GoNext()
+      {
+	e=e->NextOut();
+	if(!e && (++n).isValid()) e=G->OldGraph<N,E>::FirstOut(n.n);
+	return *this;
+      }
+      AllEdgeIterator Next() const {return AllEdgeIterator(*this).GoNext();}
+      AllEdgeIterator &operator++() { return GoNext();}
+      AllEdgeIterator operator++(int)
+	{AllEdgeIterator tmp(*this); GoNext(); return tmp;}
+      
+      
+      NodeIterator Anode() const {return n;}
+      NodeIterator Bnode() const {return n.n==From().n?To():From();}
+      
+      operator const InEdgeIterator ()
+      {InEdgeIterator i; i.G=G;i.e=e;return i;}
+      operator const OutEdgeIterator ()
+      {OutEdgeIterator i; i.G=G;i.e=e;return i;}
+      operator const BiEdgeIterator ()
+      {BiEdgeIterator i; i.G=G;i.e=e;return i;}
+      
+      friend class Graph;
+    };
+    
+    typedef NodeIterator DeletingNodeIterator;
+    typedef EdgeIterator DeletingEdgeIterator;
+    typedef BiEdgeIterator DeletingBiEdgeIterator;
+    typedef OutEdgeIterator DeletingOutEdgeIterator;
+    typedef InEdgeIterator DeletingInEdgeIterator;
+    typedef SymEdgeIterator DeletingSymEdgeIterator;
+    
+    const NodeIterator &FirstNode()
+    {
+      NodeIterator i;
+      i.G=this;i.n=OldGraph<N,E>::FirstNode();
+      return i;
+    }
+    
+    void GetFirst(NodePoint &p)   { p=OldGraph<N,E>::FirstNode(); }
+    
+    void GetFirst(InEdgePoint &p,const NodePoint &n)
+    { p=OldGraph<N,E>::FirstIn(n); }
+    void GetFirst(OutEdgePoint &p,const NodePoint &n)
+    { p=OldGraph<N,E>::FirstOut(n); }
+    void GetFirst(SymEdgePoint &p,const NodePoint &n)
+    { p=OldGraph<N,E>::FirstEdge(n); }
+    void GetFirst(EdgePoint &p) //Vegigmegy mindenen
+    { p.e=NodeNum()?OldGraph<N,E>::FirstOut(OldGraph<N,E>::FirstNode()):NULL;}
+
+    void GetFirst(NodeIterator &i) { i.G=this;i.n=OldGraph<N,E>::FirstNode();}
+    
+    void GetFirst(InEdgeIterator &i,const NodeIterator &n)
+    { i.G=this;i.e=OldGraph<N,E>::FirstIn(n.n); }
+    void GetFirst(OutEdgeIterator &i,const NodeIterator &n)
+    { i.G=this;i.e=OldGraph<N,E>::FirstOut(n.n); }
+    void GetFirst(SymEdgeIterator &i,const NodeIterator &n)
+    { i.G=this;i.e=OldGraph<N,E>::FirstSym(n.n); }
+    void GetFirst(AllEdgeIterator &i) //Vegigmegy mindenen
+    {
+      i.G=this;
+      GetFirst(i.n);
+      i.e=OldGraph<N,E>::NodeNum()?OldGraph<N,E>::FirstOut(i.n.n):NULL;
+    }  
+    
+    
+    
+    //Vagy beginnode()?
+    const DeletingEdgeIterator &FirstOut(const NodeIterator &n)
+    {
+      EdgeIterator i;
+      i.G=n.G;i.edge=n.G->OldGraph<N,E>::FirstOut(n.n);
+      return i;
+    }
+    const DeletingEdgeIterator &FirstIn(const NodeIterator &n)
+    {
+      EdgeIterator i;
+      i.G=n.G;i.edge=n.G->OldGraph<N,E>::FirstIn(n.n);
+      return i;
+    }
+    const DeletingSymEdgeIterator &FirstSym(const NodeIterator &n)
+    {
+      EdgeIterator i;
+      i.G=n.G;i.n=n.n;
+      i.edge=n.G->OldGraph<N,E>::FirstEdge(n.n);
+      return i;
+    }
+    
+    //    class FirstAnythingType;
+    //    friend class FirstAnythingType;
+
+    class FirstAnythingTypeNode
+    {
+      NodeIterator n;
+    public:
+      FirstAnythingTypeNode(NodeIterator i) : n(i) {}
+
+      operator const InEdgeIterator () const
+      {InEdgeIterator i; n.G->GetFirst(i,n);return i;}
+      operator const OutEdgeIterator () const
+      {OutEdgeIterator i; n.G->GetFirst(i,n);return i;}
+      operator const SymEdgeIterator () const
+      {SymEdgeIterator i; n.G->GetFirst(i,n);return i;}
+  
+      operator const InEdgePoint () const
+      {InEdgePoint i; n.G->GetFirst(i,n);return i;}
+      operator const OutEdgePoint () const
+      {OutEdgePoint i; n.G->GetFirst(i,n);return i;}
+      operator const SymEdgePoint () const
+      {SymEdgePoint i; n.G->GetFirst(i,n);return i;}
+    };
+    
+    class FirstAnythingType
+    {
+      Graph<N,E> *G;
+    public:
+      FirstAnythingType(Graph<N,E> *gg) : G(gg) {}
+
+      operator const AllEdgeIterator () const
+      {AllEdgeIterator i; G->GetFirst(i);return i;}  
+      operator const EdgePoint () const
+      {EdgePoint i; G->GetFirst(i);return i;}
+      operator const NodeIterator () const
+      {NodeIterator i; G->GetFirst(i);return i;}  
+      operator const NodePoint () const
+      {NodePoint i; G->GetFirst(i);return i;}
+    } _FST;
+    
+    //    const NodeIterator First() {NodeIterator i;GetFirst(i); return i;}
+    FirstAnythingTypeNode First(NodeIterator &i)
+    {FirstAnythingTypeNode t(i); return t;}
+    const FirstAnythingType &First() {return _FST;}
+    
+    // LastNode() vagy endnode() stb. Nem kell?
+    
+    DeletingNodeIterator AddNode()
+    {
+      DeletingNodeIterator i;
+      i.G=this; i.n=OldGraph<N,E>::AddNode();
+      return i;
+    }
+    DeletingEdgeIterator
+    AddEdge(const NodeIterator from,const NodeIterator to)
+    {
+      DeletingEdgeIterator i;
+      i.G=this;i.e=OldGraph<N,E>::AddEdge(from.n,to.n);return i;
+    }
+    
+    void Delete(DeletingNodeIterator n) {n.G->OldGraph<N,E>::Delete(n.n);}
+    void Delete(DeletingEdgeIterator e) {e.G->OldGraph<N,E>::Delete(e.e);}
+    
+    int NodeNum() { OldGraph<N,E>::NodeNum(); }
+    int Clean() { OldGraph<N,E>::Clean(); }
+
+    Graph() : _FST(this) {}
+  };
+  
+  /*   Ez itt a fiam kommentje:
+       <v n  nnnnnnnnnnnnnncncccccccccccccccccvvvvvv
+       vvnvnvnvnvnvvnnvnvnvnnvnbbbvfffffvvffffffffffffffffffffz
+       <<  < < <  < <  <   .cx..x.c.cc.c          
+       mcmn   
+  */
+  
+}
+
+#endif

Added: hugo/trunk/src/include/oldgraph.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/include/oldgraph.h	Sat Dec  6 20:32:27 2003
@@ -0,0 +1,551 @@
+// -*-mode: c++; -*-
+#ifndef __OLDGRAPH_H_
+#define __OLDGRAPH_H_
+
+#include <stdio.h>
+
+//#include <new>
+
+#define INVALID -1
+#define FREE_NODE INVALID
+
+#define EDGE_BLOCK_SIZE 100
+#define INIT_NODES_SIZE 10
+#define INIT_EDGES_BLOCK_MAX 10
+
+#define foreachNode(n,G) for((n)=(G).FirstNode();(n)!=INVALID;(n)=(G).NextNode(n))
+#define foreachIn(e,G,n)  for((e)=(G).FirstIn(n) ;(e);(e)=(G).NextIn(e) )
+#define foreachOut(e,G,n) for((e)=(G).FirstOut(n);(e);(e)=(G).NextOut(e))
+#define foreachEdge(e,G,n) for((e)=(G).FirstEdge(n);(e);(e)=(G).NextEdge((n),(e)))
+
+struct EdgeIndex { int block,index; };
+
+extern EdgeIndex InvalidIndex;
+
+class EdgeCorp;
+typedef EdgeCorp *EdgePoint;
+
+class EdgeCorp {
+ public:
+  int from,to;      //from==INVALID <=> this is a free edge.
+  EdgePoint previn,nextin,prevout,nextout;
+  EdgeIndex index;
+
+  int From() { return from; }
+  int To() { return to; }
+  EdgePoint NextIn() { return nextin; }
+  EdgePoint NextOut() { return nextout; }
+};
+
+inline int From(EdgePoint e) { return e->from; }
+inline int To(EdgePoint e) { return e->to; }
+inline EdgePoint NextIn(EdgePoint e) { return e->nextin; }
+inline EdgePoint NextOut(EdgePoint e) { return e->nextout; }
+
+
+//////////////////////////////////////////////////////////////////////
+//   OLDGRAPH TEMPLATE
+//////////////////////////////////////////////////////////////////////
+// Copy Constructor should be provided for N
+
+//class Graph;
+//class Graph::NodeIterator; //Nem megy. Disznosag!
+template <class N, class E> class OldGraph
+{
+
+  //  friend class NEGRO::Graph::NodeIterator; //Nem megy. Disznosag!
+
+
+  class nodes_t;
+  friend class OldGraph::nodes_t;
+  class edge_block;
+  friend class OldGraph::edge_block;
+  
+  class edge_t : public EdgeCorp {
+  public:
+    //edge_t *previn,*nextin,*prevout,*nextout;
+    union {
+      int _align;
+      char data[sizeof(E)];
+    };
+  };
+
+  class nodes_t {
+  public:
+    union {
+      int _align;
+      char data[sizeof(N)];
+    };
+    int indeg,outdeg;           // indeg==FREE_NODE <=> this node is free.
+    EdgePoint firstin, firstout;
+    int prev,next;
+
+    void Copy(nodes_t &n) 
+    {
+      indeg = n.indeg; outdeg = n.outdeg;
+      firstin = n.firstin; firstout = n.firstout;
+      prev = n.prev; next = n.next;
+      if(n.indeg!=FREE_NODE) new(data) N(*(N*)(n.data));
+      //      if(n.indeg!=FREE_NODE) {
+      //	new(data) N;
+      //	(*(N*)(data))=(*(N*)(n.data));
+      //      }
+    }
+    
+  } *nodes;
+  int nodenum, nodes_size;
+  int firstnode, freenodes;
+  class edge_block {
+  public:
+    //edge_block *next;
+    //    char fields[sizeof(edge_t)*EDGE_BLOCK_SIZE];
+    edge_t fields[EDGE_BLOCK_SIZE];    
+  } **edges;
+  int edge_block_num,edge_block_max;
+  EdgePoint freeedges;
+
+  void setup(int nosi = INIT_NODES_SIZE);
+  void destroy();
+  void inc_nodes_size(int n);
+  
+ public:
+  int NodeNum() {return nodenum;};
+  int EdgeNum();
+  int MaxNode() {return nodes_size;};
+  int FirstNode() {return firstnode;};
+  int NextNode(int n) {return nodes[n].next;};
+  int PrevNode(int n) {return nodes[n].prev;};
+  N& operator()(int n) {return *(N*)(nodes[n].data);};
+  N& Data      (int n) {return *(N*)(nodes[n].data);};
+  int AddNode();
+  void AddNodeBlock(int n) {for(int i=0;i<n;i++) AddNode();}
+  int AddNode(int n);
+  void Delete(int n);
+  int isaNode(int n) {return n>=0&&n<nodes_size&&nodes[n].indeg!=FREE_NODE;};
+  
+  int InDeg(int n) {return nodes[n].indeg;};
+  int OutDeg(int n) {return nodes[n].outdeg;};
+  EdgePoint FirstIn(int n) {return nodes[n].firstin;};
+  EdgePoint FirstOut(int n) {return nodes[n].firstout;};
+
+  E& operator()(EdgePoint e) {return *(E*)(((edge_t*)e)->data);};
+  E& Data      (EdgePoint e) {return *(E*)(((edge_t*)e)->data);};
+  int From(EdgePoint e) {return e->from;};
+  int To(EdgePoint e) {return e->to;};
+  EdgePoint NextIn(EdgePoint e)
+    {return e->nextin;};
+  EdgePoint NextOut(EdgePoint e)
+    {return e->nextout;};
+  EdgePoint AddEdge(int f, int t);
+  void Delete(EdgePoint e);
+  EdgePoint Edge(int f,int t);
+  //  EdgePoint Edge(E &d)
+  //    {return (EdgePoint)(((char*)&d)-(char*)&(((edge_t*)NULL)->data));};
+  E& operator()(int f, int t) {return *(E*)(((edge_t*)Edge(f,t))->data);};
+  E& Data(int f, int t) {return *(E*)(((edge_t*)Edge(f,t))->data);};
+  void Delete(int f, int t) {Delete(Edge(f,t));};
+  void Reverse(EdgePoint e);
+
+  // Functions for EdgeIndex
+  
+  EdgePoint Edge(EdgeIndex i)
+    { return (EdgePoint)(edges[i.block]->fields+i.index);};
+  EdgeIndex Index(EdgePoint e) { return e->index;};
+  EdgeIndex Index(int f, int t) { EdgePoint e; return Edge(f,t)->index; }
+  void Delete(EdgeIndex i) { Delete(Edge(i));};
+  E& operator()(EdgeIndex i)
+     {return *(E*)(edges[i.block]->fields[i.index].data);};
+  E& Data(EdgeIndex i)
+     {return *(E*)(edges[i.block]->fields[i.index].data);};
+  EdgePoint AddEdge(int f, int t,EdgeIndex in);
+  
+
+  
+  // Operators for symmetric graphs:
+
+  EdgePoint FirstEdge(int n)
+    { return (EdgePoint)(FirstIn(n)?FirstIn(n):FirstOut(n));};
+  EdgePoint NextEdge(int n,EdgePoint e)
+    { return From(e)==n?NextOut(e):(NextIn(e)?NextIn(e):FirstOut(n)); };
+  int Opposite(EdgePoint e,int n)
+    { return From(e)+To(e)-n; };
+  
+  // Initializers, destructors
+       
+  OldGraph() {setup();};
+  OldGraph(int nosi) {setup(nosi);};
+  OldGraph(OldGraph<N,E> &H) {setup();operator=(H);};
+  ~OldGraph() {destroy();};  
+  void Clean(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);};
+  void Clear(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);};
+
+  void DeleteEdges();
+    
+  OldGraph<N,E> &operator=(OldGraph<N,E> &H);
+};
+
+//////////////////////////////////////////////////////////////////////
+// Template Definitions
+//////////////////////////////////////////////////////////////////////
+
+//#include <stdio.h>
+
+//**********************************************************************
+//                          OldGraph definitions
+//**********************************************************************
+
+template<class N, class E> void OldGraph<N,E>::setup(int nosi) {
+  int i;
+
+  //Set up nodes
+  nodenum = 0;
+  nodes_size = nosi;
+  // nodes = (nodes_t*) new char[sizeof(nodes_t)*nodes_size];
+  nodes = (nodes_t*) new nodes_t [nodes_size];
+  for(i=0;i<nodes_size;i++)
+    {
+      nodes[i].prev=i-1;
+      nodes[i].next=i+1;
+      nodes[i].indeg=FREE_NODE;
+      nodes[i].outdeg=0;
+      nodes[i].firstin=nodes[i].firstout=NULL;
+    }
+  firstnode=nodes[0].prev=nodes[nodes_size-1].next=INVALID;
+  freenodes=0;
+  //Set up edge-list_template_type;
+  freeedges = NULL;
+  
+  edges = new edge_block* [edge_block_max=INIT_EDGES_BLOCK_MAX];
+  edge_block_num = 0;
+  
+}
+
+template<class N, class E> void OldGraph<N,E>::destroy()
+{
+  edge_block *oe;
+  int i;
+  
+  while(firstnode!=INVALID) Delete(firstnode);
+  delete [] nodes;
+  for(i=0;i<edge_block_num;i++) delete edges[i];
+  delete [] edges;
+}
+
+template<class N, class E> void OldGraph<N,E>::inc_nodes_size(int n)
+{
+  int i;
+  if(n<=nodenum) return;
+  
+  nodes_t *nn;
+//  nn = (nodes_t*) new char [sizeof(nodes_t)*n];
+  nn = (nodes_t*) new nodes_t [n];
+  for(i=0;i<nodes_size;i++)
+    {
+      nn[i].Copy(nodes[i]);
+      if(nodes[i].indeg!=FREE_NODE) ((N*)(nodes[i].data))->~N();
+    }
+  
+  delete [] nodes;
+  nodes = nn;
+  for(i=nodes_size;i<n;i++)
+    {
+      nodes[i].prev=i-1;
+      nodes[i].next=i+1;
+      nodes[i].indeg=FREE_NODE;
+      nodes[i].outdeg=0;
+      nodes[i].firstin=nodes[i].firstout=NULL;
+    }
+  nodes[nodes_size].prev=INVALID;
+  nodes[n-1].next=freenodes;
+  if(freenodes!=INVALID) nodes[freenodes].prev=n-1;
+  freenodes=nodes_size;
+  nodes_size=n;
+}
+
+template<class N, class E> OldGraph<N,E> &OldGraph<N,E>::operator=(OldGraph<N,E> &H)
+{
+  Clean();
+
+  int i;
+  EdgePoint e;
+  
+  for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i))
+    {
+      AddNode(i);
+      operator()(i)=H(i);
+    }
+  for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i))
+    for(e=H.FirstOut(i);e;e=H.NextOut(e))
+      operator()(AddEdge(i,H.To(e),H.Index(e)))=H(e);
+
+   return *this;
+}
+
+template<class N, class E> int OldGraph<N,E>::EdgeNum()
+{
+  int n=firstnode, m=0;
+  EdgePoint e;
+  while(n != INVALID)
+  {    
+    e=FirstOut(n);
+    while (e != NULL)
+    {
+      m++;
+      e=NextOut(e);
+    }
+    n=nodes[n].next;
+  }
+  return m;
+}
+
+template<class N, class E> int OldGraph<N,E>::AddNode()
+{
+  int i;
+  
+  if(freenodes==INVALID) inc_nodes_size(2*nodes_size);
+  
+  i=freenodes;
+  if(firstnode!=INVALID) nodes[firstnode].prev=i;
+  freenodes=nodes[i].next;
+  new(nodes[i].data) N;  //Explicit constructor call
+  nodes[i].next=firstnode;
+  nodes[i].prev=INVALID;
+  nodes[i].indeg=0;
+  firstnode=i;
+  if(freenodes!=INVALID) nodes[freenodes].prev=INVALID;
+  nodenum++;
+  return i;
+}
+
+template<class N, class E> int OldGraph<N,E>::AddNode(int n)
+{
+  int i;
+  
+  if(n>=nodes_size)
+    {
+      for(i=INIT_NODES_SIZE;i<=n;i*=2) ;
+      inc_nodes_size(i);
+    }
+  
+  if(nodes[n].indeg==FREE_NODE)
+    {
+      new(nodes[n].data) N;  //Explicit constructor call
+      if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev = nodes[n].prev;
+      if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next = nodes[n].next;
+      else freenodes = nodes[n].next;
+      
+      nodes[n].prev = INVALID;
+      if((nodes[n].next = firstnode)!=INVALID) nodes[firstnode].prev=n;
+      firstnode = n;
+      nodenum++;
+      nodes[n].indeg=0;
+    }
+  return n;
+}
+
+template<class N, class E> void OldGraph<N,E>::Delete(int n)
+{
+  if(n==INVALID||nodes[n].indeg==FREE_NODE) return;
+
+  EdgePoint e;
+  
+  while(e=FirstIn(n)) Delete(e);
+  while(e=FirstOut(n)) Delete(e);
+  
+  if(n==firstnode) firstnode=nodes[n].next;
+  if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next=nodes[n].next;
+  if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev=nodes[n].prev;
+  if(freenodes!=INVALID) nodes[freenodes].prev=n;
+  nodes[n].next=freenodes;
+  nodes[n].prev=INVALID;
+  nodes[n].indeg=FREE_NODE;
+  ((N*)(nodes[n].data))->~N();  //Explicit destructor call
+  freenodes=n;
+
+  nodenum--;
+}
+
+template<class N, class E> EdgePoint OldGraph<N,E>::AddEdge(int f, int t)
+{
+  int i;
+  edge_block *peb;
+  edge_block **ppeb;
+  edge_t *e;
+  
+  if(!freeedges)
+    {
+      if(edge_block_num>=edge_block_max)
+	{
+	  ppeb = new edge_block* [edge_block_max*=2];
+	  for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i];
+	  delete [] edges;
+	  edges = ppeb;
+	}
+      peb = new edge_block;
+      edges[edge_block_num] = peb;
+      
+      for(i=0;i<EDGE_BLOCK_SIZE;i++)
+	{
+	  ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1);
+	  ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1);
+	  ((edge_t*)peb->fields)[i].index.block = edge_block_num;
+	  ((edge_t*)peb->fields)[i].index.index = i;
+	  ((edge_t*)peb->fields)[i].from = INVALID;
+	}
+      ((edge_t*)peb->fields)[0].previn=
+	((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=NULL;
+      freeedges = (edge_t*)peb->fields;
+      edge_block_num++;
+    }
+  
+  e=(edge_t *)freeedges;
+  new (e->data) E;  //Explicit constructor call
+  freeedges=e->nextin;
+  if(freeedges) freeedges->previn=NULL;
+  
+  e->from=f; e->to=t;
+  e->previn=e->prevout=NULL;
+  e->nextin=nodes[t].firstin;
+  e->nextout=nodes[f].firstout;
+  if(nodes[t].firstin) nodes[t].firstin->previn=e;
+  if(nodes[f].firstout) nodes[f].firstout->prevout=e;
+  nodes[t].firstin=nodes[f].firstout=e;
+  nodes[t].indeg++; nodes[f].outdeg++;
+
+  return (EdgePoint)e;
+  
+}
+
+template<class N, class E>
+EdgePoint OldGraph<N,E>::AddEdge(int f, int t, EdgeIndex in)
+{
+  int i;
+  edge_block *peb;
+  edge_block **ppeb;
+  edge_t *e;
+  
+  while(edge_block_num<=in.block)
+    {
+      if(edge_block_num>=edge_block_max)
+	{
+	  ppeb = new edge_block* [edge_block_max*=2];
+	  for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i];
+	  delete [] edges;
+	  edges = ppeb;
+	}
+      peb = new edge_block;
+      edges[edge_block_num] = peb;
+      
+      for(i=0;i<EDGE_BLOCK_SIZE;i++)
+	{
+	  ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1);
+	  ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1);
+	  ((edge_t*)peb->fields)[i].index.block = edge_block_num;
+	  ((edge_t*)peb->fields)[i].index.index = i;
+	  ((edge_t*)peb->fields)[i].from = INVALID;
+	}
+      ((edge_t*)peb->fields)[0].previn=NULL;
+      ((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=freeedges;
+      if(freeedges)
+	freeedges->previn = ((edge_t*)peb->fields) + (EDGE_BLOCK_SIZE-1);
+      freeedges = (edge_t*)peb->fields;
+      edge_block_num++;
+    }
+  
+  
+  e=((edge_t*)(edges[in.block]->fields))+in.index;
+  if(e->from==INVALID)
+    {
+      if(e->previn) e->previn->nextin = e->nextin;
+               else freeedges = e->nextin;
+      if(e->nextin) e->nextin->previn = e->previn;
+
+      new (e->data) E;  //Explicit constructor call
+      
+      e->from=f; e->to=t;
+      e->previn=e->prevout=NULL;
+      e->nextin=nodes[t].firstin;
+      e->nextout=nodes[f].firstout;
+      if(nodes[t].firstin) nodes[t].firstin->previn=e;
+      if(nodes[f].firstout) nodes[f].firstout->prevout=e;
+      nodes[t].firstin=nodes[f].firstout=e;
+      nodes[t].indeg++; nodes[f].outdeg++;
+    }
+  return (EdgePoint)e;
+}
+
+template<class N, class E> void OldGraph<N,E>::Delete(EdgePoint e)
+{
+  if(!e||e->from==INVALID) return;
+  
+  ((E*)(((edge_t*)e)->data))->~E();  //Explicit destructor call
+  
+  nodes[e->from].outdeg--; nodes[e->to].indeg--;
+
+  
+  if(e->previn)
+    e->previn->nextin=e->nextin;
+  else nodes[e->to].firstin=e->nextin;
+  if(e->prevout)
+    e->prevout->nextout=e->nextout;
+  else nodes[e->from].firstout=e->nextout;
+  if(e->nextin)
+    e->nextin->previn=e->previn;
+  if(e->nextout)
+    e->nextout->prevout=e->prevout;
+  
+  if(freeedges) freeedges->previn=e;
+  e->previn=NULL; e->nextin=freeedges;
+
+  e->from = INVALID;
+  freeedges=e;
+}
+
+template<class N, class E> EdgePoint OldGraph<N,E>::Edge(int f, int t)
+{
+  EdgePoint e;
+  
+  for(e=nodes[f].firstout;e&&e->to!=t;e=e->nextout) ;
+  
+  return (EdgePoint) e;
+}
+
+template<class N, class E> void OldGraph<N,E>::Reverse(EdgePoint e)
+{
+  if(!e) return;
+
+  nodes[e->from].outdeg--; nodes[e->to].indeg--;
+  
+  if(e->previn)
+    e->previn->nextin=e->nextin;
+  else nodes[e->to].firstin=e->nextin;
+  if(e->prevout)
+    e->prevout->nextout=e->nextout;
+  else nodes[e->from].firstout=e->nextout;
+  if(e->nextin)
+    e->nextin->previn=e->previn;
+  if(e->nextout)
+    e->nextout->prevout=e->prevout;
+  
+  int t,f;
+  f=e->to;e->to=t=e->from;
+  e->from=f;
+
+  e->previn=e->prevout=NULL;
+  e->nextin=nodes[t].firstin;
+  e->nextout=nodes[f].firstout;
+  if(nodes[t].firstin) nodes[t].firstin->previn=e;
+  if(nodes[f].firstout) nodes[f].firstout->prevout=e;
+  nodes[t].firstin=nodes[f].firstout=e;
+  nodes[t].indeg++; nodes[f].outdeg++;
+
+}
+
+template<class N, class E> void OldGraph<N,E>::DeleteEdges()
+{
+  int n;
+  for(n=FirstNode();n!=INVALID;n=NextNode(n))
+    while(FirstOut(n)) Delete(FirstOut(n));
+}
+
+#endif

Added: hugo/trunk/src/work/graphdemo.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/graphdemo.cc	Sat Dec  6 20:32:27 2003
@@ -0,0 +1,98 @@
+#include <iostream>
+#include <graph.h>
+
+using namespace NEGRO;
+using namespace std;
+
+class NodeData;
+class EdgeData;
+
+typedef Graph<NodeData,EdgeData> TestGraph;
+
+class NodeData
+{
+public:
+  int id;
+  bool isVis;
+};
+
+class EdgeData
+{
+public:
+  int id;
+};
+
+
+typedef Graph<NodeData,EdgeData> TestGraph;
+
+void main()
+{
+  TestGraph G;
+  TestGraph::NodeIterator n,m,o,p,q;
+  TestGraph::OutEdgeIterator e,f,g,h;
+  int i,j,k;
+
+  
+  //for(i=1;i<=10;i++) G.AddNode().n=i; //Ez nagyon rossz!!!!!!!!
+  for(i=1;i<=10;i++) G.AddNode()->id=i; //Ez a jo!!!!!!!!
+
+  //n=G.AddNode();
+  
+   //for(i=1;i<=10;i++) cout << (G.AddNode()->n=i) << ' ';
+   //cout << '\n';
+ 
+  i=0;
+  for(G.GetFirst(n);n.isValid();n++)
+    for(G.GetFirst(m);m.isValid();++m)
+      if(n!=m) G.AddEdge(n,m)->id=++i;
+   
+  cout << "Number of edges: " << i << "\n\n";
+
+  TestGraph::AllEdgeIterator a;
+  for(G.GetFirst(a);a.isValid();++a)
+    cout << a->id << ":" << a.From()->id << "->" << a.To()->id << "   ";
+
+  cout << "\n\n\n";
+  
+  for(G.GetFirst(n);n.isValid();++n)
+    {
+      cout << n->id << "->";
+      for(G.GetFirst(e,n);e.isValid();++e)
+	cout << e->id << ":" << e.To()->id << ' ';
+      cout << '\n';
+    }
+  
+  cout << "\n\n\n\nB-verzio:\n\n\n";
+  
+  G.Clean();
+
+  for(i=1;i<=10;i++) G.AddNode()->id=i;
+  
+  i=0;
+  for(n=G.First();n.isValid();n++)
+    for(m=G.First();m.isValid();++m)
+      if(n!=m) G.AddEdge(n,m)->id=++i;
+   
+  ;
+  for(n=G.First();n.isValid();++n)
+    {
+      e=G.First(n);
+      while(e.isValid())
+	if((e->id)%2) G.Delete(e++);
+	else ++e;
+    }
+  
+  for(a=G.First();a.isValid();++a)
+    cout << a->id << ": " << a.From()->id << "->" << a.To()->id << "   ";
+  
+  cout << "\n\n\n";
+  
+  for(n=G.First();n.isValid();++n)
+    {
+      cout << n->id << "->";
+      for(e=G.First(n);e.isValid();++e)
+	cout << e->id << ":" << e.To()->id << ' ';
+      cout << '\n';
+    }
+  
+}

Added: hugo/trunk/src/work/makefile
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/makefile	Sat Dec  6 20:32:27 2003
@@ -0,0 +1,3 @@
+graphdemo: graphdemo.cc ../include/graph.h \
+	../include/oldgraph.h makefile
+	g++ -g -I../include -o graphdemo graphdemo.cc



More information about the Lemon-commits mailing list