SNAP Library, Developer Reference  2012-10-15 15:06:59
SNAP, a general purpose network analysis and graph mining library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
network.h
Go to the documentation of this file.
00001 
00002 // Node Data
00003 // TNodeData has to implement the following methods:
00004 //  class TNodeData {
00005 //  public:
00006 //    TNodeData() { }
00007 //    TNodeData(TSIn& SIn) { }
00008 //    void Save(TSOut& SOut) const { }
00009 //  };
00010 
00013 template <class TNodeData>
00014 class TNodeNet {
00015 public:
00016   typedef TNodeData TNodeDat;
00017   typedef TNodeNet<TNodeData> TNet;
00018   typedef TPt<TNet> PNet;
00019 public:
00020   class TNode {
00021   private:
00022     TInt Id;
00023     TNodeData NodeDat;
00024     TIntV InNIdV, OutNIdV;
00025   public:
00026     TNode() : Id(-1), NodeDat(), InNIdV(), OutNIdV() { }
00027     TNode(const int& NId) : Id(NId), NodeDat(), InNIdV(), OutNIdV() { }
00028     TNode(const int& NId, const TNodeData& NodeData) : Id(NId), NodeDat(NodeData), InNIdV(), OutNIdV() { }
00029     TNode(const TNode& Node) : Id(Node.Id), NodeDat(Node.NodeDat), InNIdV(Node.InNIdV), OutNIdV(Node.OutNIdV) { }
00030     TNode(TSIn& SIn) : Id(SIn), NodeDat(SIn), InNIdV(SIn), OutNIdV(SIn) { }
00031     void Save(TSOut& SOut) const { Id.Save(SOut);  NodeDat.Save(SOut);  InNIdV.Save(SOut);  OutNIdV.Save(SOut); }
00032     int GetId() const { return Id; }
00033     int GetDeg() const { return GetInDeg() + GetOutDeg(); }
00034     int GetInDeg() const { return InNIdV.Len(); }
00035     int GetOutDeg() const { return OutNIdV.Len(); }
00036     const TNodeData& GetDat() const { return NodeDat; }
00037     TNodeData& GetDat() { return NodeDat; }
00038     int GetInNId(const int& NodeN) const { return InNIdV[NodeN]; }
00039     int GetOutNId(const int& NodeN) const { return OutNIdV[NodeN]; }
00040     int GetNbrNId(const int& NodeN) const { return NodeN<GetOutDeg() ? GetOutNId(NodeN):GetInNId(NodeN-GetOutDeg()); }
00041     bool IsInNId(const int& NId) const { return InNIdV.SearchBin(NId) != -1; }
00042     bool IsOutNId(const int& NId) const { return OutNIdV.SearchBin(NId) != -1; }
00043     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
00044     bool operator < (const TNode& Node) const { return NodeDat < Node.NodeDat; }
00045     friend class TNodeNet<TNodeData>;
00046   };
00047 
00049   class TNodeI {
00050   private:
00051     typedef typename THash<TInt, TNode>::TIter THashIter;
00052     THashIter NodeHI;
00053     TNodeNet *Net;
00054   public:
00055     TNodeI() : NodeHI(), Net(NULL) { }
00056     TNodeI(const THashIter& NodeHIter, const TNodeNet* NetPt) : NodeHI(NodeHIter), Net((TNodeNet *) NetPt) { }
00057     TNodeI(const TNodeI& NodeI) : NodeHI(NodeI.NodeHI), Net(NodeI.Net) { }
00058     TNodeI& operator = (const TNodeI& NodeI) { NodeHI=NodeI.NodeHI; Net=NodeI.Net; return *this; }
00060     TNodeI& operator++ (int) { NodeHI++;  return *this; }
00061     bool operator < (const TNodeI& NodeI) const { return NodeHI < NodeI.NodeHI; }
00062     bool operator == (const TNodeI& NodeI) const { return NodeHI == NodeI.NodeHI; }
00063 
00065     int GetId() const { return NodeHI.GetDat().GetId(); }
00067     int GetDeg() const { return NodeHI.GetDat().GetDeg(); }
00069     int GetInDeg() const { return NodeHI.GetDat().GetInDeg(); }
00071     int GetOutDeg() const { return NodeHI.GetDat().GetOutDeg(); }
00073 
00075     int GetInNId(const int& NodeN) const { return NodeHI.GetDat().GetInNId(NodeN); }
00077 
00079     int GetOutNId(const int& NodeN) const { return NodeHI.GetDat().GetOutNId(NodeN); }
00081 
00083     int GetNbrNId(const int& NodeN) const { return NodeHI.GetDat().GetNbrNId(NodeN); }
00085     bool IsInNId(const int& NId) const { return NodeHI.GetDat().IsInNId(NId); }
00087     bool IsOutNId(const int& NId) const { return NodeHI.GetDat().IsOutNId(NId); }
00089     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
00090     const TNodeData& operator () () const { return NodeHI.GetDat().NodeDat; }
00091     TNodeData& operator () () { return NodeHI.GetDat().GetDat(); }
00092     const TNodeData& GetDat() const { return NodeHI.GetDat().GetDat(); }
00093     TNodeData& GetDat() { return NodeHI.GetDat().GetDat(); }
00094     const TNodeData& GetInNDat(const int& NodeN) const { return Net->GetNDat(GetInNId(NodeN)); }
00095     TNodeData& GetInNDat(const int& NodeN) { return Net->GetNDat(GetInNId(NodeN)); }
00096     const TNodeData& GetOutNDat(const int& NodeN) const { return Net->GetNDat(GetOutNId(NodeN)); }
00097     TNodeData& GetOutNDat(const int& NodeN) { return Net->GetNDat(GetOutNId(NodeN)); }
00098     const TNodeData& GetNbrNDat(const int& NodeN) const { return Net->GetNDat(GetNbrNId(NodeN)); }
00099     TNodeData& GetNbrNDat(const int& NodeN) { return Net->GetNDat(GetNbrNId(NodeN)); }
00100     friend class TNodeNet<TNodeData>;
00101   };
00102 
00104   class TEdgeI {
00105   private:
00106     TNodeI CurNode, EndNode;
00107     int CurEdge;
00108   public:
00109     TEdgeI() : CurNode(), EndNode(), CurEdge(0) { }
00110     TEdgeI(const TNodeI& NodeI, const TNodeI& EndNodeI, const int& EdgeN=0) : CurNode(NodeI), EndNode(EndNodeI), CurEdge(EdgeN) { }
00111     TEdgeI(const TEdgeI& EdgeI) : CurNode(EdgeI.CurNode), EndNode(EdgeI.EndNode), CurEdge(EdgeI.CurEdge) { }
00112     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { CurNode=EdgeI.CurNode;  EndNode=EdgeI.EndNode;  CurEdge=EdgeI.CurEdge; }  return *this; }
00114     TEdgeI& operator++ (int) { CurEdge++; if (CurEdge >= CurNode.GetOutDeg()) { CurEdge=0;  CurNode++;
00115       while (CurNode < EndNode && CurNode.GetOutDeg()==0) { CurNode++; } }  return *this; }
00116     bool operator < (const TEdgeI& EdgeI) const { return CurNode<EdgeI.CurNode || (CurNode==EdgeI.CurNode && CurEdge<EdgeI.CurEdge); }
00117     bool operator == (const TEdgeI& EdgeI) const { return CurNode == EdgeI.CurNode && CurEdge == EdgeI.CurEdge; }
00119     int GetId() const { return -1; }
00121     int GetSrcNId() const { return CurNode.GetId(); }
00123     int GetDstNId() const { return CurNode.GetOutNId(CurEdge); }
00124     const TNodeData& GetSrcNDat() const { return CurNode.GetDat(); }
00125     TNodeData& GetDstNDat() { return CurNode.GetOutNDat(CurEdge); }
00126     friend class TNodeNet<TNodeData>;
00127   };
00128 
00129 protected:
00130   TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
00131 
00132 protected:
00133   TCRef CRef;
00134   TInt MxNId;
00135   THash<TInt, TNode> NodeH;
00136 
00137 public:
00138   TNodeNet() : CRef(), MxNId(0), NodeH() { }
00140   explicit TNodeNet(const int& Nodes, const int& Edges) : MxNId(0) { Reserve(Nodes, Edges); }
00141   TNodeNet(const TNodeNet& NodeNet) : MxNId(NodeNet.MxNId), NodeH(NodeNet.NodeH) { }
00143   TNodeNet(TSIn& SIn) : MxNId(SIn), NodeH(SIn) { }
00144   virtual ~TNodeNet() { }
00146   virtual void Save(TSOut& SOut) const { MxNId.Save(SOut);  NodeH.Save(SOut); }
00148   static PNet New() { return PNet(new TNodeNet()); }
00150   static PNet Load(TSIn& SIn) { return PNet(new TNodeNet(SIn)); }
00152   bool HasFlag(const TGraphFlag& Flag) const;
00153   TNodeNet& operator = (const TNodeNet& NodeNet) {
00154     if (this!=&NodeNet) { NodeH=NodeNet.NodeH;  MxNId=NodeNet.MxNId; }  return *this; }
00155   // nodes
00157   int GetNodes() const { return NodeH.Len(); }
00159 
00163   int AddNode(int NId = -1);
00165 
00169   int AddNode(int NId, const TNodeData& NodeDat);
00171   int AddNode(const TNodeI& NodeId) { return AddNode(NodeId.GetId(), NodeId.GetDat()); }
00173 
00175   void DelNode(const int& NId);
00177   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
00179   bool IsNode(const int& NId) const { return NodeH.IsKey(NId); }
00181   TNodeI BegNI() const { return TNodeI(NodeH.BegI(), this); }
00183   TNodeI EndNI() const { return TNodeI(NodeH.EndI(), this); }
00185   TNodeI GetNI(const int& NId) const { return TNodeI(NodeH.GetI(NId), this); }
00187   const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
00189   void SetNDat(const int& NId, const TNodeData& NodeDat);
00191   TNodeData& GetNDat(const int& NId) { return NodeH.GetDat(NId).NodeDat; }
00193   const TNodeData& GetNDat(const int& NId) const { return NodeH.GetDat(NId).NodeDat; }
00195   int GetMxNId() const { return MxNId; }
00196 
00197   // edges
00199   int GetEdges() const;
00201 
00207   int AddEdge(const int& SrcNId, const int& DstNId);
00209   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId()); }
00211 
00215   void DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true);
00217   bool IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true) const;
00219   TEdgeI BegEI() const { TNodeI NI=BegNI();  while(NI<EndNI() && NI.GetOutDeg()==0) NI++;  return TEdgeI(NI, EndNI()); }
00221   TEdgeI EndEI() const { return TEdgeI(EndNI(), EndNI()); }
00223   TEdgeI GetEI(const int& EId) const; // not supported
00225   TEdgeI GetEI(const int& SrcNId, const int& DstNId) const;
00226 
00228   int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); }
00230   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
00232   void GetNIdV(TIntV& NIdV) const;
00233 
00235   bool Empty() const { return GetNodes()==0; }
00237   void Clr(const bool& DoDel=true, const bool& ResetDat=true) {
00238     MxNId = 0;  NodeH.Clr(DoDel, -1, ResetDat); }
00240   void Reserve(const int& Nodes, const int& Edges) { if (Nodes>0) { NodeH.Gen(Nodes/2); } }
00242   void SortNIdById(const bool& Asc=true) { NodeH.SortByKey(Asc); }
00244   void SortNIdByDat(const bool& Asc=true) { NodeH.SortByDat(Asc); }
00246 
00251   void Defrag(const bool& OnlyNodeLinks=false);
00253 
00256   bool IsOk(const bool& ThrowExcept=true) const;
00257 
00258   friend class TPt<TNodeNet<TNodeData> >;
00259 };
00260 
00261 // set flags
00262 namespace TSnap {
00263 template <class TNodeData> struct IsDirected<TNodeNet<TNodeData> > { enum { Val = 1 }; };
00264 template <class TNodeData> struct IsNodeDat<TNodeNet<TNodeData> > { enum { Val = 1 }; };
00265 }
00266 
00267 template <class TNodeData>
00268 bool TNodeNet<TNodeData>::HasFlag(const TGraphFlag& Flag) const {
00269   return HasGraphFlag(typename TNet, Flag);
00270 }
00271 
00272 template <class TNodeData>
00273 int TNodeNet<TNodeData>::AddNode(int NId) {
00274   if (NId == -1) {
00275     NId = MxNId;  MxNId++;
00276   } else {
00277     IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
00278     MxNId = TMath::Mx(NId+1, MxNId());
00279   }
00280   NodeH.AddDat(NId, TNode(NId));
00281   return NId;
00282 }
00283 
00284 template <class TNodeData>
00285 int TNodeNet<TNodeData>::AddNode(int NId, const TNodeData& NodeDat) {
00286   if (NId == -1) {
00287     NId = MxNId;  MxNId++;
00288   } else {
00289     IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
00290     MxNId = TMath::Mx(NId+1, MxNId());
00291   }
00292   NodeH.AddDat(NId, TNode(NId, NodeDat));
00293   return NId;
00294 }
00295 
00296 template <class TNodeData>
00297 void TNodeNet<TNodeData>::DelNode(const int& NId) {
00298   { TNode& Node = GetNode(NId);
00299   for (int e = 0; e < Node.GetOutDeg(); e++) {
00300   const int nbr = Node.GetOutNId(e);
00301   if (nbr == NId) { continue; }
00302     TNode& N = GetNode(nbr);
00303     int n = N.InNIdV.SearchBin(NId);
00304     if (n!= -1) { N.InNIdV.Del(n); }
00305   }
00306   for (int e = 0; e < Node.GetInDeg(); e++) {
00307   const int nbr = Node.GetInNId(e);
00308   if (nbr == NId) { continue; }
00309     TNode& N = GetNode(nbr);
00310     int n = N.OutNIdV.SearchBin(NId);
00311     if (n!= -1) { N.OutNIdV.Del(n); }
00312   } }
00313   NodeH.DelKey(NId);
00314 }
00315 
00316 template <class TNodeData>
00317 void TNodeNet<TNodeData>::SetNDat(const int& NId, const TNodeData& NodeDat) {
00318   IAssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist.", NId).CStr());
00319   NodeH.GetDat(NId).NodeDat = NodeDat;
00320 }
00321 
00322 template <class TNodeData>
00323 int TNodeNet<TNodeData>::GetEdges() const {
00324   int edges=0;
00325   for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N);) {
00326     edges+=NodeH[N].GetOutDeg(); }
00327   return edges;
00328 }
00329 
00330 template <class TNodeData>
00331 int TNodeNet<TNodeData>::AddEdge(const int& SrcNId, const int& DstNId) {
00332   IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
00333   if (IsEdge(SrcNId, DstNId)) { return -2; }
00334   GetNode(SrcNId).OutNIdV.AddSorted(DstNId);
00335   GetNode(DstNId).InNIdV.AddSorted(SrcNId);
00336   return -1; // edge id
00337 }
00338 
00339 template <class TNodeData>
00340 void TNodeNet<TNodeData>::DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) {
00341   IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
00342   GetNode(SrcNId).OutNIdV.DelIfIn(DstNId);
00343   GetNode(DstNId).InNIdV.DelIfIn(SrcNId);
00344   if (! IsDir) {
00345     GetNode(DstNId).OutNIdV.DelIfIn(SrcNId);
00346     GetNode(SrcNId).InNIdV.DelIfIn(DstNId);
00347   }
00348 }
00349 
00350 template <class TNodeData>
00351 bool TNodeNet<TNodeData>::IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) const {
00352   if (! IsNode(SrcNId) || ! IsNode(DstNId)) { return false; }
00353   if (IsDir) { return GetNode(SrcNId).IsOutNId(DstNId); }
00354   else { return GetNode(SrcNId).IsOutNId(DstNId) || GetNode(DstNId).IsOutNId(SrcNId); }
00355 }
00356 
00357 template <class TNodeData>
00358 void TNodeNet<TNodeData>::GetNIdV(TIntV& NIdV) const {
00359   NIdV.Reserve(GetNodes(), 0);
00360   for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
00361     NIdV.Add(NodeH.GetKey(N)); }
00362 }
00363 
00364 template <class TNodeData>
00365 typename TNodeNet<TNodeData>::TEdgeI  TNodeNet<TNodeData>::GetEI(const int& SrcNId, const int& DstNId) const {
00366   const TNodeI SrcNI = GetNI(SrcNId);
00367   const int NodeN = SrcNI.NodeHI.GetDat().OutNIdV.SearchBin(DstNId);
00368   if (NodeN == -1) { return EndEI(); }
00369   return TEdgeI(SrcNI, EndNI(), NodeN);
00370 }
00371 
00372 template <class TNodeData>
00373 void TNodeNet<TNodeData>::Defrag(const bool& OnlyNodeLinks) {
00374   for (int n = NodeH.FFirstKeyId(); NodeH.FNextKeyId(n); ) {
00375     TNode& Node = NodeH[n];
00376     Node.InNIdV.Pack();  Node.OutNIdV.Pack();
00377   }
00378   if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) {
00379     NodeH.Defrag(); }
00380 }
00381 
00382 template <class TNodeData>
00383 bool TNodeNet<TNodeData>::IsOk(const bool& ThrowExcept) const {
00384   bool RetVal = true;
00385   for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
00386     const TNode& Node = NodeH[N];
00387     if (! Node.OutNIdV.IsSorted()) {
00388       const TStr Msg = TStr::Fmt("Out-neighbor list of node %d is not sorted.", Node.GetId());
00389       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00390     }
00391     if (! Node.InNIdV.IsSorted()) {
00392       const TStr Msg = TStr::Fmt("In-neighbor list of node %d is not sorted.", Node.GetId());
00393       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00394     }
00395     // check out-edges
00396     int prevNId = -1;
00397     for (int e = 0; e < Node.GetOutDeg(); e++) {
00398       if (! IsNode(Node.GetOutNId(e))) {
00399         const TStr Msg = TStr::Fmt("Out-edge %d --> %d: node %d does not exist.",
00400           Node.GetId(), Node.GetOutNId(e), Node.GetOutNId(e));
00401         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00402       }
00403       if (e > 0 && prevNId == Node.GetOutNId(e)) {
00404         const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge %d --> %d.",
00405           Node.GetId(), Node.GetId(), Node.GetOutNId(e));
00406         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00407       }
00408       prevNId = Node.GetOutNId(e);
00409     }
00410     // check in-edges
00411     prevNId = -1;
00412     for (int e = 0; e < Node.GetInDeg(); e++) {
00413       if (! IsNode(Node.GetInNId(e))) {
00414         const TStr Msg = TStr::Fmt("In-edge %d <-- %d: node %d does not exist.",
00415           Node.GetId(), Node.GetInNId(e), Node.GetInNId(e));
00416         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00417       }
00418       if (e > 0 && prevNId == Node.GetInNId(e)) {
00419         const TStr Msg = TStr::Fmt("Node %d has duplidate in-edge %d <-- %d.",
00420           Node.GetId(), Node.GetId(), Node.GetInNId(e));
00421         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00422       }
00423       prevNId = Node.GetInNId(e);
00424     }
00425   }
00426   return RetVal;
00427 }
00428 
00430 // Common network types
00431 typedef TNodeNet<TInt> TIntNNet;
00432 typedef TPt<TIntNNet> PIntNNet;
00433 typedef TNodeNet<TFlt> TFltNNet;
00434 typedef TPt<TFltNNet> PFltNNet;
00435 typedef TNodeNet<TStr> TStrNNet;
00436 typedef TPt<TStrNNet> PStrNNet;
00437 
00440 template <class TNodeData, class TEdgeData>
00441 class TNodeEDatNet {
00442 public:
00443   typedef TNodeData TNodeDat;
00444   typedef TEdgeData TEdgeDat;
00445   typedef TNodeEDatNet<TNodeData, TEdgeData> TNet;
00446   typedef TPt<TNet> PNet;
00447   typedef TVec<TPair<TInt, TEdgeData> > TNIdDatPrV;
00448 public:
00449   class TNode {
00450   private:
00451     TInt  Id;
00452     TNodeData NodeDat;
00453     TIntV InNIdV;
00454     TNIdDatPrV OutNIdV;
00455   public:
00456     TNode() : Id(-1), NodeDat(), InNIdV(), OutNIdV() { }
00457     TNode(const int& NId) : Id(NId), NodeDat(), InNIdV(), OutNIdV() { }
00458     TNode(const int& NId, const TNodeData& NodeData) : Id(NId), NodeDat(NodeData), InNIdV(), OutNIdV() { }
00459     TNode(const TNode& Node) : Id(Node.Id), NodeDat(Node.NodeDat), InNIdV(Node.InNIdV), OutNIdV(Node.OutNIdV) { }
00460     TNode(TSIn& SIn) : Id(SIn), NodeDat(SIn), InNIdV(SIn), OutNIdV(SIn) { }
00461     void Save(TSOut& SOut) const { Id.Save(SOut);  NodeDat.Save(SOut);  InNIdV.Save(SOut);  OutNIdV.Save(SOut); }
00462     int GetId() const { return Id; }
00463     int GetDeg() const { return GetInDeg() + GetOutDeg(); }
00464     int GetInDeg() const { return InNIdV.Len(); }
00465     int GetOutDeg() const { return OutNIdV.Len(); }
00466     const TNodeData& GetDat() const { return NodeDat; }
00467     TNodeData& GetDat() { return NodeDat; }
00468     int GetInNId(const int& EdgeN) const { return InNIdV[EdgeN]; }
00469     int GetOutNId(const int& EdgeN) const { return OutNIdV[EdgeN].Val1; }
00470     int GetNbrNId(const int& EdgeN) const { return EdgeN<GetOutDeg() ? GetOutNId(EdgeN):GetInNId(EdgeN-GetOutDeg()); }
00471     TEdgeData& GetOutEDat(const int& EdgeN) { return OutNIdV[EdgeN].Val2; }
00472     const TEdgeData& GetOutEDat(const int& EdgeN) const { return OutNIdV[EdgeN].Val2; }
00473     bool IsInNId(const int& NId) const { return InNIdV.SearchBin(NId)!=-1; }
00474     bool IsOutNId(const int& NId) const { return TNodeEDatNet::GetNIdPos(OutNIdV, NId)!=-1; }
00475     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
00476     bool operator < (const TNode& Node) const { return NodeDat < Node.NodeDat; }
00477     friend class TNodeEDatNet<TNodeData, TEdgeData>;
00478   };
00479 
00481   class TNodeI {
00482   private:
00483     typedef typename THash<TInt, TNode>::TIter THashIter;
00484     THashIter NodeHI;
00485     TNodeEDatNet *Net;
00486   public:
00487     TNodeI() : NodeHI(), Net(NULL) { }
00488     TNodeI(const THashIter& NodeHIter, const TNodeEDatNet* NetPt) : NodeHI(NodeHIter), Net((TNodeEDatNet *) NetPt) { }
00489     TNodeI(const TNodeI& NodeI) : NodeHI(NodeI.NodeHI), Net(NodeI.Net) { }
00490     TNodeI& operator = (const TNodeI& NodeI) { NodeHI=NodeI.NodeHI; Net=NodeI.Net; return *this; }
00492     TNodeI& operator++ (int) { NodeHI++;  return *this; }
00493     bool operator < (const TNodeI& NodeI) const { return NodeHI < NodeI.NodeHI; }
00494     bool operator == (const TNodeI& NodeI) const { return NodeHI == NodeI.NodeHI; }
00495 
00497     int GetId() const { return NodeHI.GetDat().GetId(); }
00499     int GetDeg() const { return NodeHI.GetDat().GetDeg(); }
00501     int GetInDeg() const { return NodeHI.GetDat().GetInDeg(); }
00503     int GetOutDeg() const { return NodeHI.GetDat().GetOutDeg(); }
00505 
00507     int GetInNId(const int& NodeN) const { return NodeHI.GetDat().GetInNId(NodeN); }
00509 
00511     int GetOutNId(const int& NodeN) const { return NodeHI.GetDat().GetOutNId(NodeN); }
00513 
00515     int GetNbrNId(const int& NodeN) const { return NodeHI.GetDat().GetNbrNId(NodeN); }
00517     bool IsInNId(const int& NId) const { return NodeHI.GetDat().IsInNId(NId); }
00519     bool IsOutNId(const int& NId) const { return NodeHI.GetDat().IsOutNId(NId); }
00521     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
00522     // node data
00523     const TNodeData& operator () () const { return NodeHI.GetDat().NodeDat; }
00524     TNodeData& operator () () { return NodeHI.GetDat().GetDat(); }
00525     const TNodeData& GetDat() const { return NodeHI.GetDat().GetDat(); }
00526     TNodeData& GetDat() { return NodeHI.GetDat().GetDat(); }
00527     const TNodeData& GetOutNDat(const int& NodeN) const { return Net->GetNDat(GetOutNId(NodeN)); }
00528     TNodeData& GetOutNDat(const int& NodeN) { return Net->GetNDat(GetOutNId(NodeN)); }
00529     const TNodeData& GetInNDat(const int& NodeN) const { return Net->GetNDat(GetInNId(NodeN)); }
00530     TNodeData& GetInNDat(const int& NodeN) { return Net->GetNDat(GetInNId(NodeN)); }
00531     const TNodeData& GetNbrNDat(const int& NodeN) const { return Net->GetNDat(GetNbrNId(NodeN)); }
00532     TNodeData& GetNbrNDat(const int& NodeN) { return Net->GetNDat(GetNbrNId(NodeN)); }
00533     // edge data
00534     TEdgeData& GetOutEDat(const int& EdgeN) { return NodeHI.GetDat().GetOutEDat(EdgeN); }
00535     const TEdgeData& GetOutEDat(const int& EdgeN) const { return NodeHI.GetDat().GetOutEDat(EdgeN); }
00536     TEdgeData& GetInEDat(const int& EdgeN) { return Net->GetEDat(GetInNId(EdgeN), GetId()); }
00537     const TEdgeData& GetInEDat(const int& EdgeN) const { return Net->GetEDat(GetInNId(EdgeN), GetId()); }
00538     TEdgeData& GetNbrEDat(const int& EdgeN) { return EdgeN<GetOutDeg() ? GetOutEDat(EdgeN) : GetInEDat(EdgeN-GetOutDeg()); }
00539     const TEdgeData& GetNbrEDat(const int& EdgeN) const { return EdgeN<GetOutDeg() ? GetOutEDat(EdgeN) : GetInEDat(EdgeN-GetOutDeg()); }
00540     friend class TNodeEDatNet<TNodeData, TEdgeData>;
00541   };
00542 
00544   class TEdgeI {
00545   private:
00546     TNodeI CurNode, EndNode;
00547     int CurEdge;
00548   public:
00549     TEdgeI() : CurNode(), EndNode(), CurEdge(0) { }
00550     TEdgeI(const TNodeI& NodeI, const TNodeI& EndNodeI, const int& EdgeN=0) : CurNode(NodeI), EndNode(EndNodeI), CurEdge(EdgeN) { }
00551     TEdgeI(const TEdgeI& EdgeI) : CurNode(EdgeI.CurNode), EndNode(EdgeI.EndNode), CurEdge(EdgeI.CurEdge) { }
00552     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { CurNode=EdgeI.CurNode;  EndNode=EdgeI.EndNode;  CurEdge=EdgeI.CurEdge; }  return *this; }
00554     TEdgeI& operator++ (int) { CurEdge++; if (CurEdge >= CurNode.GetOutDeg()) { CurEdge=0;  CurNode++;
00555       while (CurNode < EndNode && CurNode.GetOutDeg()==0) { CurNode++; } }  return *this; }
00556     bool operator < (const TEdgeI& EdgeI) const { return CurNode<EdgeI.CurNode || (CurNode==EdgeI.CurNode && CurEdge<EdgeI.CurEdge); }
00557     bool operator == (const TEdgeI& EdgeI) const { return CurNode == EdgeI.CurNode && CurEdge == EdgeI.CurEdge; }
00559     int GetId() const { return -1; }
00561     int GetSrcNId() const { return CurNode.GetId(); }
00563     int GetDstNId() const { return CurNode.GetOutNId(CurEdge); }
00564     TEdgeData& operator () () { return CurNode.GetOutEDat(CurEdge); }
00565     const TEdgeData& operator () () const { return CurNode.GetOutEDat(CurEdge); }
00566     TEdgeData& GetDat() { return CurNode.GetOutEDat(CurEdge); }
00567     const TEdgeData& GetDat() const { return CurNode.GetOutEDat(CurEdge); }
00568     TNodeData& GetSrcNDat() { return CurNode(); }
00569     const TNodeData& GetSrcNDat() const { return CurNode(); }
00570     TNodeData& GetDstNDat() { return CurNode.GetOutNDat(CurEdge); }
00571     const TNodeData& GetDstNDat() const { return CurNode.GetOutNDat(CurEdge); }
00572     friend class TNodeEDatNet<TNodeData, TEdgeData>;
00573   };
00574 
00575 protected:
00576   TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
00577   static int GetNIdPos(const TVec<TPair<TInt, TEdgeData> >& NIdV, const int& NId);
00578 protected:
00579   TCRef CRef;
00580   TInt MxNId;
00581   THash<TInt, TNode> NodeH;
00582 public:
00583   TNodeEDatNet() : CRef(), MxNId(0), NodeH() { }
00585   explicit TNodeEDatNet(const int& Nodes, const int& Edges) : MxNId(0) { Reserve(Nodes, Edges); }
00586   TNodeEDatNet(const TNodeEDatNet& NodeNet) : MxNId(NodeNet.MxNId), NodeH(NodeNet.NodeH) { }
00588   TNodeEDatNet(TSIn& SIn) : MxNId(SIn), NodeH(SIn) { }
00589   virtual ~TNodeEDatNet() { }
00591   virtual void Save(TSOut& SOut) const { MxNId.Save(SOut);  NodeH.Save(SOut); }
00593   static PNet New() { return PNet(new TNet()); }
00595   static PNet Load(TSIn& SIn) { return PNet(new TNet(SIn)); }
00597   bool HasFlag(const TGraphFlag& Flag) const;
00598   TNodeEDatNet& operator = (const TNodeEDatNet& NodeNet) { if (this!=&NodeNet) {
00599     NodeH=NodeNet.NodeH;  MxNId=NodeNet.MxNId; }  return *this; }
00600   // nodes
00602   int GetNodes() const { return NodeH.Len(); }
00604 
00608   int AddNode(int NId = -1);
00610 
00614   int AddNode(int NId, const TNodeData& NodeDat);
00616   int AddNode(const TNodeI& NodeId) { return AddNode(NodeId.GetId(), NodeId.GetDat()); }
00618 
00620   void DelNode(const int& NId);
00622   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
00624   bool IsNode(const int& NId) const { return NodeH.IsKey(NId); }
00626   TNodeI BegNI() const { return TNodeI(NodeH.BegI(), this); }
00628   TNodeI EndNI() const { return TNodeI(NodeH.EndI(), this); }
00630   TNodeI GetNI(const int& NId) const { return TNodeI(NodeH.GetI(NId), this); }
00632   const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
00634   void SetNDat(const int& NId, const TNodeData& NodeDat);
00636   TNodeData& GetNDat(const int& NId) { return NodeH.GetDat(NId).NodeDat; }
00638   const TNodeData& GetNDat(const int& NId) const { return NodeH.GetDat(NId).NodeDat; }
00640   int GetMxNId() const { return MxNId; }
00641 
00642   // edges
00644   int GetEdges() const;
00646 
00652   int AddEdge(const int& SrcNId, const int& DstNId);
00654 
00660   int AddEdge(const int& SrcNId, const int& DstNId, const TEdgeData& EdgeDat);
00662   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId(), EdgeI()); }
00664 
00668   void DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true);
00670   bool IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true) const;
00672   TEdgeI BegEI() const { TNodeI NI=BegNI();  while(NI<EndNI() && NI.GetOutDeg()==0) NI++; return TEdgeI(NI, EndNI()); }
00674   TEdgeI EndEI() const { return TEdgeI(EndNI(), EndNI()); }
00676   TEdgeI GetEI(const int& EId) const; // not supported
00678   TEdgeI GetEI(const int& SrcNId, const int& DstNId) const;
00680   void SetEDat(const int& SrcNId, const int& DstNId, const TEdgeData& EdgeDat);
00682 
00684   bool GetEDat(const int& SrcNId, const int& DstNId, TEdgeData& EdgeDat) const;
00686   TEdgeData& GetEDat(const int& SrcNId, const int& DstNId);
00688   const TEdgeData& GetEDat(const int& SrcNId, const int& DstNId) const;
00690   void SetAllEDat(const TEdgeData& EdgeDat);
00691 
00693   int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); }
00695   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
00697   void GetNIdV(TIntV& NIdV) const;
00698 
00700   bool Empty() const { return GetNodes()==0; }
00702   void Clr(const bool& DoDel=true, const bool& ResetDat=true) {
00703     MxNId = 0;  NodeH.Clr(DoDel, -1, ResetDat); }
00705   void Reserve(const int& Nodes, const int& Edges) { if (Nodes>0) { NodeH.Gen(Nodes/2); } }
00707   void SortNIdById(const bool& Asc=true) { NodeH.SortByKey(Asc); }
00709   void SortNIdByDat(const bool& Asc=true) { NodeH.SortByDat(Asc); }
00711 
00716   void Defrag(const bool& OnlyNodeLinks=false);
00718 
00721   bool IsOk(const bool& ThrowExcept=true) const;
00722 
00723   friend class TPt<TNodeEDatNet<TNodeData, TEdgeData> >;
00724 };
00725 
00726 // set flags
00727 namespace TSnap {
00728 template <class TNodeData, class TEdgeData> struct IsDirected<TNodeEDatNet<TNodeData, TEdgeData> > { enum { Val = 1 }; };
00729 template <class TNodeData, class TEdgeData> struct IsNodeDat<TNodeEDatNet<TNodeData, TEdgeData> > { enum { Val = 1 }; };
00730 template <class TNodeData, class TEdgeData> struct IsEdgeDat<TNodeEDatNet<TNodeData, TEdgeData> > { enum { Val = 1 }; };
00731 }
00732 
00733 template <class TNodeData, class TEdgeData>
00734 bool TNodeEDatNet<TNodeData, TEdgeData>::HasFlag(const TGraphFlag& Flag) const {
00735   return HasGraphFlag(typename TNet, Flag);
00736 }
00737 
00738 template <class TNodeData, class TEdgeData>
00739 int TNodeEDatNet<TNodeData, TEdgeData>::GetNIdPos(const TVec<TPair<TInt, TEdgeData> >& NIdV, const int& NId) {
00740   int LValN=0, RValN = NIdV.Len()-1;
00741   while (RValN >= LValN) {
00742     const int ValN = (LValN+RValN)/2;
00743     const int CurNId = NIdV[ValN].Val1;
00744     if (NId == CurNId) { return ValN; }
00745     if (NId < CurNId) { RValN=ValN-1; }
00746     else { LValN=ValN+1; }
00747   }
00748   return -1;
00749 }
00750 
00751 template <class TNodeData, class TEdgeData>
00752 int TNodeEDatNet<TNodeData, TEdgeData>::AddNode(int NId) {
00753   if (NId == -1) {
00754     NId = MxNId;  MxNId++;
00755   } else {
00756     IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
00757     MxNId = TMath::Mx(NId+1, MxNId());
00758   }
00759   NodeH.AddDat(NId, TNode(NId));
00760   return NId;
00761 }
00762 
00763 template <class TNodeData, class TEdgeData>
00764 int TNodeEDatNet<TNodeData, TEdgeData>::AddNode(int NId, const TNodeData& NodeDat) {
00765   if (NId == -1) {
00766     NId = MxNId;  MxNId++;
00767   } else {
00768     IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
00769     MxNId = TMath::Mx(NId+1, MxNId());
00770   }
00771   NodeH.AddDat(NId, TNode(NId, NodeDat));
00772   return NId;
00773 }
00774 
00775 template <class TNodeData, class TEdgeData>
00776 void TNodeEDatNet<TNodeData, TEdgeData>::SetNDat(const int& NId, const TNodeData& NodeDat) {
00777   IAssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist.", NId).CStr());
00778   NodeH.GetDat(NId).NodeDat = NodeDat;
00779 }
00780 
00781 template <class TNodeData, class TEdgeData>
00782 void TNodeEDatNet<TNodeData, TEdgeData>::DelNode(const int& NId) {
00783   const TNode& Node = GetNode(NId);
00784   for (int out = 0; out < Node.GetOutDeg(); out++) {
00785     const int nbr = Node.GetOutNId(out);
00786     if (nbr == NId) { continue; }
00787     TIntV& NIdV = GetNode(nbr).InNIdV;
00788     const int pos = NIdV.SearchBin(NId);
00789     if (pos != -1) { NIdV.Del(pos); }
00790   }
00791   for (int in = 0; in < Node.GetInDeg(); in++) {
00792     const int nbr = Node.GetInNId(in);
00793     if (nbr == NId) { continue; }
00794     TNIdDatPrV& NIdDatV = GetNode(nbr).OutNIdV;
00795     const int pos = GetNIdPos(NIdDatV, NId);
00796     if (pos != -1) { NIdDatV.Del(pos); }
00797   }
00798   NodeH.DelKey(NId);
00799 }
00800 
00801 template <class TNodeData, class TEdgeData>
00802 int TNodeEDatNet<TNodeData, TEdgeData>::GetEdges() const {
00803   int edges=0;
00804   for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
00805     edges+=NodeH[N].GetOutDeg(); }
00806   return edges;
00807 }
00808 
00809 template <class TNodeData, class TEdgeData>
00810 int TNodeEDatNet<TNodeData, TEdgeData>::AddEdge(const int& SrcNId, const int& DstNId) {
00811   return AddEdge(SrcNId, DstNId, TEdgeData());
00812 }
00813 
00814 template <class TNodeData, class TEdgeData>
00815 int TNodeEDatNet<TNodeData, TEdgeData>::AddEdge(const int& SrcNId, const int& DstNId, const TEdgeData& EdgeDat) {
00816   IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
00817   //IAssert(! IsEdge(SrcNId, DstNId));
00818   if (IsEdge(SrcNId, DstNId)) {
00819     GetEDat(SrcNId, DstNId) = EdgeDat;
00820     return -2;
00821   }
00822   GetNode(SrcNId).OutNIdV.AddSorted(TPair<TInt, TEdgeData>(DstNId, EdgeDat));
00823   GetNode(DstNId).InNIdV.AddSorted(SrcNId);
00824   return -1; // edge id
00825 }
00826 
00827 template <class TNodeData, class TEdgeData>
00828 void TNodeEDatNet<TNodeData, TEdgeData>::DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) {
00829   IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
00830   int pos = GetNIdPos(GetNode(SrcNId).OutNIdV, DstNId);
00831   if (pos != -1) { GetNode(SrcNId).OutNIdV.Del(pos); }
00832   pos = GetNode(DstNId).InNIdV.SearchBin(SrcNId);
00833   if (pos != -1) { GetNode(DstNId).InNIdV.Del(pos); }
00834   if (! IsDir) {
00835     pos = GetNIdPos(GetNode(DstNId).OutNIdV, SrcNId);
00836     if (pos != -1) { GetNode(DstNId).OutNIdV.Del(pos); }
00837     pos = GetNode(SrcNId).InNIdV.SearchBin(DstNId);
00838     if (pos != -1) { GetNode(SrcNId).InNIdV.Del(pos); }
00839   }
00840 }
00841 
00842 template <class TNodeData, class TEdgeData>
00843 bool TNodeEDatNet<TNodeData, TEdgeData>::IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) const {
00844   if (! IsNode(SrcNId) || ! IsNode(DstNId)) { return false; }
00845   if (IsDir) { return GetNode(SrcNId).IsOutNId(DstNId); }
00846   else { return GetNode(SrcNId).IsOutNId(DstNId) || GetNode(DstNId).IsOutNId(SrcNId); }
00847 }
00848 
00849 template <class TNodeData, class TEdgeData>
00850 void TNodeEDatNet<TNodeData, TEdgeData>::SetEDat(const int& SrcNId, const int& DstNId, const TEdgeData& EdgeDat) {
00851   IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
00852   IAssertR(IsEdge(SrcNId, DstNId), TStr::Fmt("Edge between %d and %d does not exist.", SrcNId, DstNId).CStr());
00853   GetEDat(SrcNId, DstNId) = EdgeDat;
00854 }
00855 
00856 template <class TNodeData, class TEdgeData>
00857 bool TNodeEDatNet<TNodeData, TEdgeData>::GetEDat(const int& SrcNId, const int& DstNId, TEdgeData& EdgeDat) const {
00858   if (! IsEdge(SrcNId, DstNId)) { return false; }
00859   const TNode& N = GetNode(SrcNId);
00860   EdgeDat = N.GetOutEDat(GetNIdPos(N.OutNIdV, DstNId));
00861   return true;
00862 }
00863 
00864 template <class TNodeData, class TEdgeData>
00865 TEdgeData& TNodeEDatNet<TNodeData, TEdgeData>::GetEDat(const int& SrcNId, const int& DstNId) {
00866   Assert(IsEdge(SrcNId, DstNId));
00867   TNode& N = GetNode(SrcNId);
00868   return N.GetOutEDat(GetNIdPos(N.OutNIdV, DstNId));
00869 }
00870 
00871 template <class TNodeData, class TEdgeData>
00872 const TEdgeData& TNodeEDatNet<TNodeData, TEdgeData>::GetEDat(const int& SrcNId, const int& DstNId) const {
00873   Assert(IsEdge(SrcNId, DstNId));
00874   const TNode& N = GetNode(SrcNId);
00875   return N.GetOutEDat(GetNIdPos(N.OutNIdV, DstNId));
00876 }
00877 
00878 template <class TNodeData, class TEdgeData>
00879 void TNodeEDatNet<TNodeData, TEdgeData>::SetAllEDat(const TEdgeData& EdgeDat) {
00880   for (TEdgeI EI = BegEI(); EI < EndEI(); EI++) {
00881     EI() = EdgeDat;
00882   }
00883 }
00884 
00885 template <class TNodeData, class TEdgeData>
00886 typename TNodeEDatNet<TNodeData, TEdgeData>::TEdgeI  TNodeEDatNet<TNodeData, TEdgeData>::GetEI(const int& SrcNId, const int& DstNId) const {
00887   const TNodeI SrcNI = GetNI(SrcNId);
00888   int NodeN = -1;
00889   //SrcNI.NodeHI.GetDat().OutNIdV.SearchBin(DstNId);
00890   const TNIdDatPrV& NIdDatV = SrcNI.NodeHI.GetDat().OutNIdV;
00891   int LValN=0, RValN=NIdDatV.Len()-1;
00892   while (RValN>=LValN){
00893     int ValN=(LValN+RValN)/2;
00894     if (DstNId==NIdDatV[ValN].Val1){ NodeN=ValN; break; }
00895     if (DstNId<NIdDatV[ValN].Val1){RValN=ValN-1;} else {LValN=ValN+1;}
00896   }
00897   if (NodeN == -1) { return EndEI(); }
00898   else { return TEdgeI(SrcNI, EndNI(), NodeN); }
00899 }
00900 
00901 template <class TNodeData, class TEdgeData>
00902 void TNodeEDatNet<TNodeData, TEdgeData>::GetNIdV(TIntV& NIdV) const {
00903   NIdV.Reserve(GetNodes(), 0);
00904   for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
00905     NIdV.Add(NodeH.GetKey(N)); }
00906 }
00907 
00908 template <class TNodeData, class TEdgeData>
00909 void TNodeEDatNet<TNodeData, TEdgeData>::Defrag(const bool& OnlyNodeLinks) {
00910   for (int n = NodeH.FFirstKeyId(); NodeH.FNextKeyId(n);) {
00911     TNode& Node = NodeH[n];
00912     Node.InNIdV.Pack();  Node.OutNIdV.Pack();
00913   }
00914   if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) {
00915     NodeH.Defrag();
00916   }
00917 }
00918 
00919 template <class TNodeData, class TEdgeData>
00920 bool TNodeEDatNet<TNodeData, TEdgeData>::IsOk(const bool& ThrowExcept) const {
00921   bool RetVal = true;
00922   for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
00923     const TNode& Node = NodeH[N];
00924     if (! Node.OutNIdV.IsSorted()) {
00925       const TStr Msg = TStr::Fmt("Out-neighbor list of node %d is not sorted.", Node.GetId());
00926       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00927     }
00928     if (! Node.InNIdV.IsSorted()) {
00929       const TStr Msg = TStr::Fmt("In-neighbor list of node %d is not sorted.", Node.GetId());
00930       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00931     }
00932     // check out-edges
00933     int prevNId = -1;
00934     for (int e = 0; e < Node.GetOutDeg(); e++) {
00935       if (! IsNode(Node.GetOutNId(e))) {
00936         const TStr Msg = TStr::Fmt("Out-edge %d --> %d: node %d does not exist.",
00937           Node.GetId(), Node.GetOutNId(e), Node.GetOutNId(e));
00938         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00939       }
00940       if (e > 0 && prevNId == Node.GetOutNId(e)) {
00941         const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge %d --> %d.",
00942           Node.GetId(), Node.GetId(), Node.GetOutNId(e));
00943         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00944       }
00945       prevNId = Node.GetOutNId(e);
00946     }
00947     // check in-edges
00948     prevNId = -1;
00949     for (int e = 0; e < Node.GetInDeg(); e++) {
00950       if (! IsNode(Node.GetInNId(e))) {
00951         const TStr Msg = TStr::Fmt("In-edge %d <-- %d: node %d does not exist.",
00952           Node.GetId(), Node.GetInNId(e), Node.GetInNId(e));
00953         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00954       }
00955       if (e > 0 && prevNId == Node.GetInNId(e)) {
00956         const TStr Msg = TStr::Fmt("Node %d has duplidate in-edge %d <-- %d.",
00957           Node.GetId(), Node.GetId(), Node.GetInNId(e));
00958         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
00959       }
00960       prevNId = Node.GetInNId(e);
00961     }
00962   }
00963   return RetVal;
00964 }
00965 
00967 // Common network types
00968 typedef TNodeEDatNet<TInt, TInt> TIntNEDNet;
00969 typedef TPt<TIntNEDNet> PIntNEDNet;
00970 typedef TNodeEDatNet<TInt, TFlt> TIntFltNEDNet;
00971 typedef TPt<TIntFltNEDNet> PIntFltNEDNet;
00972 typedef TNodeEDatNet<TStr, TInt> TStrIntNEDNet;
00973 typedef TPt<TStrIntNEDNet> PStrIntNEDNet;
00974 
00977 template <class TNodeData, class TEdgeData>
00978 class TNodeEdgeNet {
00979 public:
00980   typedef TNodeData TNodeDat;
00981   typedef TEdgeData TEdgeDat;
00982   typedef TNodeEdgeNet<TNodeData, TEdgeData> TNet;
00983   typedef TPt<TNet> PNet;
00984 public:
00985   class TNode {
00986   private:
00987     TInt Id;
00988     TIntV InEIdV, OutEIdV;
00989     TNodeData NodeDat;
00990   public:
00991     TNode() : Id(-1), InEIdV(), OutEIdV(), NodeDat() { }
00992     TNode(const int& NId) : Id(NId), InEIdV(), OutEIdV(), NodeDat()  { }
00993     TNode(const int& NId, const TNodeData& NodeData) : Id(NId), InEIdV(), OutEIdV(), NodeDat(NodeData) { }
00994     TNode(const TNode& Node) : Id(Node.Id), InEIdV(Node.InEIdV), OutEIdV(Node.OutEIdV), NodeDat(Node.NodeDat) { }
00995     TNode(TSIn& SIn) : Id(SIn), InEIdV(SIn), OutEIdV(SIn), NodeDat(SIn) { }
00996     void Save(TSOut& SOut) const { Id.Save(SOut);  InEIdV.Save(SOut);  OutEIdV.Save(SOut);  NodeDat.Save(SOut); }
00997     bool operator < (const TNode& Node) const { return NodeDat < Node.NodeDat; }
00998     int GetId() const { return Id; }
00999     int GetDeg() const { return GetInDeg() + GetOutDeg(); }
01000     int GetInDeg() const { return InEIdV.Len(); }
01001     int GetOutDeg() const { return OutEIdV.Len(); }
01002     const TNodeData& GetDat() const { return NodeDat; }
01003     TNodeData& GetDat() { return NodeDat; }
01004     int GetInEId(const int& NodeN) const { return InEIdV[NodeN]; }
01005     int GetOutEId(const int& NodeN) const { return OutEIdV[NodeN]; }
01006     int GetNbrEId(const int& EdgeN) const { return EdgeN<GetOutDeg()?GetOutEId(EdgeN):GetInEId(EdgeN-GetOutDeg()); }
01007     bool IsInEId(const int& EId) const { return InEIdV.SearchBin(EId) != -1; }
01008     bool IsOutEId(const int& EId) const { return OutEIdV.SearchBin(EId) != -1; }
01009     bool IsNbrEId(const int& EId) const { return IsInEId(EId) || IsOutEId(EId); }
01010     friend class TNodeEdgeNet<TNodeData, TEdgeData>;
01011   };
01012 
01013   class TEdge {
01014   private:
01015     TInt Id, SrcNId, DstNId;
01016     TEdgeData EdgeDat;
01017   public:
01018     TEdge() : Id(-1), SrcNId(-1), DstNId(-1), EdgeDat() { }
01019     TEdge(const int& EId, const int& SourceNId, const int& DestNId) : Id(EId), SrcNId(SourceNId), DstNId(DestNId), EdgeDat() { }
01020     TEdge(const int& EId, const int& SourceNId, const int& DestNId, const TEdgeData& EdgeData) : Id(EId), SrcNId(SourceNId), DstNId(DestNId), EdgeDat(EdgeData) { }
01021     TEdge(const TEdge& Edge) : Id(Edge.Id), SrcNId(Edge.SrcNId), DstNId(Edge.DstNId), EdgeDat(Edge.EdgeDat) { }
01022     TEdge(TSIn& SIn) : Id(SIn), SrcNId(SIn), DstNId(SIn), EdgeDat(SIn) { }
01023     void Save(TSOut& SOut) const { Id.Save(SOut);  SrcNId.Save(SOut);  DstNId.Save(SOut);  EdgeDat.Save(SOut); }
01024     bool operator < (const TEdge& Edge) const { return EdgeDat < Edge.EdgeDat; }
01025     int GetId() const { return Id; }
01026     int GetSrcNId() const { return SrcNId; }
01027     int GetDstNId() const { return DstNId; }
01028     const TEdgeData& GetDat() const { return EdgeDat; }
01029     TEdgeData& GetDat() { return EdgeDat; }
01030     friend class TNodeEdgeNet;
01031   };
01032 
01034   class TNodeI {
01035   private:
01036     typedef typename THash<TInt, TNode>::TIter THashIter;
01037     THashIter NodeHI;
01038     TNodeEdgeNet *Net;
01039   public:
01040     TNodeI() : NodeHI(), Net(NULL) { }
01041     TNodeI(const THashIter& NodeHIter, const TNodeEdgeNet* NetPt) : NodeHI(NodeHIter), Net((TNodeEdgeNet *)NetPt) { }
01042     TNodeI(const TNodeI& NodeI) : NodeHI(NodeI.NodeHI), Net(NodeI.Net) { }
01043     TNodeI& operator = (const TNodeI& NodeI) { NodeHI = NodeI.NodeHI;  Net=NodeI.Net;  return *this; }
01045     TNodeI& operator++ (int) { NodeHI++;  return *this; }
01046     bool operator < (const TNodeI& NodeI) const { return NodeHI < NodeI.NodeHI; }
01047     bool operator == (const TNodeI& NodeI) const { return NodeHI == NodeI.NodeHI; }
01049     int GetId() const { return NodeHI.GetDat().GetId(); }
01051     int GetDeg() const { return NodeHI.GetDat().GetDeg(); }
01053     int GetInDeg() const { return NodeHI.GetDat().GetInDeg(); }
01055     int GetOutDeg() const { return NodeHI.GetDat().GetOutDeg(); }
01057 
01059     int GetInNId(const int& EdgeN) const { return Net->GetEdge(NodeHI.GetDat().GetInEId(EdgeN)).GetSrcNId(); }
01061 
01063     int GetOutNId(const int& EdgeN) const { return Net->GetEdge(NodeHI.GetDat().GetOutEId(EdgeN)).GetDstNId(); }
01065 
01067     int GetNbrNId(const int& EdgeN) const { const TEdge& E = Net->GetEdge(NodeHI.GetDat().GetNbrEId(EdgeN));
01068       return GetId()==E.GetSrcNId() ? E.GetDstNId():E.GetSrcNId(); }
01070     bool IsInNId(const int& NId) const;
01072     bool IsOutNId(const int& NId) const;
01074     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
01075     // node data
01076     const TNodeData& operator () () const { return NodeHI.GetDat().GetDat(); }
01077     TNodeData& operator () () { return NodeHI.GetDat().GetDat(); }
01078     const TNodeData& GetDat() const { return NodeHI.GetDat().GetDat(); }
01079     TNodeData& GetDat() { return NodeHI.GetDat().GetDat(); }
01080     const TNodeData& GetInNDat(const int& EdgeN) const { return Net->GetNDat(GetInNId(EdgeN)); }
01081     TNodeData& GetInNDat(const int& EdgeN) { return Net->GetNodeDat(GetInNId(EdgeN)); }
01082     const TNodeData& GetOutNDat(const int& EdgeN) const { return Net->GetNDat(GetOutNId(EdgeN)); }
01083     TNodeData& GetOutNDat(const int& EdgeN) { return Net->GetNDat(GetOutNId(EdgeN)); }
01084     const TNodeData& GetNbrNDat(const int& EdgeN) const { return Net->GetNDat(GetNbrNId(EdgeN)); }
01085     TNodeData& GetNbrNDat(const int& EdgeN) { return Net->GetNDat(GetNbrNId(EdgeN)); }
01086     // edges
01088     int GetInEId(const int& EdgeN) const { return NodeHI.GetDat().GetInEId(EdgeN); }
01090     int GetOutEId(const int& EdgeN) const { return NodeHI.GetDat().GetOutEId(EdgeN); }
01092     int GetNbrEId(const int& EdgeN) const { return NodeHI.GetDat().GetNbrEId(EdgeN); }
01094     bool IsInEId(const int& EId) const { return NodeHI.GetDat().IsInEId(EId); }
01096     bool IsOutEId(const int& EId) const { return NodeHI.GetDat().IsOutEId(EId); }
01098     bool IsNbrEId(const int& EId) const { return NodeHI.GetDat().IsNbrEId(EId); }
01099     // edge data
01100     TEdgeDat& GetInEDat(const int& EdgeN) { return Net->GetEDat(GetInEId(EdgeN)); }
01101     const TEdgeDat& GetInEDat(const int& EdgeN) const { return Net->GetEDat(GetInEId(EdgeN)); }
01102     TEdgeDat& GetOutEDat(const int& EdgeN) { return Net->GetEDat(GetOutEId(EdgeN)); }
01103     const TEdgeDat& GetOutEDat(const int& EdgeN) const { return Net->GetEDat(GetOutEId(EdgeN)); }
01104     TEdgeDat& GetNbrEDat(const int& EdgeN) { return Net->GetEDat(GetNbrEId(EdgeN)); }
01105     const TEdgeDat& GetNbrEDat(const int& EdgeN) const { return Net->GetEDat(GetNbrEId(EdgeN)); }
01106     friend class TNodeEdgeNet;
01107   };
01108 
01110   class TEdgeI {
01111   private:
01112     typedef typename THash<TInt, TEdge>::TIter THashIter;
01113     THashIter EdgeHI;
01114     TNodeEdgeNet *Net;
01115   public:
01116     TEdgeI() : EdgeHI(), Net(NULL) { }
01117     TEdgeI(const THashIter& EdgeHIter, const TNodeEdgeNet *NetPt) : EdgeHI(EdgeHIter), Net((TNodeEdgeNet *) NetPt) { }
01118     TEdgeI(const TEdgeI& EdgeI) : EdgeHI(EdgeI.EdgeHI), Net(EdgeI.Net) { }
01119     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { EdgeHI=EdgeI.EdgeHI;  Net=EdgeI.Net; }  return *this; }
01120     TEdgeI& operator++ (int) { EdgeHI++;  return *this; }
01121     bool operator < (const TEdgeI& EdgeI) const { return EdgeHI < EdgeI.EdgeHI; }
01122     bool operator == (const TEdgeI& EdgeI) const { return EdgeHI == EdgeI.EdgeHI; }
01124     int GetId() const { return EdgeHI.GetDat().GetId(); }
01126     int GetSrcNId() const { return EdgeHI.GetDat().GetSrcNId(); }
01128     int GetDstNId() const { return EdgeHI.GetDat().GetDstNId(); }
01129     const TEdgeData& operator () () const { return EdgeHI.GetDat().GetDat(); }
01130     TEdgeData& operator () () { return EdgeHI.GetDat().GetDat(); }
01131     const TEdgeData& GetDat() const { return EdgeHI.GetDat().GetDat(); }
01132     TEdgeData& GetDat() { return EdgeHI.GetDat().GetDat(); }
01133     const TNodeData& GetSrcNDat() const { return Net->GetNDat(GetSrcNId()); }
01134     TNodeData& GetSrcNDat() { return Net->GetNDat(GetSrcNId()); }
01135     const TNodeData& GetDstNDat() const { return Net->GetNDat(GetDstNId()); }
01136     TNodeData& GetDstNDat() { return Net->GetNDat(GetDstNId()); }
01137     friend class TNodeEdgeNet;
01138   };
01139 
01140 private:
01141   TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
01142   const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
01143   const TNode& GetNodeKId(const int& NodeKeyId) const { return NodeH[NodeKeyId]; }
01144   TEdge& GetEdge(const int& EId) { return EdgeH.GetDat(EId); }
01145   const TEdge& GetEdge(const int& EId) const { return EdgeH.GetDat(EId); }
01146   const TEdge& GetEdgeKId(const int& EdgeKeyId) const { return EdgeH[EdgeKeyId]; }
01147 protected:
01148   TCRef CRef;
01149   TInt MxNId, MxEId;
01150   THash<TInt, TNode> NodeH;
01151   THash<TInt, TEdge> EdgeH;
01152 public:
01153   TNodeEdgeNet() : CRef(), MxNId(0), MxEId(0) { }
01155   explicit TNodeEdgeNet(const int& Nodes, const int& Edges) : CRef(), MxNId(0), MxEId(0) { Reserve(Nodes, Edges); }
01156   TNodeEdgeNet(const TNodeEdgeNet& Net) : MxNId(Net.MxNId), MxEId(Net.MxEId), NodeH(Net.NodeH), EdgeH(Net.EdgeH) { }
01158   TNodeEdgeNet(TSIn& SIn) : MxNId(SIn), MxEId(SIn), NodeH(SIn), EdgeH(SIn) { }
01159   virtual ~TNodeEdgeNet() { }
01161   virtual void Save(TSOut& SOut) const { MxNId.Save(SOut);  MxEId.Save(SOut);  NodeH.Save(SOut);  EdgeH.Save(SOut); }
01163   static PNet New() { return PNet(new TNet()); }
01165   static PNet Load(TSIn& SIn) { return PNet(new TNet(SIn)); }
01167   bool HasFlag(const TGraphFlag& Flag) const;
01168   TNodeEdgeNet& operator = (const TNodeEdgeNet& Net) {
01169     if (this!=&Net) { NodeH=Net.NodeH; EdgeH=Net.EdgeH; MxNId=Net.MxNId; MxEId=Net.MxEId; }  return *this; }
01170   // nodes
01172   int GetNodes() const { return NodeH.Len(); }
01174 
01178   int AddNode(int NId = -1);
01180 
01184   int AddNode(int NId, const TNodeData& NodeDat);
01186   int AddNode(const TNodeI& NodeId) { return AddNode(NodeId.GetId(), NodeId.GetDat()); }
01188 
01190   void DelNode(const int& NId);
01192   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
01194   bool IsNode(const int& NId) const { return NodeH.IsKey(NId); }
01196   TNodeI BegNI() const { return TNodeI(NodeH.BegI(), this); }
01198   TNodeI EndNI() const { return TNodeI(NodeH.EndI(), this); }
01200   TNodeI GetNI(const int& NId) const { return TNodeI(NodeH.GetI(NId), this); }
01202   void SetNDat(const int& NId, const TNodeData& NodeDat);
01204   TNodeData& GetNDat(const int& NId) { return NodeH.GetDat(NId).NodeDat; }
01206   const TNodeData& GetNDat(const int& NId) const { return NodeH.GetDat(NId).NodeDat; }
01208   int GetMxNId() const { return MxNId; }
01209 
01210   // edges
01212   int GetEdges() const { return EdgeH.Len(); }
01214   int GetUniqEdges(const bool& IsDir=true) const;
01216 
01221   int AddEdge(const int& SrcNId, const int& DstNId, int EId = -1);
01223 
01228   int AddEdge(const int& SrcNId, const int& DstNId, int EId, const TEdgeData& EdgeDat);
01230   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId(), EdgeI.GetId(), EdgeI.GetDat()); }
01232   void DelEdge(const int& EId);
01234 
01238   void DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true);
01240   bool IsEdge(const int& EId) const { return EdgeH.IsKey(EId); }
01242   bool IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true) const { int EId;  return IsEdge(SrcNId, DstNId, EId, IsDir); }
01244   bool IsEdge(const int& SrcNId, const int& DstNId, int& EId, const bool& IsDir = true) const;
01245   int GetEId(const int& SrcNId, const int& DstNId) const { int EId; return IsEdge(SrcNId, DstNId, EId)?EId:-1; }
01247   TEdgeI BegEI() const { return TEdgeI(EdgeH.BegI(), this); }
01249   TEdgeI EndEI() const { return TEdgeI(EdgeH.EndI(), this); }
01250   // TODO document TNodeEdgeNet::GetEI()
01251   TEdgeI GetEI(const int& EId) const { return TEdgeI(EdgeH.GetI(EId), this); }
01252   // TODO document TNodeEdgeNet::GetEI()
01253   TEdgeI GetEI(const int& SrcNId, const int& DstNId) const { return GetEI(GetEId(SrcNId, DstNId)); }
01255   void SetEDat(const int& EId, const TEdgeData& EdgeDat);
01257   TEdgeData& GetEDat(const int& EId) { return EdgeH.GetDat(EId).EdgeDat; }
01259   const TEdgeData& GetEDat(const int& EId) const { return EdgeH.GetDat(EId).EdgeDat; }
01261   void SetAllEDat(const TEdgeData& EdgeDat);
01262 
01264   int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); }
01266   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
01268   int GetRndEId(TRnd& Rnd=TInt::Rnd) { return EdgeH.GetKey(EdgeH.GetRndKeyId(Rnd, 0.8)); }
01270   TEdgeI GetRndEI(TRnd& Rnd=TInt::Rnd) { return GetEI(GetRndEId(Rnd)); }
01272   void GetNIdV(TIntV& NIdV) const;
01274   void GetEIdV(TIntV& EIdV) const;
01275 
01277   bool Empty() const { return GetNodes()==0; }
01279   void Clr() { MxNId=0;  MxEId=0;  NodeH.Clr();  EdgeH.Clr(); }
01281   void Reserve(const int& Nodes, const int& Edges) {
01282     if (Nodes>0) { NodeH.Gen(Nodes/2); }  if (Edges>0) { EdgeH.Gen(Edges/2); } }
01284   void SortNIdById(const bool& Asc=true) { NodeH.SortByKey(Asc); }
01286   void SortNIdByDat(const bool& Asc=true) { NodeH.SortByDat(Asc); }
01288   void SortEIdById(const bool& Asc=true) { EdgeH.SortByKey(Asc); }
01290   void SortEIdByDat(const bool& Asc=true) { EdgeH.SortByDat(Asc); }
01292 
01297   void Defrag(const bool& OnlyNodeLinks=false);
01299 
01302   bool IsOk(const bool& ThrowExcept=true) const;
01303 
01304   friend class TPt<TNodeEdgeNet<TNodeData, TEdgeData> >;
01305 };
01306 
01307 // set flags
01308 namespace TSnap {
01309 template <class TNodeData, class TEdgeData> struct IsMultiGraph<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; };
01310 template <class TNodeData, class TEdgeData> struct IsDirected<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; };
01311 template <class TNodeData, class TEdgeData> struct IsNodeDat<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; };
01312 template <class TNodeData, class TEdgeData> struct IsEdgeDat<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; };
01313 }
01314 
01315 template <class TNodeData, class TEdgeData>
01316 bool TNodeEdgeNet<TNodeData, TEdgeData>::HasFlag(const TGraphFlag& Flag) const {
01317   return HasGraphFlag(typename TNet, Flag);
01318 }
01319 
01320 template <class TNodeData, class TEdgeData>
01321 bool TNodeEdgeNet<TNodeData, TEdgeData>::TNodeI::IsInNId(const int& NId) const {
01322   const TNode& Node = NodeHI.GetDat();
01323   for (int edge = 0; edge < Node.GetInDeg(); edge++) {
01324     if (NId == Net->GetEdge(Node.GetInEId(edge)).GetSrcNId())
01325       return true;
01326   }
01327   return false;
01328 }
01329 
01330 template <class TNodeData, class TEdgeData>
01331 bool TNodeEdgeNet<TNodeData, TEdgeData>::TNodeI::IsOutNId(const int& NId) const {
01332   const TNode& Node = NodeHI.GetDat();
01333   for (int edge = 0; edge < Node.GetOutDeg(); edge++) {
01334     if (NId == Net->GetEdge(Node.GetOutEId(edge)).GetDstNId())
01335       return true;
01336   }
01337   return false;
01338 }
01339 
01340 template <class TNodeData, class TEdgeData>
01341 int TNodeEdgeNet<TNodeData, TEdgeData>::AddNode(int NId) {
01342   if (NId == -1) {
01343     NId = MxNId;  MxNId++;
01344   } else {
01345     IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
01346     MxNId = TMath::Mx(NId+1, MxNId());
01347   }
01348   NodeH.AddDat(NId, TNode(NId));
01349   return NId;
01350 }
01351 
01352 template <class TNodeData, class TEdgeData>
01353 int TNodeEdgeNet<TNodeData, TEdgeData>::AddNode(int NId, const TNodeData& NodeDat) {
01354   if (NId == -1) {
01355     NId = MxNId;  MxNId++;
01356   } else {
01357     IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
01358     MxNId = TMath::Mx(NId+1, MxNId());
01359   }
01360   NodeH.AddDat(NId, TNode(NId, NodeDat));
01361   return NId;
01362 }
01363 
01364 template <class TNodeData, class TEdgeData>
01365 void TNodeEdgeNet<TNodeData, TEdgeData>::DelNode(const int& NId) {
01366   const TNode& Node = GetNode(NId);
01367   for (int out = 0; out < Node.GetOutDeg(); out++) {
01368     const int EId = Node.GetOutEId(out);
01369     const TEdge& Edge = GetEdge(EId);
01370     IAssert(Edge.GetSrcNId() == NId);
01371     GetNode(Edge.GetDstNId()).InEIdV.DelIfIn(EId);
01372     EdgeH.DelKey(EId);
01373   }
01374   for (int in = 0; in < Node.GetInDeg(); in++) {
01375     const int EId = Node.GetInEId(in);
01376     const TEdge& Edge = GetEdge(EId);
01377     IAssert(Edge.GetDstNId() == NId);
01378     GetNode(Edge.GetSrcNId()).OutEIdV.DelIfIn(EId);
01379     EdgeH.DelKey(EId);
01380   }
01381   NodeH.DelKey(NId);
01382 }
01383 
01384 template <class TNodeData, class TEdgeData>
01385 void TNodeEdgeNet<TNodeData, TEdgeData>::SetNDat(const int& NId, const TNodeData& NodeDat) {
01386   IAssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist.", NId).CStr());
01387   NodeH.GetDat(NId).NodeDat = NodeDat;
01388 }
01389 
01390 template <class TNodeData, class TEdgeData>
01391 int TNodeEdgeNet<TNodeData, TEdgeData>::GetUniqEdges(const bool& IsDir) const {
01392   TIntPrSet UniqESet(GetEdges());
01393   for (TEdgeI EI = BegEI(); EI < EndEI(); EI++) {
01394     const int Src = EI.GetSrcNId();
01395     const int Dst = EI.GetDstNId();
01396     if (IsDir) { UniqESet.AddKey(TIntPr(Src, Dst)); }
01397     else { UniqESet.AddKey(TIntPr(TMath::Mn(Src, Dst), TMath::Mx(Src, Dst))); }
01398   }
01399   return UniqESet.Len();
01400 }
01401 
01402 template <class TNodeData, class TEdgeData>
01403 int TNodeEdgeNet<TNodeData, TEdgeData>::AddEdge(const int& SrcNId, const int& DstNId, int EId) {
01404   if (EId == -1) { EId = MxEId;  MxEId++; }
01405   else { MxEId = TMath::Mx(EId+1, MxEId()); }
01406   IAssertR(!IsEdge(EId), TStr::Fmt("EdgeId %d already exists", EId));
01407   IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
01408   EdgeH.AddDat(EId, TEdge(EId, SrcNId, DstNId));
01409   GetNode(SrcNId).OutEIdV.AddSorted(EId);
01410   GetNode(DstNId).InEIdV.AddSorted(EId);
01411   return EId;
01412 }
01413 
01414 template <class TNodeData, class TEdgeData>
01415 int TNodeEdgeNet<TNodeData, TEdgeData>::AddEdge(const int& SrcNId, const int& DstNId, int EId, const TEdgeData& EdgeDat) {
01416   if (EId == -1) { EId = MxEId;  MxEId++; }
01417   else { MxEId = TMath::Mx(EId+1, MxEId()); }
01418   IAssertR(!IsEdge(EId), TStr::Fmt("EdgeId %d already exists", EId));
01419   IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
01420   EdgeH.AddDat(EId, TEdge(EId, SrcNId, DstNId, EdgeDat));
01421   GetNode(SrcNId).OutEIdV.AddSorted(EId);
01422   GetNode(DstNId).InEIdV.AddSorted(EId);
01423   return EId;
01424 }
01425 
01426 template <class TNodeData, class TEdgeData>
01427 void TNodeEdgeNet<TNodeData, TEdgeData>::DelEdge(const int& EId) {
01428   IAssert(IsEdge(EId));
01429   const int SrcNId = GetEdge(EId).GetSrcNId();
01430   const int DstNId = GetEdge(EId).GetDstNId();
01431   GetNode(SrcNId).OutEIdV.DelIfIn(EId);
01432   GetNode(DstNId).InEIdV.DelIfIn(EId);
01433   EdgeH.DelKey(EId);
01434 }
01435 
01436 template <class TNodeData, class TEdgeData>
01437 void TNodeEdgeNet<TNodeData, TEdgeData>::DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) {
01438   int EId;
01439   IAssert(IsEdge(SrcNId, DstNId, EId, IsDir));
01440   GetNode(SrcNId).OutEIdV.DelIfIn(EId);
01441   GetNode(DstNId).InEIdV.DelIfIn(EId);
01442   EdgeH.DelKey(EId);
01443 }
01444 
01445 template <class TNodeData, class TEdgeData>
01446 bool TNodeEdgeNet<TNodeData, TEdgeData>::IsEdge(const int& SrcNId, const int& DstNId, int& EId, const bool& IsDir) const {
01447   if (! IsNode(SrcNId)) { return false; }
01448   if (! IsNode(DstNId)) { return false; }
01449   const TNode& SrcNode = GetNode(SrcNId);
01450   for (int edge = 0; edge < SrcNode.GetOutDeg(); edge++) {
01451     const TEdge& Edge = GetEdge(SrcNode.GetOutEId(edge));
01452     if (DstNId == Edge.GetDstNId()) {
01453       EId = Edge.GetId();  return true; }
01454   }
01455   if (! IsDir) {
01456     for (int edge = 0; edge < SrcNode.GetInDeg(); edge++) {
01457     const TEdge& Edge = GetEdge(SrcNode.GetInEId(edge));
01458     if (DstNId == Edge.GetSrcNId()) {
01459       EId = Edge.GetId();  return true; }
01460     }
01461   }
01462   return false;
01463 }
01464 
01465 template <class TNodeData, class TEdgeData>
01466 void TNodeEdgeNet<TNodeData, TEdgeData>::SetEDat(const int& EId, const TEdgeData& EdgeDat) {
01467   IAssertR(IsEdge(EId), TStr::Fmt("EdgeId %d does not exist.", EId).CStr());
01468   GetEI(EId).GetDat() = EdgeDat;
01469 }
01470 
01471 template <class TNodeData, class TEdgeData>
01472 void TNodeEdgeNet<TNodeData, TEdgeData>::SetAllEDat(const TEdgeData& EdgeDat) {
01473   for (TEdgeI EI = BegEI(); EI < EndEI(); EI++) {
01474     EI() = EdgeDat;
01475   }
01476 }
01477 
01478 
01479 template <class TNodeData, class TEdgeData>
01480 void TNodeEdgeNet<TNodeData, TEdgeData>::GetNIdV(TIntV& NIdV) const {
01481   NIdV.Gen(GetNodes(), 0);
01482   for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N);) {
01483     NIdV.Add(NodeH.GetKey(N));
01484   }
01485 }
01486 
01487 template <class TNodeData, class TEdgeData>
01488 void TNodeEdgeNet<TNodeData, TEdgeData>::GetEIdV(TIntV& EIdV) const {
01489   EIdV.Gen(GetEdges(), 0);
01490   for (int E=EdgeH.FFirstKeyId(); EdgeH.FNextKeyId(E);) {
01491     EIdV.Add(EdgeH.GetKey(E));
01492   }
01493 }
01494 
01495 template <class TNodeData, class TEdgeData>
01496 void TNodeEdgeNet<TNodeData, TEdgeData>::Defrag(const bool& OnlyNodeLinks) {
01497   for (int kid = NodeH.FFirstKeyId(); NodeH.FNextKeyId(kid);) {
01498     TNode& Node = NodeH[kid];
01499     Node.InEIdV.Pack();  Node.OutEIdV.Pack();
01500   }
01501   if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) { NodeH.Defrag(); }
01502   if (! OnlyNodeLinks && ! EdgeH.IsKeyIdEqKeyN()) { EdgeH.Defrag(); }
01503 }
01504 
01505 template <class TNodeData, class TEdgeData>
01506 bool TNodeEdgeNet<TNodeData, TEdgeData>::IsOk(const bool& ThrowExcept) const {
01507   bool RetVal = true;
01508   for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
01509     const TNode& Node = NodeH[N];
01510     if (! Node.OutEIdV.IsSorted()) {
01511       const TStr Msg = TStr::Fmt("Out-edge list of node %d is not sorted.", Node.GetId());
01512       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01513     }
01514     if (! Node.InEIdV.IsSorted()) {
01515       const TStr Msg = TStr::Fmt("In-edge list of node %d is not sorted.", Node.GetId());
01516       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01517     }
01518     // check out-edge ids
01519     int prevEId = -1;
01520     for (int e = 0; e < Node.GetOutDeg(); e++) {
01521       if (! IsEdge(Node.GetOutEId(e))) {
01522         const TStr Msg = TStr::Fmt("Out-edge id %d of node %d does not exist.",  Node.GetOutEId(e), Node.GetId());
01523         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01524       }
01525       if (e > 0 && prevEId == Node.GetOutEId(e)) {
01526         const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge id %d.", Node.GetId(), Node.GetOutEId(e));
01527         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01528       }
01529       prevEId = Node.GetOutEId(e);
01530     }
01531     // check in-edge ids
01532     prevEId = -1;
01533     for (int e = 0; e < Node.GetInDeg(); e++) {
01534       if (! IsEdge(Node.GetInEId(e))) {
01535         const TStr Msg = TStr::Fmt("Out-edge id %d of node %d does not exist.",  Node.GetInEId(e), Node.GetId());
01536         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01537       }
01538       if (e > 0 && prevEId == Node.GetInEId(e)) {
01539         const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge id %d.", Node.GetId(), Node.GetInEId(e));
01540         if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01541       }
01542       prevEId = Node.GetInEId(e);
01543     }
01544   }
01545   for (int E = EdgeH.FFirstKeyId(); EdgeH.FNextKeyId(E); ) {
01546     const TEdge& Edge = EdgeH[E];
01547     if (! IsNode(Edge.GetSrcNId())) {
01548       const TStr Msg = TStr::Fmt("Edge %d source node %d does not exist.", Edge.GetId(), Edge.GetSrcNId());
01549       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01550     }
01551     if (! IsNode(Edge.GetDstNId())) {
01552       const TStr Msg = TStr::Fmt("Edge %d destination node %d does not exist.", Edge.GetId(), Edge.GetDstNId());
01553       if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
01554     }
01555   }
01556   return RetVal;
01557 }
01558 
01560 // Common Node-Edge Network Types
01561 typedef TNodeEdgeNet<TInt, TInt> TIntNENet;
01562 typedef TPt<TIntNENet> PIntNENet;
01563 typedef TNodeEdgeNet<TFlt, TFlt> TFltNENet;
01564 typedef TPt<TFltNENet> PFltNENet;