Open
Graph Drawing
Framework

 v.2012.07
 

HyperGraph.h
Go to the documentation of this file.
1 /*
2  * $Revision: 2615 $
3  *
4  * last checkin:
5  * $Author: gutwenger $
6  * $Date: 2012-07-16 14:23:36 +0200 (Mo, 16. Jul 2012) $
7  ***************************************************************/
8 
44 #ifdef _MSC_VER
45 #pragma once
46 #endif
47 
48 #ifndef OGDF_HYPER_GRAPH_H
49 #define OGDF_HYPER_GRAPH_H
50 
52 #include <ogdf/basic/EList.h>
53 #include <ogdf/basic/EFreeList.h>
54 
55 namespace ogdf {
56 
58 {
59  friend class HyperGraphTypes;
60 
61 public:
62  // forward declaration to make AdjElement pointers available
63  class AdjElement;
64 
67  {
68  friend class HyperGraph;
69  friend class HyperGraphTypes;
70  public:
72  int index() const { return m_index; }
73 
75  int degree() const { return m_numAdj; }
76 
77  private:
82  int m_numAdj;
83  int m_index;
84  }; // class NodeElement
85 
86 
89  {
90  friend class HyperGraph;
91  friend class HyperGraphTypes;
92  public:
94  int index() const { return m_index; }
95 
97  int cardinality() const { return m_numAdj; }
98 
99  private:
104  int m_numAdj;
105  int m_index;
106  }; // class EdgeElement
107 
108 
111  {
112  friend class HyperGraph;
113  friend class HyperGraphTypes;
114  public:
115  AdjElement() : m_pNode(0), m_pEdge(0) { }
116 
118  NodeElement* theNode() { return m_pNode; }
119 
121  EdgeElement* theEdge() { return m_pEdge; }
122 
124  int index() const { return m_index; }
125  private:
126 
128  m_pNode(pNode),
129  m_pEdge(pEdge),
130  m_pPrev_nodeAdj(0),
131  m_pNext_nodeAdj(0),
132  m_pPrev_edgeAdj(0),
133  m_pNext_edgeAdj(0)
134  { }
135 
138 
141 
144  int m_index;
145  };
146 
147  typedef NodeElement* node;
148  typedef EdgeElement* edge;
149 
150 protected:
154 
158 
159 protected:
161  NodeElement,
162  &NodeElement::m_pNext,
163  &NodeElement::m_index
165 
167  EdgeElement,
168  &EdgeElement::m_pNext,
169  &EdgeElement::m_index
171 
173  AdjElement,
174  &AdjElement::m_pNext_nodeAdj, // note: we just need one next pointer, nobody cares which one.
175  &AdjElement::m_index
177 
178 
179  template<typename E>
181  {
182  friend class HyperGraph;
183  public:
185  virtual void setSize(int numElements) = 0;
186 
189  };
190 
191 
192  template<typename T, typename E>
193  class GraphArray : protected Array<T>, GraphArrayBase<E>
194  {
195  friend class HyperGraph;
196  public:
197  // Creates an empty graph array not attached to a graph.
198  GraphArray() : m_pGraph(0), Array<T>() { }
199 
201  GraphArray(HyperGraph* pGraph) : m_pGraph(pGraph), m_initialValue(), Array<T>()
202  {
203  if (m_pGraph)
204  m_pGraph->registerArray(this);
205  }
206 
208  GraphArray(HyperGraph* pGraph, const T& initialValue) : m_pGraph(pGraph), m_initialValue(initialValue), Array<T>()
209  {
210  if (m_pGraph)
211  m_pGraph->registerArray(this);
212  }
213 
215 
218  virtual ~GraphArray()
219  {
220  if (m_pGraph)
221  m_pGraph->unregisterArray(this);
222  }
223 
225  const T& operator[](const E* e) const
226  {
227  return Array<T>::operator [](e->index());
228  }
229 
231  T& operator[](const E* e)
232  {
233  return Array<T>::operator [](e->index());
234  }
235 
237  HyperGraph* graph() const
238  {
239  return m_pGraph;
240  }
241 
242  protected:
243 
245  virtual void setSize(int numElements)
246  {
247  if (numElements > Array<T>::size())
248  Array<T>::grow(numElements-Array<T>::size(),m_initialValue);
249  }
250 
253 
256 
257  }; // end of class GraphArray
258 
259 
260  template<typename ElementType> class ArrayControllerTypes;
261 
263  template<typename ElementType>
265  {
266  friend class ArrayControllerTypes<ElementType>;
267  public:
269  ArrayController() : m_tableSize(0)
270  {
272  }
273 
275  ~ArrayController();
276 
278  void registerArray(GraphArrayBase<ElementType>* pArray);
279 
281  void unregisterArray(GraphArrayBase<ElementType>* pArray);
282 
284  int newTableSize(int minSize)
285  {
286  int res = 1;
287  while (res < minSize)
288  res = res << 1;
289  return res;
290  }
291 
293  void numUsedIndicesChanged(int numUsedIndices);
294 
295  protected:
298 
301 
304 
307  };
308 
309 
310  template<typename ElementType>
312  {
313  public:
321  };
322 
323 
327 
328  void registerArray(GraphArrayBase<NodeElement>* pArray) { m_nodeArrayController.registerArray(pArray); }
329  void registerArray(GraphArrayBase<EdgeElement>* pArray) { m_edgeArrayController.registerArray(pArray); }
330  void registerArray(GraphArrayBase<AdjElement>* pArray) { m_adjArrayController.registerArray(pArray); }
331 
332 
333  void unregisterArray(GraphArrayBase<NodeElement>* pArray) { m_nodeArrayController.unregisterArray(pArray); }
334  void unregisterArray(GraphArrayBase<EdgeElement>* pArray) { m_edgeArrayController.unregisterArray(pArray); }
335  void unregisterArray(GraphArrayBase<AdjElement>* pArray) { m_adjArrayController.unregisterArray(pArray); }
336 
338  NodeElement* allocateNodeElement()
339  {
340  NodeElement* pResult = m_nodeAllocator.alloc();
341  m_nodeArrayController.numUsedIndicesChanged(m_nodeAllocator.numUsedIndices());
342  return pResult;
343  }
344 
346  EdgeElement* allocateEdgeElement()
347  {
348  EdgeElement* pResult = m_edgeAllocator.alloc();
349  m_edgeArrayController.numUsedIndicesChanged(m_edgeAllocator.numUsedIndices());
350  return pResult;
351  }
352 
354  AdjElement* allocateAdjElement()
355  {
356  AdjElement* pResult = m_adjAllocator.alloc();
357  m_adjArrayController.numUsedIndicesChanged(m_adjAllocator.numUsedIndices());
358  return pResult;
359  }
360 
362  void freeNodeElement(NodeElement* pNode)
363  {
364  m_nodeAllocator.free(pNode);
365  }
366 
368  void freeEdgeElement(EdgeElement* pEdge)
369  {
370  m_edgeAllocator.free(pEdge);
371  }
372 
374  void freeAdjElement(AdjElement* pAdj)
375  {
376  m_adjAllocator.free(pAdj);
377  }
378 
379 public:
380 
382  template<typename T>
383  class NodeArray : public GraphArray<T, NodeElement>
384  {
385  public:
386  NodeArray(HyperGraph* pGraph) : GraphArray<T, NodeElement>(pGraph) {}
387  NodeArray(HyperGraph* pGraph, const T& initValue) : GraphArray<T, NodeElement>(pGraph, initValue) {}
388  };
389 
391  template<typename T>
392  class EdgeArray : public GraphArray<T, EdgeElement>
393  {
394  public:
395  EdgeArray(HyperGraph* pGraph) : GraphArray<T, EdgeElement>(pGraph) {}
396  EdgeArray(HyperGraph* pGraph, const T& initValue) : GraphArray<T, EdgeElement>(pGraph, initValue) {}
397  };
398 
400  template<typename T>
401  class AdjArray : public GraphArray<T, AdjElement>
402  {
403  public:
404  AdjArray(HyperGraph* pGraph) : GraphArray<T, AdjElement>(pGraph) {}
405  AdjArray(HyperGraph* pGraph, const T& initValue) : GraphArray<T, AdjElement>(pGraph, initValue) {}
406  };
407 
408 
410  HyperGraph();
411 
413  NodeElement* newNode();
414 
416  EdgeElement* newEdge();
417 
419  EdgeElement* newEdge(NodeElement* pNode1, NodeElement* pNode2)
420  {
421  EdgeElement* pEdge = newEdge();
422  newAdjElement( pNode1, pEdge );
423  newAdjElement( pNode2, pEdge );
424  return pEdge;
425  }
426 
428 
435  AdjElement* newAdjElement(NodeElement* pNode, EdgeElement* pEdge);
436 
438  void delAdjElement(AdjElement* pAdj);
439 
441  void delAdjElement(NodeElement* pNode, EdgeElement* pEdge)
442  {
443  AdjElement* pAdj = findAdjElement(pNode, pEdge);
444  if (pAdj) delAdjElement(pAdj);
445  }
446 
448  AdjElement* addNode(NodeElement* pNode, EdgeElement* pEdge, bool checkIfAlreadyExists = false)
449  {
450  if (!checkIfAlreadyExists)
451  return newAdjElement( pNode, pEdge );
452 
453  AdjElement* pAdj = findAdjElement(pNode, pEdge);
454  if (!pAdj)
455  pAdj = newAdjElement( pNode, pEdge );
456  return pAdj;
457  }
458 
460 
466  void removeNode(NodeElement* pNode, EdgeElement* pEdge, bool removeDuplicates = false)
467  {
468  AdjElement* pAdj = findAdjElement(pNode, pEdge);
469  if (!removeDuplicates && pAdj)
470  {
471  delAdjElement(pAdj);
472  } else
473  {
474  while (pAdj)
475  {
476  delAdjElement(pAdj);
477  pAdj = findAdjElement(pNode, pEdge);
478  }
479  }
480  }
481 
483 
489  AdjElement* findAdjElement(NodeElement* pNode, EdgeElement* pEdge) const;
490 
492  void delEdge(EdgeElement* pEdge);
493 
495  void delNode(NodeElement* pNode);
496 
497  int numberOfNodes() const;
498  int numberOfEdges() const;
499 
501  void clear();
502 
503  /* void toCliqueGraph(
504  Graph* pG,
505  NodeArray<HyperGraph::NodeElement*>* pNodeMap = 0,
506  EdgeArray<HyperGraph::EdgeElement*>* pEdgeMap = 0)
507  {
508  HyperGraph::NodeArray<ogdf::node> hgNode_to_gNode(this);
509  for (NodeList::iterator it = HyperGraph::NodeList::begin(this); it.valid(); it++)
510  {
511  HyperGraph::NodeElement* hgNode = *it;
512  ogdf::node gNode = pG->newNode();
513  hgNode_to_gNode[ hgNode ] = gNode;
514  if (pNodeMap)
515  (*pNodeMap)[gNode] = hgNode;
516  }
517 
518  for (HyperGraph::EdgeList::iterator it = HyperGraph::EdgeList::begin(this); it.valid(); it++)
519  {
520  EdgeElement* hgEdge = *it;
521  for (HyperGraph::EdgeAdjList::iterator adj_it = HyperGraph::EdgeAdjList::begin(hgEdge); adj_it.valid(); adj_it++)
522  {
523  for (HyperGraph::EdgeAdjList::iterator adj_it2 = adj_it.succ(); adj_it2.valid(); adj_it2++)
524  {
525  NodeElement* hgNode = (*adj_it)->theNode();
526  NodeElement* hgNode2 = (*adj_it2)->theNode();
527  node gNode = hgNode_to_gNode[ hgNode ];
528  node gNode2 = hgNode_to_gNode[ hgNode2 ];
529 
530  edge gEdge = pG->newEdge(gNode, gNode2);
531  if (pEdgeMap)
532  (*pEdgeMap)[gEdge] = hgEdge;
533  }
534  }
535  }
536  }
537 
538  void toStarGraph(
539  Graph* pG,
540  NodeArray<NodeElement*>* pNodeMap = 0,
541  EdgeArray<EdgeElement*>* pEdgeMap = 0)
542  {
543  HyperGraph::NodeArray<ogdf::node> hgNode_to_gNode(this);
544  for (NodeList::iterator it = HyperGraph::NodeList::begin(this); it.valid(); it++)
545  {
546  NodeElement* hgNode = *it;
547  node gNode = pG->newNode();
548  hgNode_to_gNode[ hgNode ] = gNode;
549  if (pNodeMap)
550  (*pNodeMap)[gNode] = hgNode;
551  }
552 
553  for (HyperGraph::EdgeList::iterator it = HyperGraph::EdgeList::begin(this); it.valid(); it++)
554  {
555  EdgeElement* hgEdge = *it;
556  node gNodeDummy = pG->newNode();
557  if (pNodeMap)
558  (*pNodeMap)[gNodeDummy] = 0;
559 
560  for (HyperGraph::EdgeAdjList::iterator adj_it = HyperGraph::EdgeAdjList::begin(hgEdge); adj_it.valid(); adj_it++)
561  {
562  NodeElement* hgNode = (*adj_it)->theNode();
563  node gNode = hgNode_to_gNode[ hgNode ];
564  edge gEdge = pG->newEdge(gNodeDummy, gNode);
565  if (pEdgeMap)
566  (*pEdgeMap)[gEdge] = hgEdge;
567  }
568  }
569  } */
570 }; // end of class HyperGraph
571 
572 
575 {
576 public:
578  typedef EList<
586 
588  typedef EList<
596 
598  typedef EList<
606 
608  typedef EList<
616 };
617 
618 
619 template<typename ElementType>
621 {
622  // Unregisters all arrays, but does not delete them.
625 }
626 
627 
628 // Registers a new graph array and sets the size to \a m_tableSize.
629 template<typename ElementType>
631 {
633  pArray->setSize(m_tableSize);
634 }
635 
636 
637 // Unregisters an array by removing it from the list.
638 template<typename ElementType>
640 {
642  pArray->setSize(0);
643 }
644 
645 
646 template<typename ElementType>
648 {
649  // check if we have to grow
650  if (numUsedIndices > m_tableSize)
651  {
652  // we have to resize
653  // calculate new table size
654  m_tableSize = newTableSize(numUsedIndices);
655  // iterate over all arrays
657  it.valid(); it++)
658  {
659  // and resize them
660  (*it)->setSize(m_tableSize);
661  }
662  }
663 }
664 
665 
667 {
670 }
671 
672 
674 {
675  NodeElement* pNode = allocateNodeElement();
678  return pNode;
679 }
680 
681 
683 {
684  EdgeElement* pEdge = allocateEdgeElement();
687  return pEdge;
688 }
689 
690 
692 {
693  AdjElement* pAdj = allocateAdjElement();
694  pAdj->m_pNode = pNode;
695  pAdj->m_pEdge = pEdge;
696 
699  return pAdj;
700 }
701 
702 
704 {
707  freeAdjElement( pAdj );
708 }
709 
710 
712 {
714  {
716  it.valid(); it++)
717  {
718  if ((*it)->theNode() == pNode) return (*it);
719  }
720  } else
721  {
723  it.valid(); it++)
724  {
725  if ((*it)->theEdge() == pEdge) return (*it);
726  }
727  }
728  return 0;
729 }
730 
731 
733 {
735  {
736  AdjElement* pAdj = *it;
738  it = HyperGraphTypes::EdgeAdjList::remove( pEdge, it );
739  freeAdjElement( pAdj );
740  }
741  HyperGraphTypes::EdgeList::remove( this, pEdge );
742  freeEdgeElement( pEdge );
743 }
744 
745 
747 {
749  {
750  AdjElement* pAdj = *it;
752  it = HyperGraphTypes::NodeAdjList::remove( pNode, it );
753  freeAdjElement( pAdj );
754  }
755  HyperGraphTypes::NodeList::remove( this, pNode );
756  freeNodeElement( pNode );
757 }
758 
759 
760 inline int HyperGraph::numberOfNodes() const { return HyperGraphTypes::NodeList::size(this); }
761 
762 inline int HyperGraph::numberOfEdges() const { return HyperGraphTypes::EdgeList::size(this); }
763 
764 
765 inline void HyperGraph::clear()
766 {
767  while (numberOfNodes())
768  {
770  }
771 
772  while (numberOfEdges())
773  {
775  }
776 }
777 
778 
779 
780 template<typename ListType, typename ArrayType>
781 static void writeToStream(std::ostream& outStream, ArrayType& array)
782 {
783  for (typename ListType::iterator it = ListType::begin(array.graph()); it.valid(); it++)
784  {
785  outStream << array[*it] << std::endl;
786  }
787 }
788 
789 
790 template<typename ListType, typename ArrayType>
791 static void readFromStream(std::istream& inStream, ArrayType& array)
792 {
793  for (typename ListType::iterator it = ListType::begin(array.graph());it.valid(); it++)
794  {
795  inStream >> array[(*it)];
796  }
797 }
798 
799 template<typename T>
800 static std::ostream& operator<<(std::ostream& outStream, HyperGraph::NodeArray<T>& array)
801 {
802  writeToStream<HyperGraphTypes::NodeList, HyperGraph::NodeArray<T> >(outStream, array);
803  return outStream;
804 }
805 
806 template<typename T>
807 static std::ostream& operator<<(std::ostream& outStream, HyperGraph::EdgeArray<T>& array)
808 {
809  writeToStream<HyperGraphTypes::EdgeList, HyperGraph::EdgeArray<T> >(outStream, array);
810  return outStream;
811 }
812 
813 template<typename T>
814 static std::ostream& operator<<(std::ostream& outStream, HyperGraph::AdjArray<T>& array)
815 {
817  {
818  HyperGraph::edge e = *it;
820  {
821  outStream << array[(*adj_it)] << std::endl;
822  }
823  }
824  return outStream;
825 }
826 
827 
828 template<typename T>
829 static std::istream& operator>>(std::istream& inStream, HyperGraph::NodeArray<T>& array)
830 {
831  readFromStream<HyperGraphTypes::NodeList, HyperGraph::NodeArray<T> >(inStream, array);
832  return inStream;
833 }
834 
835 
836 template<typename T>
837 static std::istream& operator>>(std::istream& inStream, HyperGraph::EdgeArray<T>& array)
838 {
839  readFromStream<HyperGraphTypes::EdgeList, HyperGraph::EdgeArray<T> >(inStream, array);
840  return inStream;
841 }
842 
843 
844 template<typename T>
845 static std::istream& operator>>(std::istream& inStream, HyperGraph::AdjArray<T>& array)
846 {
848  {
849  HyperGraph::edge e = *it;
851  {
852  inStream >> array[(*adj_it)];
853  }
854  }
855  return inStream;
856 }
857 
858 
859 static std::ostream& operator<<(std::ostream& outStream, HyperGraph& graph)
860 {
861  outStream << graph.numberOfNodes() << std::endl;
862  outStream << graph.numberOfEdges() << std::endl;
863 
864  HyperGraph::NodeArray<int> packed_index(&graph);
865 
866  int i=0;
868  {
869  packed_index[*it] = i++;
870  }
871 
873  {
874  HyperGraph::edge e = *it;
875  outStream << e->cardinality() << std::endl;
877  {
878  outStream << packed_index[(*adj_it)->theNode()] << std::endl;
879  }
880  }
881  return outStream;
882 }
883 
884 
885 static std::istream& operator>>(std::istream& inStream, HyperGraph& graph)
886 {
887  int numNodes;
888  int numEdges;
889  inStream >> numNodes;
890  inStream >> numEdges;
891 
892  HyperGraph::node* pNodes = new HyperGraph::node[numNodes];
893  for (int i=0; i<numNodes;i++)
894  pNodes[i] = graph.newNode();
895 
896  for (int i=0; i<numEdges;i++)
897  {
898  HyperGraph::edge e = graph.newEdge();
899  int numAdj;
900  inStream >> numAdj;
901  for (int j=0; j<numAdj; j++)
902  {
903  int packedNodeIndex;
904  inStream >> packedNodeIndex;
905  graph.addNode(pNodes[packedNodeIndex], e);
906  }
907  }
908  return inStream;
909 }
910 
911 } // end of namespace ogdf
912 
913 #endif /* HYPERGRAPH_H_ */