SNAP Library , Developer Reference  2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 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, NEdges;
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), NEdges(0), NodeH() { }
00141   explicit TUNGraph(const int& Nodes, const int& Edges) : MxNId(0), NEdges(0) { Reserve(Nodes, Edges); }
00142   TUNGraph(const TUNGraph& Graph) : MxNId(Graph.MxNId), NEdges(Graph.NEdges), NodeH(Graph.NodeH) { }
00144   TUNGraph(TSIn& SIn) : MxNId(SIn), NEdges(SIn), NodeH(SIn) { }
00146   void Save(TSOut& SOut) const { MxNId.Save(SOut); NEdges.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; NEdges=Graph.NEdges; 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(); TEdgeI EI(NI, EndNI(), 0); if (GetNodes() != 0 && (NI.GetOutDeg()==0 || NI.GetId()>NI.GetOutNId(0))) { EI++; } return EI; }
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; NEdges=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 }