SNAP Library, Developer Reference  2012-10-02 12:56:23
SNAP, a general purpose network analysis and graph mining library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
graph.h
Go to the documentation of this file.
00001 
00002 // Undirected graphs
00003 class TUNGraph;
00004 class TBPGraph;
00005 //TODO:class TUNEGraph; -- undirected multigraph
00006 
00008 typedef TPt<TUNGraph> PUNGraph;
00010 typedef TPt<TBPGraph> PBPGraph;
00011 
00013 // Directed graphs
00014 class TNGraph;
00015 class TNEGraph;
00016 
00018 typedef TPt<TNGraph> PNGraph;
00020 typedef TPt<TNEGraph> PNEGraph;
00021 
00024 
00031 class TUNGraph {
00032 public:
00033   typedef TUNGraph TNet;
00034   typedef TPt<TUNGraph> PNet;
00035 public:
00036   class TNode {
00037   private:
00038     TInt Id;
00039     TIntV NIdV;
00040   public:
00041     TNode() : Id(-1), NIdV() { }
00042     TNode(const int& NId) : Id(NId), NIdV() { }
00043     TNode(const TNode& Node) : Id(Node.Id), NIdV(Node.NIdV) { }
00044     TNode(TSIn& SIn) : Id(SIn), NIdV(SIn) { }
00045     void Save(TSOut& SOut) const { Id.Save(SOut);  NIdV.Save(SOut); }
00046     int GetId() const { return Id; }
00047     int GetDeg() const { return NIdV.Len(); }
00048     int GetInDeg() const { return GetDeg(); }
00049     int GetOutDeg() const { return GetDeg(); }
00050     int GetInNId(const int& NodeN) const { return GetNbrNId(NodeN); }
00051     int GetOutNId(const int& NodeN) const { return GetNbrNId(NodeN); }
00052     int GetNbrNId(const int& NodeN) const { return NIdV[NodeN]; }
00053     bool IsNbrNId(const int& NId) const { return NIdV.SearchBin(NId)!=-1; }
00054     bool IsInNId(const int& NId) const { return IsNbrNId(NId); }
00055     bool IsOutNId(const int& NId) const { return IsNbrNId(NId); }
00056     void PackOutNIdV() { NIdV.Pack(); }
00057     void PackNIdV() { NIdV.Pack(); }
00058     friend class TUNGraph;
00059     friend class TUNGraphMtx;
00060   };
00062   class TNodeI {
00063   private:
00064     typedef THash<TInt, TNode>::TIter THashIter;
00065     THashIter NodeHI;
00066   public:
00067     TNodeI() : NodeHI() { }
00068     TNodeI(const THashIter& NodeHIter) : NodeHI(NodeHIter) { }
00069     TNodeI(const TNodeI& NodeI) : NodeHI(NodeI.NodeHI) { }
00070     TNodeI& operator = (const TNodeI& NodeI) { NodeHI = NodeI.NodeHI;  return *this; }
00071 
00073     TNodeI& operator++ (int) { NodeHI++;  return *this; }
00074 
00075     bool operator < (const TNodeI& NodeI) const { return NodeHI < NodeI.NodeHI; }
00076     bool operator == (const TNodeI& NodeI) const { return NodeHI == NodeI.NodeHI; }
00077 
00079     int GetId() const { return NodeHI.GetDat().GetId(); }
00081     int GetDeg() const { return NodeHI.GetDat().GetDeg(); }
00083     int GetInDeg() const { return NodeHI.GetDat().GetInDeg(); }
00085     int GetOutDeg() const { return NodeHI.GetDat().GetOutDeg(); }
00087 
00090     int GetInNId(const int& NodeN) const { return NodeHI.GetDat().GetInNId(NodeN); }
00092 
00095     int GetOutNId(const int& NodeN) const { return NodeHI.GetDat().GetOutNId(NodeN); }
00097 
00100     int GetNbrNId(const int& NodeN) const { return NodeHI.GetDat().GetNbrNId(NodeN); }
00102     bool IsInNId(const int& NId) const { return NodeHI.GetDat().IsInNId(NId); }
00104     bool IsOutNId(const int& NId) const { return NodeHI.GetDat().IsOutNId(NId); }
00106     bool IsNbrNId(const int& NId) const { return NodeHI.GetDat().IsNbrNId(NId); }
00107     friend class TUNGraph;
00108   };
00110   class TEdgeI {
00111   private:
00112     TNodeI CurNode, EndNode;
00113     int CurEdge;
00114   public:
00115     TEdgeI() : CurNode(), EndNode(), CurEdge(0) { }
00116     TEdgeI(const TNodeI& NodeI, const TNodeI& EndNodeI, const int& EdgeN=0) : CurNode(NodeI), EndNode(EndNodeI), CurEdge(EdgeN) { }
00117     TEdgeI(const TEdgeI& EdgeI) : CurNode(EdgeI.CurNode), EndNode(EdgeI.EndNode), CurEdge(EdgeI.CurEdge) { }
00118     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { CurNode=EdgeI.CurNode;  EndNode=EdgeI.EndNode;  CurEdge=EdgeI.CurEdge; }  return *this; }
00120     TEdgeI& operator++ (int) { do { CurEdge++; if (CurEdge >= CurNode.GetOutDeg()) { CurEdge=0;  CurNode++; while (CurNode < EndNode && CurNode.GetOutDeg()==0) { CurNode++; } } } while (CurNode < EndNode && GetSrcNId()>GetDstNId()); return *this; }
00121     bool operator < (const TEdgeI& EdgeI) const { return CurNode<EdgeI.CurNode || (CurNode==EdgeI.CurNode && CurEdge<EdgeI.CurEdge); }
00122     bool operator == (const TEdgeI& EdgeI) const { return CurNode == EdgeI.CurNode && CurEdge == EdgeI.CurEdge; }
00124     int GetId() const { return -1; }
00126     int GetSrcNId() const { return CurNode.GetId(); }
00128     int GetDstNId() const { return CurNode.GetOutNId(CurEdge); }
00129     friend class TUNGraph;
00130   };
00131 private:
00132   TCRef CRef;
00133   TInt MxNId;
00134   THash<TInt, TNode> NodeH;
00135 private:
00136   TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
00137   const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
00138 public:
00139   TUNGraph() : CRef(), MxNId(0), NodeH() { }
00141   explicit TUNGraph(const int& Nodes, const int& Edges) : MxNId(0) { Reserve(Nodes, Edges); }
00142   TUNGraph(const TUNGraph& Graph) : MxNId(Graph.MxNId), NodeH(Graph.NodeH) { }
00144   TUNGraph(TSIn& SIn) : MxNId(SIn), NodeH(SIn) { }
00146   void Save(TSOut& SOut) const { MxNId.Save(SOut);  NodeH.Save(SOut); }
00148   static PUNGraph New() { return new TUNGraph(); }
00150 
00152   static PUNGraph New(const int& Nodes, const int& Edges) { return new TUNGraph(Nodes, Edges); }
00154   static PUNGraph Load(TSIn& SIn) { return PUNGraph(new TUNGraph(SIn)); }
00156   bool HasFlag(const TGraphFlag& Flag) const;
00157   TUNGraph& operator = (const TUNGraph& Graph) {
00158     if (this!=&Graph) { MxNId=Graph.MxNId;  NodeH=Graph.NodeH; }  return *this; }
00159   
00161   int GetNodes() const { return NodeH.Len(); }
00163 
00167   int AddNode(int NId = -1);
00169   int AddNode(const TNodeI& NodeI) { return AddNode(NodeI.GetId()); }
00171 
00180   int AddNode(const int& NId, const TIntV& NbrNIdV);
00182 
00190   int AddNode(const int& NId, const TVecPool<TInt>& Pool, const int& NIdVId);
00192 
00194   void DelNode(const int& NId);
00196   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
00198   bool IsNode(const int& NId) const { return NodeH.IsKey(NId); }
00200   TNodeI BegNI() const { return TNodeI(NodeH.BegI()); }
00202   TNodeI EndNI() const { return TNodeI(NodeH.EndI()); }
00204   TNodeI GetNI(const int& NId) const { return TNodeI(NodeH.GetI(NId)); }
00206   int GetMxNId() const { return MxNId; }
00207 
00209   int GetEdges() const;
00211 
00215   int AddEdge(const int& SrcNId, const int& DstNId);
00217   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId()); }
00219 
00222   void DelEdge(const int& SrcNId, const int& DstNId);
00224   bool IsEdge(const int& SrcNId, const int& DstNId) const;
00226   TEdgeI BegEI() const { TNodeI NI=BegNI(); while (NI<EndNI() && (NI.GetOutDeg()==0 || NI.GetId()>NI.GetOutNId(0))) { NI++; } return TEdgeI(NI, EndNI()); }
00228   TEdgeI EndEI() const { return TEdgeI(EndNI(), EndNI()); }
00230   TEdgeI GetEI(const int& EId) const;
00232 
00234   TEdgeI GetEI(const int& SrcNId, const int& DstNId) const;
00235 
00237   int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); }
00239   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
00241   void GetNIdV(TIntV& NIdV) const;
00242 
00244   bool Empty() const { return GetNodes()==0; }
00246   void Clr() { MxNId=0;  NodeH.Clr(); }
00248   void Reserve(const int& Nodes, const int& Edges) { if (Nodes>0) NodeH.Gen(Nodes/2); }
00250   void ReserveNIdDeg(const int& NId, const int& Deg) { GetNode(NId).NIdV.Reserve(Deg); }
00252 
00256   void Defrag(const bool& OnlyNodeLinks=false);
00258 
00260   bool IsOk(const bool& ThrowExcept=true) const;
00262   void Dump(FILE *OutF=stdout) const;
00264 
00270   static PUNGraph GetSmallGraph();
00271 
00272   friend class TUNGraphMtx;
00273   friend class TPt<TUNGraph>;
00274 };
00275 
00277 // Directed Node Graph
00278 
00280 
00294 class TNGraph {
00295 public:
00296   typedef TNGraph TNet;
00297   typedef TPt<TNGraph> PNet;
00298 public:
00299   class TNode {
00300   private:
00301     TInt Id;
00302     TIntV InNIdV, OutNIdV;
00303   public:
00304     TNode() : Id(-1), InNIdV(), OutNIdV() { }
00305     TNode(const int& NId) : Id(NId), InNIdV(), OutNIdV() { }
00306     TNode(const TNode& Node) : Id(Node.Id), InNIdV(Node.InNIdV), OutNIdV(Node.OutNIdV) { }
00307     TNode(TSIn& SIn) : Id(SIn), InNIdV(SIn), OutNIdV(SIn) { }
00308     void Save(TSOut& SOut) const { Id.Save(SOut);  InNIdV.Save(SOut);  OutNIdV.Save(SOut);  }
00309     int GetId() const { return Id; }
00310     int GetDeg() const { return GetInDeg() + GetOutDeg(); }
00311     int GetInDeg() const { return InNIdV.Len(); }
00312     int GetOutDeg() const { return OutNIdV.Len(); }
00313     int GetInNId(const int& NodeN) const { return InNIdV[NodeN]; }
00314     int GetOutNId(const int& NodeN) const { return OutNIdV[NodeN]; }
00315     int GetNbrNId(const int& NodeN) const { return NodeN<GetOutDeg()?GetOutNId(NodeN):GetInNId(NodeN-GetOutDeg()); }
00316     bool IsInNId(const int& NId) const { return InNIdV.SearchBin(NId) != -1; }
00317     bool IsOutNId(const int& NId) const { return OutNIdV.SearchBin(NId) != -1; }
00318     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
00319     void PackOutNIdV() { OutNIdV.Pack(); }
00320     void PackNIdV() { InNIdV.Pack(); }
00321     friend class TNGraph;
00322     friend class TNGraphMtx;
00323   };
00325   class TNodeI {
00326   private:
00327     typedef THash<TInt, TNode>::TIter THashIter;
00328     THashIter NodeHI;
00329   public:
00330     TNodeI() : NodeHI() { }
00331     TNodeI(const THashIter& NodeHIter) : NodeHI(NodeHIter) { }
00332     TNodeI(const TNodeI& NodeI) : NodeHI(NodeI.NodeHI) { }
00333     TNodeI& operator = (const TNodeI& NodeI) { NodeHI = NodeI.NodeHI;  return *this; }
00335     TNodeI& operator++ (int) { NodeHI++;  return *this; }
00336     bool operator < (const TNodeI& NodeI) const { return NodeHI < NodeI.NodeHI; }
00337     bool operator == (const TNodeI& NodeI) const { return NodeHI == NodeI.NodeHI; }
00339     int GetId() const { return NodeHI.GetDat().GetId(); }
00341     int GetDeg() const { return NodeHI.GetDat().GetDeg(); }
00343     int GetInDeg() const { return NodeHI.GetDat().GetInDeg(); }
00345     int GetOutDeg() const { return NodeHI.GetDat().GetOutDeg(); }
00347 
00349     int GetInNId(const int& NodeN) const { return NodeHI.GetDat().GetInNId(NodeN); }
00351 
00353     int GetOutNId(const int& NodeN) const { return NodeHI.GetDat().GetOutNId(NodeN); }
00355 
00357     int GetNbrNId(const int& NodeN) const { return NodeHI.GetDat().GetNbrNId(NodeN); }
00359     bool IsInNId(const int& NId) const { return NodeHI.GetDat().IsInNId(NId); }
00361     bool IsOutNId(const int& NId) const { return NodeHI.GetDat().IsOutNId(NId); }
00363     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
00364     friend class TNGraph;
00365   };
00367   class TEdgeI {
00368   private:
00369     TNodeI CurNode, EndNode;
00370     int CurEdge;
00371   public:
00372     TEdgeI() : CurNode(), EndNode(), CurEdge(0) { }
00373     TEdgeI(const TNodeI& NodeI, const TNodeI& EndNodeI, const int& EdgeN=0) : CurNode(NodeI), EndNode(EndNodeI), CurEdge(EdgeN) { }
00374     TEdgeI(const TEdgeI& EdgeI) : CurNode(EdgeI.CurNode), EndNode(EdgeI.EndNode), CurEdge(EdgeI.CurEdge) { }
00375     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { CurNode=EdgeI.CurNode;  EndNode=EdgeI.EndNode;  CurEdge=EdgeI.CurEdge; }  return *this; }
00377     TEdgeI& operator++ (int) { CurEdge++; if (CurEdge >= CurNode.GetOutDeg()) { CurEdge=0;  CurNode++;
00378       while (CurNode < EndNode && CurNode.GetOutDeg()==0) { CurNode++; } }  return *this; }
00379     bool operator < (const TEdgeI& EdgeI) const { return CurNode<EdgeI.CurNode || (CurNode==EdgeI.CurNode && CurEdge<EdgeI.CurEdge); }
00380     bool operator == (const TEdgeI& EdgeI) const { return CurNode == EdgeI.CurNode && CurEdge == EdgeI.CurEdge; }
00382     int GetId() const { return -1; }
00384     int GetSrcNId() const { return CurNode.GetId(); }
00386     int GetDstNId() const { return CurNode.GetOutNId(CurEdge); }
00387     friend class TNGraph;
00388   };
00389 private:
00390   TCRef CRef;
00391   TInt MxNId;
00392   THash<TInt, TNode> NodeH;
00393 private:
00394   TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
00395   const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
00396 public:
00397   TNGraph() : CRef(), MxNId(0), NodeH() { }
00399   explicit TNGraph(const int& Nodes, const int& Edges) : MxNId(0) { Reserve(Nodes, Edges); }
00400   TNGraph(const TNGraph& Graph) : MxNId(Graph.MxNId), NodeH(Graph.NodeH) { }
00402   TNGraph(TSIn& SIn) : MxNId(SIn), NodeH(SIn) { }
00404   void Save(TSOut& SOut) const { MxNId.Save(SOut);  NodeH.Save(SOut); }
00406   static PNGraph New() { return new TNGraph(); }
00408 
00410   static PNGraph New(const int& Nodes, const int& Edges) { return new TNGraph(Nodes, Edges); }
00412   static PNGraph Load(TSIn& SIn) { return PNGraph(new TNGraph(SIn)); }
00414   bool HasFlag(const TGraphFlag& Flag) const;
00415   TNGraph& operator = (const TNGraph& Graph) {
00416     if (this!=&Graph) { MxNId=Graph.MxNId;  NodeH=Graph.NodeH; }  return *this; }
00417   
00419   int GetNodes() const { return NodeH.Len(); }
00421 
00425   int AddNode(int NId = -1);
00427   int AddNode(const TNodeI& NodeId) { return AddNode(NodeId.GetId()); }
00429 
00438   int AddNode(const int& NId, const TIntV& InNIdV, const TIntV& OutNIdV);
00440 
00448   int AddNode(const int& NId, const TVecPool<TInt>& Pool, const int& SrcVId, const int& DstVId);
00450 
00452   void DelNode(const int& NId);
00454   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
00456   bool IsNode(const int& NId) const { return NodeH.IsKey(NId); }
00458   TNodeI BegNI() const { return TNodeI(NodeH.BegI()); }
00460   TNodeI EndNI() const { return TNodeI(NodeH.EndI()); }
00462   TNodeI GetNI(const int& NId) const { return TNodeI(NodeH.GetI(NId)); }
00463   // GetNodeC() has been commented out. It was a quick shortcut, do not use.
00464   //const TNode& GetNodeC(const int& NId) const { return NodeH.GetDat(NId); }
00466   int GetMxNId() const { return MxNId; }
00467 
00469   int GetEdges() const;
00471 
00477   int AddEdge(const int& SrcNId, const int& DstNId);
00479   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId()); }
00481 
00485   void DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true);
00487   bool IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true) const;
00489   TEdgeI BegEI() const { TNodeI NI=BegNI();  while(NI<EndNI() && NI.GetOutDeg()==0) NI++;  return TEdgeI(NI, EndNI()); }
00491   TEdgeI EndEI() const { return TEdgeI(EndNI(), EndNI()); }
00493   TEdgeI GetEI(const int& EId) const; // not supported
00495   TEdgeI GetEI(const int& SrcNId, const int& DstNId) const;
00496 
00498   int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); }
00500   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
00502   void GetNIdV(TIntV& NIdV) const;
00503 
00505   bool Empty() const { return GetNodes()==0; }
00507   void Clr() { MxNId=0;  NodeH.Clr(); }
00509   void Reserve(const int& Nodes, const int& Edges) { if (Nodes>0) { NodeH.Gen(Nodes/2); } }
00511   void ReserveNIdInDeg(const int& NId, const int& InDeg) { GetNode(NId).InNIdV.Reserve(InDeg); }
00513   void ReserveNIdOutDeg(const int& NId, const int& OutDeg) { GetNode(NId).OutNIdV.Reserve(OutDeg); }
00515 
00520   void Defrag(const bool& OnlyNodeLinks=false);
00522 
00525   bool IsOk(const bool& ThrowExcept=true) const;
00527   void Dump(FILE *OutF=stdout) const;
00529 
00533   static PNGraph GetSmallGraph();
00534   friend class TPt<TNGraph>;
00535   friend class TNGraphMtx;
00536 };
00537 
00538 // set flags
00539 namespace TSnap {
00540 template <> struct IsDirected<TNGraph> { enum { Val = 1 }; };
00541 }
00542 
00544 // Node Edge Graph
00545 
00546 // TODO TNEGraph describe time complexity for basic operations
00548 
00555 class TNEGraph {
00556 public:
00557   typedef TNEGraph TNet;
00558   typedef TPt<TNEGraph> PNet;
00559 public:
00560   class TNode {
00561   private:
00562     TInt Id;
00563     TIntV InEIdV, OutEIdV;
00564   public:
00565     TNode() : Id(-1), InEIdV(), OutEIdV() { }
00566     TNode(const int& NId) : Id(NId), InEIdV(), OutEIdV() { }
00567     TNode(const TNode& Node) : Id(Node.Id), InEIdV(Node.InEIdV), OutEIdV(Node.OutEIdV) { }
00568     TNode(TSIn& SIn) : Id(SIn), InEIdV(SIn), OutEIdV(SIn) { }
00569     void Save(TSOut& SOut) const { Id.Save(SOut);  InEIdV.Save(SOut);  OutEIdV.Save(SOut);  }
00570     int GetId() const { return Id; }
00571     int GetDeg() const { return GetInDeg() + GetOutDeg(); }
00572     int GetInDeg() const { return InEIdV.Len(); }
00573     int GetOutDeg() const { return OutEIdV.Len(); }
00574     int GetInEId(const int& EdgeN) const { return InEIdV[EdgeN]; }
00575     int GetOutEId(const int& EdgeN) const { return OutEIdV[EdgeN]; }
00576     int GetNbrEId(const int& EdgeN) const { return EdgeN<GetOutDeg()?GetOutEId(EdgeN):GetInEId(EdgeN-GetOutDeg()); }
00577     bool IsInEId(const int& EId) const { return InEIdV.SearchBin(EId) != -1; }
00578     bool IsOutEId(const int& EId) const { return OutEIdV.SearchBin(EId) != -1; }
00579     friend class TNEGraph;
00580   };
00581   class TEdge {
00582   private:
00583     TInt Id, SrcNId, DstNId;
00584   public:
00585     TEdge() : Id(-1), SrcNId(-1), DstNId(-1) { }
00586     TEdge(const int& EId, const int& SourceNId, const int& DestNId) : Id(EId), SrcNId(SourceNId), DstNId(DestNId) { }
00587     TEdge(const TEdge& Edge) : Id(Edge.Id), SrcNId(Edge.SrcNId), DstNId(Edge.DstNId) { }
00588     TEdge(TSIn& SIn) : Id(SIn), SrcNId(SIn), DstNId(SIn) { }
00589     void Save(TSOut& SOut) const { Id.Save(SOut);  SrcNId.Save(SOut);  DstNId.Save(SOut); }
00590     int GetId() const { return Id; }
00591     int GetSrcNId() const { return SrcNId; }
00592     int GetDstNId() const { return DstNId; }
00593     friend class TNEGraph;
00594   };
00596   class TNodeI {
00597   private:
00598     typedef THash<TInt, TNode>::TIter THashIter;
00599     THashIter NodeHI;
00600     const TNEGraph *Graph;
00601   public:
00602     TNodeI() : NodeHI(), Graph(NULL) { }
00603     TNodeI(const THashIter& NodeHIter, const TNEGraph* GraphPt) : NodeHI(NodeHIter), Graph(GraphPt) { }
00604     TNodeI(const TNodeI& NodeI) : NodeHI(NodeI.NodeHI), Graph(NodeI.Graph) { }
00605     TNodeI& operator = (const TNodeI& NodeI) { NodeHI = NodeI.NodeHI;  Graph=NodeI.Graph;  return *this; }
00607     TNodeI& operator++ (int) { NodeHI++;  return *this; }
00608     bool operator < (const TNodeI& NodeI) const { return NodeHI < NodeI.NodeHI; }
00609     bool operator == (const TNodeI& NodeI) const { return NodeHI == NodeI.NodeHI; }
00611     int GetId() const { return NodeHI.GetDat().GetId(); }
00613     int GetDeg() const { return NodeHI.GetDat().GetDeg(); }
00615     int GetInDeg() const { return NodeHI.GetDat().GetInDeg(); }
00617     int GetOutDeg() const { return NodeHI.GetDat().GetOutDeg(); }
00619 
00621     int GetInNId(const int& EdgeN) const { return Graph->GetEdge(NodeHI.GetDat().GetInEId(EdgeN)).GetSrcNId(); }
00623 
00625     int GetOutNId(const int& EdgeN) const { return Graph->GetEdge(NodeHI.GetDat().GetOutEId(EdgeN)).GetDstNId(); }
00627 
00629     int GetNbrNId(const int& EdgeN) const { const TEdge& E = Graph->GetEdge(NodeHI.GetDat().GetNbrEId(EdgeN));
00630       return GetId()==E.GetSrcNId() ? E.GetDstNId():E.GetSrcNId(); }
00632     bool IsInNId(const int& NId) const;
00634     bool IsOutNId(const int& NId) const;
00636     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
00637     // edges
00639     int GetInEId(const int& EdgeN) const { return NodeHI.GetDat().GetInEId(EdgeN); }
00641     int GetOutEId(const int& EdgeN) const { return NodeHI.GetDat().GetOutEId(EdgeN); }
00643     int GetNbrEId(const int& EdgeN) const { return NodeHI.GetDat().GetNbrEId(EdgeN); }
00645     bool IsInEId(const int& EId) const { return NodeHI.GetDat().IsInEId(EId); }
00647     bool IsOutEId(const int& EId) const { return NodeHI.GetDat().IsOutEId(EId); }
00649     bool IsNbrEId(const int& EId) const { return IsInEId(EId) || IsOutEId(EId); }
00650     friend class TNEGraph;
00651   };
00653   class TEdgeI {
00654   private:
00655     typedef THash<TInt, TEdge>::TIter THashIter;
00656     THashIter EdgeHI;
00657     const TNEGraph *Graph;
00658   public:
00659     TEdgeI() : EdgeHI(), Graph(NULL) { }
00660     TEdgeI(const THashIter& EdgeHIter, const TNEGraph *GraphPt) : EdgeHI(EdgeHIter), Graph(GraphPt) { }
00661     TEdgeI(const TEdgeI& EdgeI) : EdgeHI(EdgeI.EdgeHI), Graph(EdgeI.Graph) { }
00662     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { EdgeHI=EdgeI.EdgeHI;  Graph=EdgeI.Graph; }  return *this; }
00664     TEdgeI& operator++ (int) { EdgeHI++;  return *this; }
00665     bool operator < (const TEdgeI& EdgeI) const { return EdgeHI < EdgeI.EdgeHI; }
00666     bool operator == (const TEdgeI& EdgeI) const { return EdgeHI == EdgeI.EdgeHI; }
00668     int GetId() const { return EdgeHI.GetDat().GetId(); }
00670     int GetSrcNId() const { return EdgeHI.GetDat().GetSrcNId(); }
00672     int GetDstNId() const { return EdgeHI.GetDat().GetDstNId(); }
00673     friend class TNEGraph;
00674   };
00675 
00676 private:
00677   TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
00678   const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
00679   TEdge& GetEdge(const int& EId) { return EdgeH.GetDat(EId); }
00680   const TEdge& GetEdge(const int& EId) const { return EdgeH.GetDat(EId); }
00681 private:
00682   TCRef CRef;
00683   TInt MxNId, MxEId;
00684   THash<TInt, TNode> NodeH;
00685   THash<TInt, TEdge> EdgeH;
00686 public:
00687   TNEGraph() : CRef(), MxNId(0), MxEId(0) { }
00689   explicit TNEGraph(const int& Nodes, const int& Edges) : CRef(), MxNId(0), MxEId(0) { Reserve(Nodes, Edges); }
00690   TNEGraph(const TNEGraph& Graph) : MxNId(Graph.MxNId), MxEId(Graph.MxEId), NodeH(Graph.NodeH), EdgeH(Graph.EdgeH) { }
00692   TNEGraph(TSIn& SIn) : MxNId(SIn), MxEId(SIn), NodeH(SIn), EdgeH(SIn) { }
00694   void Save(TSOut& SOut) const { MxNId.Save(SOut);  MxEId.Save(SOut);  NodeH.Save(SOut);  EdgeH.Save(SOut); }
00696   static PNEGraph New() { return PNEGraph(new TNEGraph()); }
00698 
00700   static PNEGraph New(const int& Nodes, const int& Edges) { return PNEGraph(new TNEGraph(Nodes, Edges)); }
00702   static PNEGraph Load(TSIn& SIn) { return PNEGraph(new TNEGraph(SIn)); }
00704   bool HasFlag(const TGraphFlag& Flag) const;
00705   TNEGraph& operator = (const TNEGraph& Graph) { if (this!=&Graph) {
00706     MxNId=Graph.MxNId; MxEId=Graph.MxEId; NodeH=Graph.NodeH; EdgeH=Graph.EdgeH; }  return *this; }
00707 
00709   int GetNodes() const { return NodeH.Len(); }
00711 
00715   int AddNode(int NId = -1);
00717   int AddNode(const TNodeI& NodeId) { return AddNode(NodeId.GetId()); }
00719 
00721   void DelNode(const int& NId);
00723   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
00725   bool IsNode(const int& NId) const { return NodeH.IsKey(NId); }
00727   TNodeI BegNI() const { return TNodeI(NodeH.BegI(), this); }
00729   TNodeI EndNI() const { return TNodeI(NodeH.EndI(), this); }
00731   TNodeI GetNI(const int& NId) const { return TNodeI(NodeH.GetI(NId), this); }
00733   int GetMxNId() const { return MxNId; }
00734 
00736   int GetEdges() const { return EdgeH.Len(); }
00738 
00743   int AddEdge(const int& SrcNId, const int& DstNId, int EId  = -1);
00745   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId(), EdgeI.GetId()); }
00747   void DelEdge(const int& EId);
00749 
00753   void DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true);
00755   bool IsEdge(const int& EId) const { return EdgeH.IsKey(EId); }
00757   bool IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true) const { int EId;  return IsEdge(SrcNId, DstNId, EId, IsDir); }
00759   bool IsEdge(const int& SrcNId, const int& DstNId, int& EId, const bool& IsDir = true) const;
00761   int GetEId(const int& SrcNId, const int& DstNId) const { int EId; return IsEdge(SrcNId, DstNId, EId)?EId:-1; }
00763   TEdgeI BegEI() const { return TEdgeI(EdgeH.BegI(), this); }
00765   TEdgeI EndEI() const { return TEdgeI(EdgeH.EndI(), this); }
00766   // TODO document TNEGraph::GetEI()
00767   TEdgeI GetEI(const int& EId) const { return TEdgeI(EdgeH.GetI(EId), this); }
00768   // TODO document TNEGraph::GetEI()
00769   TEdgeI GetEI(const int& SrcNId, const int& DstNId) const { return GetEI(GetEId(SrcNId, DstNId)); }
00770 
00772   int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); }
00774   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
00776   int GetRndEId(TRnd& Rnd=TInt::Rnd) { return EdgeH.GetKey(EdgeH.GetRndKeyId(Rnd, 0.8)); }
00778   TEdgeI GetRndEI(TRnd& Rnd=TInt::Rnd) { return GetEI(GetRndEId(Rnd)); }
00780   void GetNIdV(TIntV& NIdV) const;
00782   void GetEIdV(TIntV& EIdV) const;
00783 
00785   bool Empty() const { return GetNodes()==0; }
00787   void Clr() { MxNId=0;  MxEId=0;  NodeH.Clr();  EdgeH.Clr(); }
00789   void Reserve(const int& Nodes, const int& Edges) {
00790     if (Nodes>0) NodeH.Gen(Nodes/2);  if (Edges>0) EdgeH.Gen(Edges/2); }
00792 
00797   void Defrag(const bool& OnlyNodeLinks=false);
00799 
00802   bool IsOk(const bool& ThrowExcept=true) const;
00804   void Dump(FILE *OutF=stdout) const;
00805   // TODO implement and document TNEGraph::GetSmallGraph()
00806   static PNEGraph GetSmallGraph();
00807   friend class TPt<TNEGraph>;
00808 };
00809 
00810 // set flags
00811 namespace TSnap {
00812 template <> struct IsMultiGraph<TNEGraph> { enum { Val = 1 }; };
00813 template <> struct IsDirected<TNEGraph> { enum { Val = 1 }; };
00814 }
00815 
00818 
00819 class TBPGraph {
00820 public:
00821   typedef TBPGraph TNet;
00822   typedef TPt<TBPGraph> PNet;
00823   typedef enum { bgsUndef, bgsLeft, bgsRight, bgsBoth } TNodeTy; // left or right hand side node
00824 public:
00825   class TNode {
00826   private:
00827     TInt Id;
00828     TIntV NIdV;
00829     TNodeTy NodeTy; // remove
00830   public:
00831     TNode() : Id(-1), NIdV(), NodeTy(bgsUndef) { }
00832     TNode(const int& NId) : Id(NId), NIdV(), NodeTy(true?bgsLeft:bgsRight) { }
00833     TNode(const TNode& Node) : Id(Node.Id), NIdV(Node.NIdV), NodeTy(Node.NodeTy) { }
00834     TNode(TSIn& SIn) : Id(SIn), NIdV(SIn), NodeTy(bgsUndef) { TInt Ty(SIn);  NodeTy=(TNodeTy)Ty.Val; }
00835     void Save(TSOut& SOut) const { Id.Save(SOut);  NIdV.Save(SOut);  TInt(NodeTy).Save(SOut); }
00836     int GetId() const { return Id; }
00837     int GetDeg() const { return NIdV.Len(); }
00838     int GetInDeg() const { return GetDeg(); }
00839     int GetOutDeg() const { return GetDeg(); }
00840     int GetInNId(const int& NodeN) const { return GetNbrNId(NodeN); }
00841     int GetOutNId(const int& NodeN) const { return GetNbrNId(NodeN); }
00842     int GetNbrNId(const int& NodeN) const { return NIdV[NodeN]; }
00843     bool IsNbrNId(const int& NId) const { return NIdV.SearchBin(NId)!=-1; }
00844     bool IsInNId(const int& NId) const { return IsNbrNId(NId); }
00845     bool IsOutNId(const int& NId) const { return IsNbrNId(NId); }
00846     void PackOutNIdV() { NIdV.Pack(); }
00847     void PackNIdV() { NIdV.Pack(); }
00848     friend class TBPGraph;
00849   };
00851   class TNodeI {
00852   private:
00853     typedef THash<TInt, TNode>::TIter THashIter;
00854     THashIter LeftHI, RightHI; // iterator over left and right hand-side nodes
00855   private:
00856     inline THashIter HI() const { return ! LeftHI.IsEnd()?LeftHI:RightHI; }
00857   public:
00858     TNodeI() : LeftHI(), RightHI() { }
00859     TNodeI(const THashIter& LeftHIter, const THashIter& RightHIter) : LeftHI(LeftHIter), RightHI(RightHIter) { }
00860     TNodeI(const TNodeI& NodeI) : LeftHI(NodeI.LeftHI), RightHI(NodeI.RightHI) { }
00861     TNodeI& operator = (const TNodeI& NodeI) { LeftHI = NodeI.LeftHI;  RightHI=NodeI.RightHI;  return *this; }
00863     TNodeI& operator++ (int) { 
00864       if (! LeftHI.IsEnd()) { 
00865         LeftHI++; } 
00866       else if (! RightHI.IsEnd()) { 
00867         RightHI++; } 
00868       return *this; }
00869     bool operator < (const TNodeI& NodeI) const { return LeftHI < NodeI.LeftHI || (LeftHI==NodeI.LeftHI && RightHI < NodeI.RightHI); }
00870     bool operator == (const TNodeI& NodeI) const { return LeftHI==NodeI.LeftHI && RightHI==NodeI.RightHI; }
00872     int GetId() const { return HI().GetDat().GetId(); }
00874     bool IsLeft() const { return ! LeftHI.IsEnd(); }
00876     bool IsRight() const { return ! IsLeft(); }
00878     int GetDeg() const { return HI().GetDat().GetDeg(); }
00880     int GetInDeg() const { return HI().GetDat().GetInDeg(); }
00882     int GetOutDeg() const { return HI().GetDat().GetOutDeg(); }
00884 
00885     int GetInNId(const int& NodeN) const { return HI().GetDat().GetInNId(NodeN); }
00887 
00888     int GetOutNId(const int& NodeN) const { return HI().GetDat().GetOutNId(NodeN); }
00890 
00891     int GetNbrNId(const int& NodeN) const { return HI().GetDat().GetNbrNId(NodeN); }
00893     bool IsInNId(const int& NId) const { return HI().GetDat().IsInNId(NId); }
00895     bool IsOutNId(const int& NId) const { return HI().GetDat().IsOutNId(NId); }
00897     bool IsNbrNId(const int& NId) const { return HI().GetDat().IsNbrNId(NId); }
00898     friend class TBPGraph;
00899   };
00901   class TEdgeI {
00902   private:
00903     TNodeI CurNode, EndNode; // end node on the 'left'
00904     int CurEdge;
00905   public:
00906     TEdgeI() : CurNode(), EndNode(), CurEdge(0) { }
00907     TEdgeI(const TNodeI& NodeI, const TNodeI& EndNodeI, const int& EdgeN=0) : CurNode(NodeI), EndNode(EndNodeI), CurEdge(EdgeN) { }
00908     TEdgeI(const TEdgeI& EdgeI) : CurNode(EdgeI.CurNode), EndNode(EdgeI.EndNode), CurEdge(EdgeI.CurEdge) { }
00909     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { CurNode=EdgeI.CurNode;  EndNode=EdgeI.EndNode;  CurEdge=EdgeI.CurEdge; }  return *this; }
00911     TEdgeI& operator++ (int) { CurEdge++; if (CurEdge >= CurNode.GetOutDeg()) { CurEdge=0;  CurNode++;
00912       while (CurNode < EndNode && CurNode.GetOutDeg()==0) { CurNode++; } }  return *this; }
00913     bool operator < (const TEdgeI& EdgeI) const { return CurNode<EdgeI.CurNode || (CurNode==EdgeI.CurNode && CurEdge<EdgeI.CurEdge); }
00914     bool operator == (const TEdgeI& EdgeI) const { return CurNode == EdgeI.CurNode && CurEdge == EdgeI.CurEdge; }
00916     int GetId() const { return -1; }
00918     int GetSrcNId() const { return CurNode.GetId(); }
00920     int GetDstNId() const { return CurNode.GetOutNId(CurEdge); }
00922     int GetLNId() const { return GetSrcNId(); }
00924     int GetRNId() const { return GetDstNId(); }
00925     friend class TBPGraph;
00926   };
00927 private:
00928   TCRef CRef;
00929   TInt MxNId;                 // maximum node id in the graph
00930   THash<TInt, TNode> LeftH;   // 'left' nodes
00931   THash<TInt, TNode> RightH;  // 'right' nodes
00932 private:
00933   //TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
00934   //const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
00935 public:
00936   TBPGraph() : CRef(), MxNId(0), LeftH(), RightH() { }
00938   explicit TBPGraph(const int& Nodes, const int& Edges) : MxNId(0) { } 
00939   TBPGraph(const TBPGraph& BPGraph) : MxNId(BPGraph.MxNId), LeftH(BPGraph.LeftH), RightH(BPGraph.RightH) { }
00941   TBPGraph(TSIn& SIn) : MxNId(SIn), LeftH(SIn), RightH(SIn) { }
00943   void Save(TSOut& SOut) const { MxNId.Save(SOut);  LeftH.Save(SOut);  RightH.Save(SOut); }
00945   static PBPGraph New() { return new TBPGraph(); }
00947 
00948   static PBPGraph New(const int& Nodes, const int& Edges) { return new TBPGraph(Nodes, Edges); }
00950   static PBPGraph Load(TSIn& SIn) { return PBPGraph(new TBPGraph(SIn)); }
00952   bool HasFlag(const TGraphFlag& Flag) const;
00953   TBPGraph& operator = (const TBPGraph& BPGraph) {
00954     if (this!=&BPGraph) { MxNId=BPGraph.MxNId;  LeftH=BPGraph.LeftH;  RightH=BPGraph.RightH; }  return *this; }
00955   
00957   int GetNodes() const { return GetLNodes() + GetRNodes(); }
00959   int GetLNodes() const { return LeftH.Len(); }
00961   int GetRNodes() const { return RightH.Len(); }
00963 
00964   int AddNode(int NId = -1, const bool& LeftNode=true);
00966   int AddNode(const TNodeI& NodeI) { return AddNode(NodeI.GetId(), NodeI.IsLeft()); }
00968 
00969   void DelNode(const int& NId);
00971   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
00973   bool IsNode(const int& NId) const { return IsLNode(NId) || IsRNode(NId); }
00975   bool IsLNode(const int& NId) const { return LeftH.IsKey(NId); }
00977   bool IsRNode(const int& NId) const { return RightH.IsKey(NId); }
00979   int GetMxNId() const { return MxNId; }
00980     
00982   TNodeI BegNI() const { return TNodeI(LeftH.BegI(), RightH.BegI()); }
00984   TNodeI EndNI() const { return TNodeI(LeftH.EndI(), RightH.EndI()); }
00986   TNodeI GetNI(const int& NId) const { return IsLNode(NId) ? TNodeI(LeftH.GetI(NId), RightH.EndI()) : TNodeI(LeftH.EndI(), RightH.GetI(NId)); }
00988   TNodeI BegLNI() const { return TNodeI(LeftH.BegI(), RightH.EndI()); }
00990   TNodeI EndLNI() const { return EndNI(); }
00992   TNodeI BegRNI() const { return TNodeI(LeftH.EndI(), RightH.BegI()); }
00994   TNodeI EndRNI() const { return EndNI(); }
00995 
00997   int GetEdges() const;
00999 
01000   int AddEdge(const int& LeftNId, const int& RightNId);
01002   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId()); }
01004 
01005   void DelEdge(const int& LeftNId, const int& RightNId);
01007   bool IsEdge(const int& LeftNId, const int& RightNId) const;
01009   TEdgeI BegEI() const { TNodeI NI=BegLNI(); while (NI<EndLNI() && (NI.GetOutDeg()==0 || NI.GetId()>NI.GetOutNId(0))) { NI++; } return TEdgeI(NI, EndLNI()); }
01011   TEdgeI EndEI() const { return TEdgeI(EndNI(), EndNI()); }
01013   TEdgeI GetEI(const int& EId) const;
01015 
01016   TEdgeI GetEI(const int& LeftNId, const int& RightNId) const;
01017     
01019   int GetRndNId(TRnd& Rnd=TInt::Rnd);
01021   int GetRndLNId(TRnd& Rnd=TInt::Rnd);
01023   int GetRndRNId(TRnd& Rnd=TInt::Rnd);
01025   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
01027   void GetNIdV(TIntV& NIdV) const;
01029   void GetLNIdV(TIntV& NIdV) const;
01031   void GetRNIdV(TIntV& NIdV) const;
01032 
01034   bool Empty() const { return GetNodes()==0; }
01036   void Clr() { MxNId=0;  LeftH.Clr();  RightH.Clr(); }
01038   void Reserve(const int& Nodes, const int& Edges);
01040 
01041   void Defrag(const bool& OnlyNodeLinks=false);
01043 
01044   bool IsOk(const bool& ThrowExcept=true) const;
01046   void Dump(FILE *OutF=stdout) const;
01048 
01049   static PBPGraph GetSmallGraph();
01050 
01051   friend class TPt<TBPGraph>;
01052 };
01053 
01054 // set flags
01055 namespace TSnap {
01056 template <> struct IsBipart<TBPGraph> { enum { Val = 1 }; };
01057 }