SNAP Library 2.2, Developer Reference  2014-03-11 19:15:55
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
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 
00011 //#//////////////////////////////////////////////
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;
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 
00438 //#//////////////////////////////////////////////
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 
00975 //#//////////////////////////////////////////////
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); }
01251   TEdgeI GetEI(const int& EId) const { return TEdgeI(EdgeH.GetI(EId), this); }
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;
01565 
01566 class TNEANet;
01568 typedef TPt<TNEANet> PNEANet;
01569 
01570 //#//////////////////////////////////////////////
01572 
01587 class TNEANet {
01588 public:
01589   typedef TNEANet TNet;
01590   typedef TPt<TNEANet> PNet;
01591 public:
01592   class TNode {
01593   private:
01594     TInt Id;
01595     TIntV InEIdV, OutEIdV;
01596   public:
01597     TNode() : Id(-1), InEIdV(), OutEIdV() { }
01598     TNode(const int& NId) : Id(NId), InEIdV(), OutEIdV() { }
01599     TNode(const TNode& Node) : Id(Node.Id), InEIdV(Node.InEIdV), OutEIdV(Node.OutEIdV) { }
01600     TNode(TSIn& SIn) : Id(SIn), InEIdV(SIn), OutEIdV(SIn) { }
01601     void Save(TSOut& SOut) const { Id.Save(SOut); InEIdV.Save(SOut); OutEIdV.Save(SOut); }
01602     int GetId() const { return Id; }
01603     int GetDeg() const { return GetInDeg() + GetOutDeg(); }
01604     int GetInDeg() const { return InEIdV.Len(); }
01605     int GetOutDeg() const { return OutEIdV.Len(); }
01606     int GetInEId(const int& EdgeN) const { return InEIdV[EdgeN]; }
01607     int GetOutEId(const int& EdgeN) const { return OutEIdV[EdgeN]; }
01608     int GetNbrEId(const int& EdgeN) const { return EdgeN<GetOutDeg()?GetOutEId(EdgeN):GetInEId(EdgeN-GetOutDeg()); }
01609     bool IsInEId(const int& EId) const { return InEIdV.SearchBin(EId) != -1; }
01610     bool IsOutEId(const int& EId) const { return OutEIdV.SearchBin(EId) != -1; }
01611     friend class TNEANet;
01612   };
01613   class TEdge {
01614   private:
01615     TInt Id, SrcNId, DstNId;
01616   public:
01617     TEdge() : Id(-1), SrcNId(-1), DstNId(-1) { }
01618     TEdge(const int& EId, const int& SourceNId, const int& DestNId) : Id(EId), SrcNId(SourceNId), DstNId(DestNId) { }
01619     TEdge(const TEdge& Edge) : Id(Edge.Id), SrcNId(Edge.SrcNId), DstNId(Edge.DstNId) { }
01620     TEdge(TSIn& SIn) : Id(SIn), SrcNId(SIn), DstNId(SIn) { }
01621     void Save(TSOut& SOut) const { Id.Save(SOut); SrcNId.Save(SOut); DstNId.Save(SOut); }
01622     int GetId() const { return Id; }
01623     int GetSrcNId() const { return SrcNId; }
01624     int GetDstNId() const { return DstNId; }
01625     friend class TNEANet;
01626   };
01628   class TNodeI {
01629   private:
01630     typedef THash<TInt, TNode>::TIter THashIter;
01631     THashIter NodeHI;
01632     const TNEANet *Graph;
01633   public:
01634     TNodeI() : NodeHI(), Graph(NULL) { }
01635     TNodeI(const THashIter& NodeHIter, const TNEANet* GraphPt) : NodeHI(NodeHIter), Graph(GraphPt) { }
01636     TNodeI(const TNodeI& NodeI) : NodeHI(NodeI.NodeHI), Graph(NodeI.Graph) { }
01637     TNodeI& operator = (const TNodeI& NodeI) { NodeHI = NodeI.NodeHI; Graph=NodeI.Graph; return *this; }
01639     TNodeI& operator++ (int) { NodeHI++; return *this; }
01640     bool operator < (const TNodeI& NodeI) const { return NodeHI < NodeI.NodeHI; }
01641     bool operator == (const TNodeI& NodeI) const { return NodeHI == NodeI.NodeHI; }
01643     int GetId() const { return NodeHI.GetDat().GetId(); }
01645     int GetDeg() const { return NodeHI.GetDat().GetDeg(); }
01647     int GetInDeg() const { return NodeHI.GetDat().GetInDeg(); }
01649     int GetOutDeg() const { return NodeHI.GetDat().GetOutDeg(); }
01651 
01653     int GetInNId(const int& EdgeN) const { return Graph->GetEdge(NodeHI.GetDat().GetInEId(EdgeN)).GetSrcNId(); }
01655 
01657     int GetOutNId(const int& EdgeN) const { return Graph->GetEdge(NodeHI.GetDat().GetOutEId(EdgeN)).GetDstNId(); }
01659 
01661     int GetNbrNId(const int& EdgeN) const { const TEdge& E = Graph->GetEdge(NodeHI.GetDat().GetNbrEId(EdgeN)); return GetId()==E.GetSrcNId() ? E.GetDstNId():E.GetSrcNId(); }
01663     bool IsInNId(const int& NId) const;
01665     bool IsOutNId(const int& NId) const;
01667     bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); }
01669     int GetInEId(const int& EdgeN) const { return NodeHI.GetDat().GetInEId(EdgeN); }
01671     int GetOutEId(const int& EdgeN) const { return NodeHI.GetDat().GetOutEId(EdgeN); }
01673     int GetNbrEId(const int& EdgeN) const { return NodeHI.GetDat().GetNbrEId(EdgeN); }
01675     bool IsInEId(const int& EId) const { return NodeHI.GetDat().IsInEId(EId); }
01677     bool IsOutEId(const int& EId) const { return NodeHI.GetDat().IsOutEId(EId); }
01679     bool IsNbrEId(const int& EId) const { return IsInEId(EId) || IsOutEId(EId); }
01681     void GetAttrNames(TStrV& Names) const { Graph->AttrNameNI(GetId(), Names); }
01683     void GetAttrVal(TStrV& Val) const { Graph->AttrValueNI(GetId(), Val); }
01685     void GetIntAttrNames(TStrV& Names) const { Graph->IntAttrNameNI(GetId(), Names); }
01687     void GetIntAttrVal(TIntV& Val) const { Graph->IntAttrValueNI(GetId(), Val); }
01689     void GetStrAttrNames(TStrV& Names) const { Graph->StrAttrNameNI(GetId(), Names); }
01691     void GetStrAttrVal(TStrV& Val) const { Graph->StrAttrValueNI(GetId(), Val); }
01693     void GetFltAttrNames(TStrV& Names) const { Graph->FltAttrNameNI(GetId(), Names); }
01695     void GetFltAttrVal(TFltV& Val) const { Graph->FltAttrValueNI(GetId(), Val); }
01696     friend class TNEANet;
01697   };
01699   class TEdgeI {
01700   private:
01701     typedef THash<TInt, TEdge>::TIter THashIter;
01702     THashIter EdgeHI;
01703     const TNEANet *Graph;
01704   public:
01705     TEdgeI() : EdgeHI(), Graph(NULL) { }
01706     TEdgeI(const THashIter& EdgeHIter, const TNEANet *GraphPt) : EdgeHI(EdgeHIter), Graph(GraphPt) { }
01707     TEdgeI(const TEdgeI& EdgeI) : EdgeHI(EdgeI.EdgeHI), Graph(EdgeI.Graph) { }
01708     TEdgeI& operator = (const TEdgeI& EdgeI) { if (this!=&EdgeI) { EdgeHI=EdgeI.EdgeHI; Graph=EdgeI.Graph; }  return *this; }
01710     TEdgeI& operator++ (int) { EdgeHI++; return *this; }
01711     bool operator < (const TEdgeI& EdgeI) const { return EdgeHI < EdgeI.EdgeHI; }
01712     bool operator == (const TEdgeI& EdgeI) const { return EdgeHI == EdgeI.EdgeHI; }
01714     int GetId() const { return EdgeHI.GetDat().GetId(); }
01716     int GetSrcNId() const { return EdgeHI.GetDat().GetSrcNId(); }
01718     int GetDstNId() const { return EdgeHI.GetDat().GetDstNId(); }
01720     void GetAttrNames(TStrV& Names) const { Graph->AttrNameEI(GetId(), Names); }
01722     void GetAttrVal(TStrV& Val) const { Graph->AttrValueEI(GetId(), Val); }
01724     void GetIntAttrNames(TStrV& Names) const { Graph->IntAttrNameEI(GetId(), Names); }
01726     void GetIntAttrVal(TIntV& Val) const { Graph->IntAttrValueEI(GetId(), Val); }
01728     void GetStrAttrNames(TStrV& Names) const { Graph->StrAttrNameEI(GetId(), Names); }
01730     void GetStrAttrVal(TStrV& Val) const { Graph->StrAttrValueEI(GetId(), Val); }
01732     void GetFltAttrNames(TStrV& Names) const { Graph->FltAttrNameEI(GetId(), Names); }
01734     void GetFltAttrVal(TFltV& Val) const { Graph->FltAttrValueEI(GetId(), Val); }
01735     friend class TNEANet;
01736   };
01737 
01739   class TAIntI {
01740   private:
01741     typedef TIntV::TIter TIntVecIter;
01742     TIntVecIter HI;
01743     bool isNode;
01744     TStr attr;
01745     const TNEANet *Graph;
01746   public:
01747     TAIntI() : HI(), attr(), Graph(NULL) { }
01748     TAIntI(const TIntVecIter& HIter, TStr attribute, bool isEdgeIter, const TNEANet* GraphPt) : HI(HIter), attr(), Graph(GraphPt) { isNode = !isEdgeIter; attr = attribute; }
01749     TAIntI(const TAIntI& I) : HI(I.HI), attr(I.attr), Graph(I.Graph) { isNode = I.isNode; }
01750     TAIntI& operator = (const TAIntI& I) { HI = I.HI; Graph=I.Graph; isNode = I.isNode; attr = I.attr; return *this; }
01751     bool operator < (const TAIntI& I) const { return HI < I.HI; }
01752     bool operator == (const TAIntI& I) const { return HI == I.HI; }
01754     TInt GetDat() const { return HI[0]; }
01756     bool IsDeleted() const { return isNode ? GetDat() == Graph->GetIntAttrDefaultN(attr) : GetDat() == Graph->GetIntAttrDefaultE(attr); };
01757     TAIntI& operator++(int) { HI++; return *this; }
01758     friend class TNEANet;
01759   };
01760 
01762   class TAStrI {
01763   private:
01764     typedef TStrV::TIter TStrVecIter;
01765     TStrVecIter HI;
01766     bool isNode;
01767     TStr attr;
01768     const TNEANet *Graph;
01769   public:
01770     TAStrI() : HI(), attr(), Graph(NULL) { }
01771     TAStrI(const TStrVecIter& HIter, TStr attribute, bool isEdgeIter, const TNEANet* GraphPt) : HI(HIter), attr(), Graph(GraphPt) { isNode = !isEdgeIter; attr = attribute; }
01772     TAStrI(const TAStrI& I) : HI(I.HI), attr(I.attr), Graph(I.Graph) { isNode = I.isNode; }
01773     TAStrI& operator = (const TAStrI& I) { HI = I.HI; Graph=I.Graph; isNode = I.isNode; attr = I.attr; return *this; }
01774     bool operator < (const TAStrI& I) const { return HI < I.HI; }
01775     bool operator == (const TAStrI& I) const { return HI == I.HI; }
01777     TStr GetDat() const { return HI[0]; }
01779     bool IsDeleted() const { return isNode ? GetDat() == Graph->GetStrAttrDefaultN(attr) : GetDat() == Graph->GetStrAttrDefaultE(attr); };
01780     TAStrI& operator++(int) { HI++; return *this; }
01781     friend class TNEANet;
01782   };
01783 
01785   class TAFltI {
01786   private:
01787     typedef TFltV::TIter TFltVecIter;
01788     TFltVecIter HI;
01789     bool isNode;
01790     TStr attr;
01791     const TNEANet *Graph;
01792   public:
01793     TAFltI() : HI(), attr(), Graph(NULL) { }
01794     TAFltI(const TFltVecIter& HIter, TStr attribute, bool isEdgeIter, const TNEANet* GraphPt) : HI(HIter), attr(), Graph(GraphPt) { isNode = !isEdgeIter; attr = attribute; }
01795     TAFltI(const TAFltI& I) : HI(I.HI), attr(I.attr), Graph(I.Graph) { isNode = I.isNode; }
01796     TAFltI& operator = (const TAFltI& I) { HI = I.HI; Graph=I.Graph; isNode = I.isNode; attr = I.attr; return *this; }
01797     bool operator < (const TAFltI& I) const { return HI < I.HI; }
01798     bool operator == (const TAFltI& I) const { return HI == I.HI; }
01800     TFlt GetDat() const { return HI[0]; }
01802     bool IsDeleted() const { return isNode ? GetDat() == Graph->GetFltAttrDefaultN(attr) : GetDat() == Graph->GetFltAttrDefaultE(attr); };
01803     TAFltI& operator++(int) { HI++; return *this; }
01804     friend class TNEANet;
01805   };
01806 
01807 private:
01808   TNode& GetNode(const int& NId) { return NodeH.GetDat(NId); }
01809   const TNode& GetNode(const int& NId) const { return NodeH.GetDat(NId); }
01810   TEdge& GetEdge(const int& EId) { return EdgeH.GetDat(EId); }
01811   const TEdge& GetEdge(const int& EId) const { return EdgeH.GetDat(EId); }
01812 
01814   TInt GetIntAttrDefaultN(const TStr& attribute) const { return IntDefaultsN.IsKey(attribute) ? IntDefaultsN.GetDat(attribute) : (TInt) TInt::Mn; }
01816   TStr GetStrAttrDefaultN(const TStr& attribute) const { return StrDefaultsN.IsKey(attribute) ? StrDefaultsN.GetDat(attribute) : (TStr) TStr::GetNullStr(); }
01818   TFlt GetFltAttrDefaultN(const TStr& attribute) const { return FltDefaultsN.IsKey(attribute) ? FltDefaultsN.GetDat(attribute) : (TFlt) TFlt::Mn; }
01820   TInt GetIntAttrDefaultE(const TStr& attribute) const { return IntDefaultsE.IsKey(attribute) ? IntDefaultsE.GetDat(attribute) : (TInt) TInt::Mn; }
01822   TStr GetStrAttrDefaultE(const TStr& attribute) const { return StrDefaultsE.IsKey(attribute) ? StrDefaultsE.GetDat(attribute) : (TStr) TStr::GetNullStr(); }
01824   TFlt GetFltAttrDefaultE(const TStr& attribute) const { return FltDefaultsE.IsKey(attribute) ? FltDefaultsE.GetDat(attribute) : (TFlt) TFlt::Mn; }
01825 
01826 private:
01827   TCRef CRef;
01828   TInt MxNId, MxEId;
01829   THash<TInt, TNode> NodeH;
01830   THash<TInt, TEdge> EdgeH;
01832   TStrIntPrH KeyToIndexTypeN, KeyToIndexTypeE;
01833 
01834   THash<TStr, TInt> IntDefaultsN, IntDefaultsE;
01835   THash<TStr, TStr> StrDefaultsN, StrDefaultsE;
01836   THash<TStr, TFlt> FltDefaultsN, FltDefaultsE;
01837   TVec<TIntV> VecOfIntVecsN, VecOfIntVecsE;
01838   TVec<TStrV> VecOfStrVecsN, VecOfStrVecsE;
01839   TVec<TFltV> VecOfFltVecsN, VecOfFltVecsE;
01840   enum { IntType, StrType, FltType };
01841 public:
01842   TNEANet() : CRef(), MxNId(0), MxEId(0), NodeH(), EdgeH(),
01843     KeyToIndexTypeN(), KeyToIndexTypeE(), IntDefaultsN(), IntDefaultsE(),
01844     StrDefaultsN(), StrDefaultsE(), FltDefaultsN(), FltDefaultsE(),
01845     VecOfIntVecsN(), VecOfIntVecsE(), VecOfStrVecsN(), VecOfStrVecsE(),
01846     VecOfFltVecsN(), VecOfFltVecsE() { }
01848   explicit TNEANet(const int& Nodes, const int& Edges) : CRef(),
01849     MxNId(0), MxEId(0), NodeH(), EdgeH(), KeyToIndexTypeN(), KeyToIndexTypeE(),
01850     IntDefaultsN(), IntDefaultsE(), StrDefaultsN(), StrDefaultsE(),
01851     FltDefaultsN(), FltDefaultsE(), VecOfIntVecsN(), VecOfIntVecsE(),
01852     VecOfStrVecsN(), VecOfStrVecsE(), VecOfFltVecsN(), VecOfFltVecsE()
01853     { Reserve(Nodes, Edges); }
01854   TNEANet(const TNEANet& Graph) : MxNId(Graph.MxNId), MxEId(Graph.MxEId),
01855     NodeH(Graph.NodeH), EdgeH(Graph.EdgeH), KeyToIndexTypeN(), KeyToIndexTypeE(),
01856     IntDefaultsN(), IntDefaultsE(), StrDefaultsN(), StrDefaultsE(),
01857     FltDefaultsN(), FltDefaultsE(), VecOfIntVecsN(), VecOfIntVecsE(),
01858     VecOfStrVecsN(), VecOfStrVecsE(), VecOfFltVecsN(), VecOfFltVecsE() { }
01860   TNEANet(TSIn& SIn) : MxNId(SIn), MxEId(SIn), NodeH(SIn), EdgeH(SIn),
01861     KeyToIndexTypeN(SIn), KeyToIndexTypeE(SIn), IntDefaultsN(SIn), IntDefaultsE(SIn),
01862     StrDefaultsN(SIn), StrDefaultsE(SIn), FltDefaultsN(SIn), FltDefaultsE(SIn), 
01863     VecOfIntVecsN(SIn), VecOfIntVecsE(SIn), VecOfStrVecsN(SIn),VecOfStrVecsE(SIn),
01864     VecOfFltVecsN(SIn), VecOfFltVecsE(SIn) { }
01866   void Save(TSOut& SOut) const {
01867     MxNId.Save(SOut); MxEId.Save(SOut); NodeH.Save(SOut); EdgeH.Save(SOut);
01868     KeyToIndexTypeN.Save(SOut); KeyToIndexTypeE.Save(SOut);
01869     IntDefaultsN.Save(SOut); IntDefaultsE.Save(SOut);
01870     StrDefaultsN.Save(SOut); StrDefaultsE.Save(SOut);
01871     FltDefaultsN.Save(SOut); FltDefaultsE.Save(SOut);
01872     VecOfIntVecsN.Save(SOut); VecOfIntVecsE.Save(SOut);
01873     VecOfStrVecsN.Save(SOut); VecOfStrVecsE.Save(SOut);
01874     VecOfFltVecsN.Save(SOut); VecOfFltVecsE.Save(SOut); }
01876   static PNEANet New() { return PNEANet(new TNEANet()); }
01878 
01880   static PNEANet New(const int& Nodes, const int& Edges) { return PNEANet(new TNEANet(Nodes, Edges)); }
01882   static PNEANet Load(TSIn& SIn) { return PNEANet(new TNEANet(SIn)); }
01884   bool HasFlag(const TGraphFlag& Flag) const;
01885   TNEANet& operator = (const TNEANet& Graph) { if (this!=&Graph) {
01886     MxNId=Graph.MxNId; MxEId=Graph.MxEId; NodeH=Graph.NodeH; EdgeH=Graph.EdgeH; }
01887     return *this; }
01888 
01890   int GetNodes() const { return NodeH.Len(); }
01892 
01896   int AddNode(int NId = -1);
01898   int AddNode(const TNodeI& NodeId) { return AddNode(NodeId.GetId()); }
01900 
01902   void DelNode(const int& NId);
01904   void DelNode(const TNode& NodeI) { DelNode(NodeI.GetId()); }
01906   bool IsNode(const int& NId) const { return NodeH.IsKey(NId); }
01908   TNodeI BegNI() const { return TNodeI(NodeH.BegI(), this); }
01910   TNodeI EndNI() const { return TNodeI(NodeH.EndI(), this); }
01912   TNodeI GetNI(const int& NId) const { return TNodeI(NodeH.GetI(NId), this); }
01914   TAIntI BegNAIntI(const TStr& attr) const {
01915     return TAIntI(VecOfIntVecsN[KeyToIndexTypeN.GetDat(attr).Val2].BegI(), attr, false, this); }
01917   TAIntI EndNAIntI(const TStr& attr) const {
01918     return TAIntI(VecOfIntVecsN[KeyToIndexTypeN.GetDat(attr).Val2].EndI(), attr, false, this); }
01920   TAIntI GetNAIntI(const TStr& attr, const int& NId) const {
01921     return TAIntI(VecOfIntVecsN[KeyToIndexTypeN.GetDat(attr).Val2].GetI(NodeH.GetKeyId(NId)), attr, false, this); }
01923   TAStrI BegNAStrI(const TStr& attr) const {
01924 
01925     return TAStrI(VecOfStrVecsN[KeyToIndexTypeN.GetDat(attr).Val2].BegI(), attr, false, this); }
01927   TAStrI EndNAStrI(const TStr& attr) const {
01928     return TAStrI(VecOfStrVecsN[KeyToIndexTypeN.GetDat(attr).Val2].EndI(), attr, false, this); }
01930   TAStrI GetNAStrI(const TStr& attr, const int& NId) const {
01931     return TAStrI(VecOfStrVecsN[KeyToIndexTypeN.GetDat(attr).Val2].GetI(NodeH.GetKeyId(NId)), attr, false, this); }
01933   TAFltI BegNAFltI(const TStr& attr) const {
01934     return TAFltI(VecOfFltVecsN[KeyToIndexTypeN.GetDat(attr).Val2].BegI(), attr, false, this); }
01936   TAFltI EndNAFltI(const TStr& attr) const {
01937     return TAFltI(VecOfFltVecsN[KeyToIndexTypeN.GetDat(attr).Val2].EndI(), attr, false, this); }
01939   TAFltI GetNAFltI(const TStr& attr, const int& NId) const {
01940     return TAFltI(VecOfFltVecsN[KeyToIndexTypeN.GetDat(attr).Val2].GetI(NodeH.GetKeyId(NId)), attr, false, this); }
01941 
01943   void AttrNameNI(const TInt& NId, TStrV& Names) const {
01944     AttrNameNI(NId, KeyToIndexTypeN.BegI(), Names);}
01945   void AttrNameNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TStrV& Names) const;
01947   void AttrValueNI(const TInt& NId, TStrV& Values) const {
01948     AttrValueNI(NId, KeyToIndexTypeN.BegI(), Values);}
01949   void AttrValueNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TStrV& Values) const; 
01951   void IntAttrNameNI(const TInt& NId, TStrV& Names) const {
01952     IntAttrNameNI(NId, KeyToIndexTypeN.BegI(), Names);}
01953   void IntAttrNameNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TStrV& Names) const;
01955   void IntAttrValueNI(const TInt& NId, TIntV& Values) const {
01956     IntAttrValueNI(NId, KeyToIndexTypeN.BegI(), Values);}
01957   void IntAttrValueNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TIntV& Values) const; 
01959   void StrAttrNameNI(const TInt& NId, TStrV& Names) const {
01960     StrAttrNameNI(NId, KeyToIndexTypeN.BegI(), Names);}
01961   void StrAttrNameNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TStrV& Names) const;
01963   void StrAttrValueNI(const TInt& NId, TStrV& Values) const {
01964     StrAttrValueNI(NId, KeyToIndexTypeN.BegI(), Values);}
01965   void StrAttrValueNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TStrV& Values) const; 
01967   void FltAttrNameNI(const TInt& NId, TStrV& Names) const {
01968     FltAttrNameNI(NId, KeyToIndexTypeN.BegI(), Names);}
01969   void FltAttrNameNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TStrV& Names) const;
01971   void FltAttrValueNI(const TInt& NId, TFltV& Values) const {
01972     FltAttrValueNI(NId, KeyToIndexTypeN.BegI(), Values);}
01973   void FltAttrValueNI(const TInt& NId, TStrIntPrH::TIter NodeHI, TFltV& Values) const; 
01974 
01976   void AttrNameEI(const TInt& EId, TStrV& Names) const {
01977     AttrNameEI(EId, KeyToIndexTypeE.BegI(), Names);}
01978   void AttrNameEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TStrV& Names) const;
01980   void AttrValueEI(const TInt& EId, TStrV& Values) const {
01981     AttrValueEI(EId, KeyToIndexTypeE.BegI(), Values);}
01982   void AttrValueEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TStrV& Values) const;
01984   void IntAttrNameEI(const TInt& EId, TStrV& Names) const {
01985     IntAttrNameEI(EId, KeyToIndexTypeE.BegI(), Names);}
01986   void IntAttrNameEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TStrV& Names) const;
01988   void IntAttrValueEI(const TInt& EId, TIntV& Values) const {
01989     IntAttrValueEI(EId, KeyToIndexTypeE.BegI(), Values);}
01990   void IntAttrValueEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TIntV& Values) const; 
01992   void StrAttrNameEI(const TInt& EId, TStrV& Names) const {
01993     StrAttrNameEI(EId, KeyToIndexTypeE.BegI(), Names);}
01994   void StrAttrNameEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TStrV& Names) const;
01996   void StrAttrValueEI(const TInt& EId, TStrV& Values) const {
01997     StrAttrValueEI(EId, KeyToIndexTypeE.BegI(), Values);}
01998   void StrAttrValueEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TStrV& Values) const; 
02000   void FltAttrNameEI(const TInt& EId, TStrV& Names) const {
02001     FltAttrNameEI(EId, KeyToIndexTypeE.BegI(), Names);}
02002   void FltAttrNameEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TStrV& Names) const;
02004   void FltAttrValueEI(const TInt& EId, TFltV& Values) const {
02005     FltAttrValueEI(EId, KeyToIndexTypeE.BegI(), Values);}
02006   void FltAttrValueEI(const TInt& EId, TStrIntPrH::TIter EdgeHI, TFltV& Values) const; 
02007 
02009   TAIntI BegEAIntI(const TStr& attr) const {
02010     return TAIntI(VecOfIntVecsE[KeyToIndexTypeE.GetDat(attr).Val2].BegI(), attr, true, this);
02011   }
02013   TAIntI EndEAIntI(const TStr& attr) const {
02014     return TAIntI(VecOfIntVecsE[KeyToIndexTypeE.GetDat(attr).Val2].EndI(), attr, true, this);
02015   }
02017   TAIntI GetEAIntI(const TStr& attr, const int& EId) const {
02018     return TAIntI(VecOfIntVecsE[KeyToIndexTypeE.GetDat(attr).Val2].GetI(EdgeH.GetKeyId(EId)), attr, true, this);
02019   }
02021   TAStrI BegEAStrI(const TStr& attr) const {
02022     return TAStrI(VecOfStrVecsE[KeyToIndexTypeE.GetDat(attr).Val2].BegI(), attr, true, this);   }
02024   TAStrI EndEAStrI(const TStr& attr) const {
02025     return TAStrI(VecOfStrVecsE[KeyToIndexTypeE.GetDat(attr).Val2].EndI(), attr, true, this);
02026   }
02028   TAStrI GetEAStrI(const TStr& attr, const int& EId) const {
02029     return TAStrI(VecOfStrVecsE[KeyToIndexTypeE.GetDat(attr).Val2].GetI(EdgeH.GetKeyId(EId)), attr, true, this);
02030   }
02032   TAFltI BegEAFltI(const TStr& attr) const {
02033     return TAFltI(VecOfFltVecsE[KeyToIndexTypeE.GetDat(attr).Val2].BegI(), attr, true, this);
02034   }
02036   TAFltI EndEAFltI(const TStr& attr) const {
02037     return TAFltI(VecOfFltVecsE[KeyToIndexTypeE.GetDat(attr).Val2].EndI(), attr, true, this);
02038   }
02040   TAFltI GetEAFltI(const TStr& attr, const int& EId) const {
02041     return TAFltI(VecOfFltVecsE[KeyToIndexTypeE.GetDat(attr).Val2].GetI(EdgeH.GetKeyId(EId)), attr, true, this);
02042   }
02044   int GetMxNId() const { return MxNId; }
02045 
02047   int GetEdges() const { return EdgeH.Len(); }
02049 
02054   int AddEdge(const int& SrcNId, const int& DstNId, int EId  = -1);
02056   int AddEdge(const TEdgeI& EdgeI) { return AddEdge(EdgeI.GetSrcNId(), EdgeI.GetDstNId(), EdgeI.GetId()); }
02058   void DelEdge(const int& EId);
02060 
02064   void DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true);
02066   bool IsEdge(const int& EId) const { return EdgeH.IsKey(EId); }
02068   bool IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir = true) const { int EId; return IsEdge(SrcNId, DstNId, EId, IsDir); }
02070   bool IsEdge(const int& SrcNId, const int& DstNId, int& EId, const bool& IsDir = true) const;
02072   int GetEId(const int& SrcNId, const int& DstNId) const { int EId; return IsEdge(SrcNId, DstNId, EId)?EId:-1; }
02074   TEdgeI BegEI() const { return TEdgeI(EdgeH.BegI(), this); }
02076   TEdgeI EndEI() const { return TEdgeI(EdgeH.EndI(), this); }
02078   TEdgeI GetEI(const int& EId) const { return TEdgeI(EdgeH.GetI(EId), this); }
02080   TEdgeI GetEI(const int& SrcNId, const int& DstNId) const { return GetEI(GetEId(SrcNId, DstNId)); }
02081 
02083   int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); }
02085   TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); }
02087   int GetRndEId(TRnd& Rnd=TInt::Rnd) { return EdgeH.GetKey(EdgeH.GetRndKeyId(Rnd, 0.8)); }
02089   TEdgeI GetRndEI(TRnd& Rnd=TInt::Rnd) { return GetEI(GetRndEId(Rnd)); }
02091   void GetNIdV(TIntV& NIdV) const;
02093   void GetEIdV(TIntV& EIdV) const;
02094 
02096   bool Empty() const { return GetNodes()==0; }
02098   void Clr() { MxNId=0; MxEId=0; NodeH.Clr(); EdgeH.Clr(),
02099     KeyToIndexTypeN.Clr(), KeyToIndexTypeE.Clr(), IntDefaultsN.Clr(), IntDefaultsE.Clr(),
02100     StrDefaultsN.Clr(), StrDefaultsE.Clr(), FltDefaultsN.Clr(), FltDefaultsE.Clr(),
02101     VecOfIntVecsN.Clr(), VecOfIntVecsE.Clr(), VecOfStrVecsN.Clr(), VecOfStrVecsE.Clr(), 
02102     VecOfFltVecsN.Clr(), VecOfFltVecsE.Clr();}
02104   void Reserve(const int& Nodes, const int& Edges) {
02105     if (Nodes>0) { NodeH.Gen(Nodes/2); } if (Edges>0) { EdgeH.Gen(Edges/2); } }
02107 
02112   void Defrag(const bool& OnlyNodeLinks=false);
02114 
02117   bool IsOk(const bool& ThrowExcept=true) const;
02119   void Dump(FILE *OutF=stdout) const;
02120 
02122 
02124   int AddIntAttrDatN(const TNodeI& NodeId, const TInt& value, const TStr& attr) { return AddIntAttrDatN(NodeId.GetId(), value, attr); }
02125   int AddIntAttrDatN(const int& NId, const TInt& value, const TStr& attr);
02127 
02129   int AddStrAttrDatN(const TNodeI& NodeId, const TStr& value, const TStr& attr) { return AddStrAttrDatN(NodeId.GetId(), value, attr); }
02130   int AddStrAttrDatN(const int& NId, const TStr& value, const TStr& attr);
02132 
02134   int AddFltAttrDatN(const TNodeI& NodeId, const TFlt& value, const TStr& attr) { return AddFltAttrDatN(NodeId.GetId(), value, attr); }
02135   int AddFltAttrDatN(const int& NId, const TFlt& value, const TStr& attr);
02136 
02138 
02140   int AddIntAttrDatE(const TEdgeI& EdgeId, const TInt& value, const TStr& attr) { return AddIntAttrDatE(EdgeId.GetId(), value, attr); }
02141   int AddIntAttrDatE(const int& EId, const TInt& value, const TStr& attr);
02143 
02145   int AddStrAttrDatE(const TEdgeI& EdgeId, const TStr& value, const TStr& attr) { return AddStrAttrDatE(EdgeId.GetId(), value, attr); }
02146   int AddStrAttrDatE(const int& EId, const TStr& value, const TStr& attr);
02148 
02150   int AddFltAttrDatE(const TEdgeI& EdgeId, const TFlt& value, const TStr& attr) { return AddFltAttrDatE(EdgeId.GetId(), value, attr); }
02151   int AddFltAttrDatE(const int& EId, const TFlt& value, const TStr& attr);
02152 
02154   TInt GetIntAttrDatN(const TNodeI& NodeId, const TStr& attr) { return GetIntAttrDatN(NodeId.GetId(), attr); }
02155   TInt GetIntAttrDatN(const int& NId, const TStr& attr);
02157   TStr GetStrAttrDatN(const TNodeI& NodeId, const TStr& attr) { return GetStrAttrDatN(NodeId.GetId(), attr); }
02158   TStr GetStrAttrDatN(const int& NId, const TStr& attr);
02160   TFlt GetFltAttrDatN(const TNodeI& NodeId, const TStr& attr) { return GetFltAttrDatN(NodeId.GetId(), attr); }
02161   TFlt GetFltAttrDatN(const int& NId, const TStr& attr);
02162 
02164   TInt GetIntAttrDatE(const TEdgeI& EdgeId, const TStr& attr) { return GetIntAttrDatE(EdgeId.GetId(), attr); }
02165   TInt GetIntAttrDatE(const int& EId, const TStr& attr);
02167   TStr GetStrAttrDatE(const TEdgeI& EdgeId, const TStr& attr) { return GetStrAttrDatE(EdgeId.GetId(), attr); }
02168   TStr GetStrAttrDatE(const int& EId, const TStr& attr);
02170   TFlt GetFltAttrDatE(const TEdgeI& EdgeId, const TStr& attr) { return GetFltAttrDatE(EdgeId.GetId(), attr); }
02171   TFlt GetFltAttrDatE(const int& EId, const TStr& attr);
02172  
02174   int DelAttrDatN(const TNodeI& NodeId, const TStr& attr) { return DelAttrDatN(NodeId.GetId(), attr); } 
02175   int DelAttrDatN(const int& NId, const TStr& attr); 
02177   int DelAttrDatE(const TEdgeI& EdgeId, const TStr& attr) { return DelAttrDatE(EdgeId.GetId(), attr); } 
02178   int DelAttrDatE(const int& EId, const TStr& attr); 
02179 
02181   int AddIntAttrN(const TStr& attr, TInt defaultValue=TInt::Mn);
02183   int AddStrAttrN(const TStr& attr, TStr defaultValue=TStr::GetNullStr());
02185   int AddFltAttrN(const TStr& attr, TFlt defaultValue=TFlt::Mn);
02186 
02188   int AddIntAttrE(const TStr& attr, TInt defaultValue=TInt::Mn);
02190   int AddStrAttrE(const TStr& attr, TStr defaultValue=TStr::GetNullStr());
02192   int AddFltAttrE(const TStr& attr, TFlt defaultValue=TFlt::Mn);
02193 
02195   int DelAttrN(const TStr& attr);
02197   int DelAttrE(const TStr& attr);
02198 
02199   // Returns true if NId deleted for current node attr iterator.
02200   bool NodeAttrIsDeleted(const int& NId, const TStrIntPrH::TIter& NodeHI) const;
02201   // Returns true if NId deleted for current node int attr iterator.
02202   bool NodeAttrIsIntDeleted(const int& NId, const TStrIntPrH::TIter& NodeHI) const;
02203   // Returns true if NId deleted for current node str attr iterator.
02204   bool NodeAttrIsStrDeleted(const int& NId, const TStrIntPrH::TIter& NodeHI) const;
02205   // Returns true if NId deleted for current node flt attr iterator.
02206   bool NodeAttrIsFltDeleted(const int& NId, const TStrIntPrH::TIter& NodeHI) const;
02207 
02208   // Returns true if EId deleted for current edge attr iterator.
02209   bool EdgeAttrIsDeleted(const int& EId, const TStrIntPrH::TIter& EdgeHI) const;
02210   // Returns true if EId deleted for current edge int attr iterator.
02211   bool EdgeAttrIsIntDeleted(const int& EId, const TStrIntPrH::TIter& EdgeHI) const;
02212   // Returns true if EId deleted for current edge str attr iterator.
02213   bool EdgeAttrIsStrDeleted(const int& EId, const TStrIntPrH::TIter& EdgeHI) const;
02214   // Returns true if EId deleted for current edge flt attr iterator.
02215   bool EdgeAttrIsFltDeleted(const int& EId, const TStrIntPrH::TIter& EdgeHI) const;
02216 
02217   // Returns node attribute value, converted to Str type.
02218   TStr GetNodeAttrValue(const int& NId, const TStrIntPrH::TIter& NodeHI) const;
02219   // Returns edge attribute value, converted to Str type.
02220   TStr GetEdgeAttrValue(const int& EId, const TStrIntPrH::TIter& EdgeHI) const;
02221  
02223 
02227   static PNEANet GetSmallGraph();
02228   friend class TPt<TNEANet>;
02229 };
02230 
02231 // set flags
02232 namespace TSnap {
02233 template <> struct IsMultiGraph<TNEANet> { enum { Val = 1 }; };
02234 template <> struct IsDirected<TNEANet> { enum { Val = 1 }; };
02235 }