SNAP Library 2.0, User Reference
2013-05-13 16:33:57
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
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; // not supported 00225 TEdgeI GetEI(const int& SrcNId, const int& DstNId) const; 00226 00228 int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); } 00230 TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); } 00232 void GetNIdV(TIntV& NIdV) const; 00233 00235 bool Empty() const { return GetNodes()==0; } 00237 void Clr(const bool& DoDel=true, const bool& ResetDat=true) { 00238 MxNId = 0; NodeH.Clr(DoDel, -1, ResetDat); } 00240 void Reserve(const int& Nodes, const int& Edges) { if (Nodes>0) { NodeH.Gen(Nodes/2); } } 00242 void SortNIdById(const bool& Asc=true) { NodeH.SortByKey(Asc); } 00244 void SortNIdByDat(const bool& Asc=true) { NodeH.SortByDat(Asc); } 00246 00251 void Defrag(const bool& OnlyNodeLinks=false); 00253 00256 bool IsOk(const bool& ThrowExcept=true) const; 00257 00258 friend class TPt<TNodeNet<TNodeData> >; 00259 }; 00260 00261 // set flags 00262 namespace TSnap { 00263 template <class TNodeData> struct IsDirected<TNodeNet<TNodeData> > { enum { Val = 1 }; }; 00264 template <class TNodeData> struct IsNodeDat<TNodeNet<TNodeData> > { enum { Val = 1 }; }; 00265 } 00266 00267 template <class TNodeData> 00268 bool TNodeNet<TNodeData>::HasFlag(const TGraphFlag& Flag) const { 00269 return HasGraphFlag(typename TNet, Flag); 00270 } 00271 00272 template <class TNodeData> 00273 int TNodeNet<TNodeData>::AddNode(int NId) { 00274 if (NId == -1) { 00275 NId = MxNId; MxNId++; 00276 } else { 00277 IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId)); 00278 MxNId = TMath::Mx(NId+1, MxNId()); 00279 } 00280 NodeH.AddDat(NId, TNode(NId)); 00281 return NId; 00282 } 00283 00284 template <class TNodeData> 00285 int TNodeNet<TNodeData>::AddNode(int NId, const TNodeData& NodeDat) { 00286 if (NId == -1) { 00287 NId = MxNId; MxNId++; 00288 } else { 00289 IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId)); 00290 MxNId = TMath::Mx(NId+1, MxNId()); 00291 } 00292 NodeH.AddDat(NId, TNode(NId, NodeDat)); 00293 return NId; 00294 } 00295 00296 template <class TNodeData> 00297 void TNodeNet<TNodeData>::DelNode(const int& NId) { 00298 { TNode& Node = GetNode(NId); 00299 for (int e = 0; e < Node.GetOutDeg(); e++) { 00300 const int nbr = Node.GetOutNId(e); 00301 if (nbr == NId) { continue; } 00302 TNode& N = GetNode(nbr); 00303 int n = N.InNIdV.SearchBin(NId); 00304 if (n!= -1) { N.InNIdV.Del(n); } 00305 } 00306 for (int e = 0; e < Node.GetInDeg(); e++) { 00307 const int nbr = Node.GetInNId(e); 00308 if (nbr == NId) { continue; } 00309 TNode& N = GetNode(nbr); 00310 int n = N.OutNIdV.SearchBin(NId); 00311 if (n!= -1) { N.OutNIdV.Del(n); } 00312 } } 00313 NodeH.DelKey(NId); 00314 } 00315 00316 template <class TNodeData> 00317 void TNodeNet<TNodeData>::SetNDat(const int& NId, const TNodeData& NodeDat) { 00318 IAssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist.", NId).CStr()); 00319 NodeH.GetDat(NId).NodeDat = NodeDat; 00320 } 00321 00322 template <class TNodeData> 00323 int TNodeNet<TNodeData>::GetEdges() const { 00324 int edges=0; 00325 for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N);) { 00326 edges+=NodeH[N].GetOutDeg(); } 00327 return edges; 00328 } 00329 00330 template <class TNodeData> 00331 int TNodeNet<TNodeData>::AddEdge(const int& SrcNId, const int& DstNId) { 00332 IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr()); 00333 if (IsEdge(SrcNId, DstNId)) { return -2; } 00334 GetNode(SrcNId).OutNIdV.AddSorted(DstNId); 00335 GetNode(DstNId).InNIdV.AddSorted(SrcNId); 00336 return -1; // edge id 00337 } 00338 00339 template <class TNodeData> 00340 void TNodeNet<TNodeData>::DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) { 00341 IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr()); 00342 GetNode(SrcNId).OutNIdV.DelIfIn(DstNId); 00343 GetNode(DstNId).InNIdV.DelIfIn(SrcNId); 00344 if (! IsDir) { 00345 GetNode(DstNId).OutNIdV.DelIfIn(SrcNId); 00346 GetNode(SrcNId).InNIdV.DelIfIn(DstNId); 00347 } 00348 } 00349 00350 template <class TNodeData> 00351 bool TNodeNet<TNodeData>::IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) const { 00352 if (! IsNode(SrcNId) || ! IsNode(DstNId)) { return false; } 00353 if (IsDir) { return GetNode(SrcNId).IsOutNId(DstNId); } 00354 else { return GetNode(SrcNId).IsOutNId(DstNId) || GetNode(DstNId).IsOutNId(SrcNId); } 00355 } 00356 00357 template <class TNodeData> 00358 void TNodeNet<TNodeData>::GetNIdV(TIntV& NIdV) const { 00359 NIdV.Reserve(GetNodes(), 0); 00360 for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) { 00361 NIdV.Add(NodeH.GetKey(N)); } 00362 } 00363 00364 template <class TNodeData> 00365 typename TNodeNet<TNodeData>::TEdgeI TNodeNet<TNodeData>::GetEI(const int& SrcNId, const int& DstNId) const { 00366 const TNodeI SrcNI = GetNI(SrcNId); 00367 const int NodeN = SrcNI.NodeHI.GetDat().OutNIdV.SearchBin(DstNId); 00368 if (NodeN == -1) { return EndEI(); } 00369 return TEdgeI(SrcNI, EndNI(), NodeN); 00370 } 00371 00372 template <class TNodeData> 00373 void TNodeNet<TNodeData>::Defrag(const bool& OnlyNodeLinks) { 00374 for (int n = NodeH.FFirstKeyId(); NodeH.FNextKeyId(n); ) { 00375 TNode& Node = NodeH[n]; 00376 Node.InNIdV.Pack(); Node.OutNIdV.Pack(); 00377 } 00378 if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) { 00379 NodeH.Defrag(); } 00380 } 00381 00382 template <class TNodeData> 00383 bool TNodeNet<TNodeData>::IsOk(const bool& ThrowExcept) const { 00384 bool RetVal = true; 00385 for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) { 00386 const TNode& Node = NodeH[N]; 00387 if (! Node.OutNIdV.IsSorted()) { 00388 const TStr Msg = TStr::Fmt("Out-neighbor list of node %d is not sorted.", Node.GetId()); 00389 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 00390 } 00391 if (! Node.InNIdV.IsSorted()) { 00392 const TStr Msg = TStr::Fmt("In-neighbor list of node %d is not sorted.", Node.GetId()); 00393 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 00394 } 00395 // check out-edges 00396 int prevNId = -1; 00397 for (int e = 0; e < Node.GetOutDeg(); e++) { 00398 if (! IsNode(Node.GetOutNId(e))) { 00399 const TStr Msg = TStr::Fmt("Out-edge %d --> %d: node %d does not exist.", 00400 Node.GetId(), Node.GetOutNId(e), Node.GetOutNId(e)); 00401 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 00402 } 00403 if (e > 0 && prevNId == Node.GetOutNId(e)) { 00404 const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge %d --> %d.", 00405 Node.GetId(), Node.GetId(), Node.GetOutNId(e)); 00406 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 00407 } 00408 prevNId = Node.GetOutNId(e); 00409 } 00410 // check in-edges 00411 prevNId = -1; 00412 for (int e = 0; e < Node.GetInDeg(); e++) { 00413 if (! IsNode(Node.GetInNId(e))) { 00414 const TStr Msg = TStr::Fmt("In-edge %d <-- %d: node %d does not exist.", 00415 Node.GetId(), Node.GetInNId(e), Node.GetInNId(e)); 00416 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 00417 } 00418 if (e > 0 && prevNId == Node.GetInNId(e)) { 00419 const TStr Msg = TStr::Fmt("Node %d has duplidate in-edge %d <-- %d.", 00420 Node.GetId(), Node.GetId(), Node.GetInNId(e)); 00421 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 00422 } 00423 prevNId = Node.GetInNId(e); 00424 } 00425 } 00426 return RetVal; 00427 } 00428 00430 // Common network types 00431 typedef TNodeNet<TInt> TIntNNet; 00432 typedef TPt<TIntNNet> PIntNNet; 00433 typedef TNodeNet<TFlt> TFltNNet; 00434 typedef TPt<TFltNNet> PFltNNet; 00435 typedef TNodeNet<TStr> TStrNNet; 00436 typedef TPt<TStrNNet> PStrNNet; 00437 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); } 01250 // TODO document TNodeEdgeNet::GetEI() 01251 TEdgeI GetEI(const int& EId) const { return TEdgeI(EdgeH.GetI(EId), this); } 01252 // TODO document TNodeEdgeNet::GetEI() 01253 TEdgeI GetEI(const int& SrcNId, const int& DstNId) const { return GetEI(GetEId(SrcNId, DstNId)); } 01255 void SetEDat(const int& EId, const TEdgeData& EdgeDat); 01257 TEdgeData& GetEDat(const int& EId) { return EdgeH.GetDat(EId).EdgeDat; } 01259 const TEdgeData& GetEDat(const int& EId) const { return EdgeH.GetDat(EId).EdgeDat; } 01261 void SetAllEDat(const TEdgeData& EdgeDat); 01262 01264 int GetRndNId(TRnd& Rnd=TInt::Rnd) { return NodeH.GetKey(NodeH.GetRndKeyId(Rnd, 0.8)); } 01266 TNodeI GetRndNI(TRnd& Rnd=TInt::Rnd) { return GetNI(GetRndNId(Rnd)); } 01268 int GetRndEId(TRnd& Rnd=TInt::Rnd) { return EdgeH.GetKey(EdgeH.GetRndKeyId(Rnd, 0.8)); } 01270 TEdgeI GetRndEI(TRnd& Rnd=TInt::Rnd) { return GetEI(GetRndEId(Rnd)); } 01272 void GetNIdV(TIntV& NIdV) const; 01274 void GetEIdV(TIntV& EIdV) const; 01275 01277 bool Empty() const { return GetNodes()==0; } 01279 void Clr() { MxNId=0; MxEId=0; NodeH.Clr(); EdgeH.Clr(); } 01281 void Reserve(const int& Nodes, const int& Edges) { 01282 if (Nodes>0) { NodeH.Gen(Nodes/2); } if (Edges>0) { EdgeH.Gen(Edges/2); } } 01284 void SortNIdById(const bool& Asc=true) { NodeH.SortByKey(Asc); } 01286 void SortNIdByDat(const bool& Asc=true) { NodeH.SortByDat(Asc); } 01288 void SortEIdById(const bool& Asc=true) { EdgeH.SortByKey(Asc); } 01290 void SortEIdByDat(const bool& Asc=true) { EdgeH.SortByDat(Asc); } 01292 01297 void Defrag(const bool& OnlyNodeLinks=false); 01299 01302 bool IsOk(const bool& ThrowExcept=true) const; 01303 01304 friend class TPt<TNodeEdgeNet<TNodeData, TEdgeData> >; 01305 }; 01306 01307 // set flags 01308 namespace TSnap { 01309 template <class TNodeData, class TEdgeData> struct IsMultiGraph<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; }; 01310 template <class TNodeData, class TEdgeData> struct IsDirected<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; }; 01311 template <class TNodeData, class TEdgeData> struct IsNodeDat<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; }; 01312 template <class TNodeData, class TEdgeData> struct IsEdgeDat<TNodeEdgeNet<TNodeData, TEdgeData> > { enum { Val = 1 }; }; 01313 } 01314 01315 template <class TNodeData, class TEdgeData> 01316 bool TNodeEdgeNet<TNodeData, TEdgeData>::HasFlag(const TGraphFlag& Flag) const { 01317 return HasGraphFlag(typename TNet, Flag); 01318 } 01319 01320 template <class TNodeData, class TEdgeData> 01321 bool TNodeEdgeNet<TNodeData, TEdgeData>::TNodeI::IsInNId(const int& NId) const { 01322 const TNode& Node = NodeHI.GetDat(); 01323 for (int edge = 0; edge < Node.GetInDeg(); edge++) { 01324 if (NId == Net->GetEdge(Node.GetInEId(edge)).GetSrcNId()) 01325 return true; 01326 } 01327 return false; 01328 } 01329 01330 template <class TNodeData, class TEdgeData> 01331 bool TNodeEdgeNet<TNodeData, TEdgeData>::TNodeI::IsOutNId(const int& NId) const { 01332 const TNode& Node = NodeHI.GetDat(); 01333 for (int edge = 0; edge < Node.GetOutDeg(); edge++) { 01334 if (NId == Net->GetEdge(Node.GetOutEId(edge)).GetDstNId()) 01335 return true; 01336 } 01337 return false; 01338 } 01339 01340 template <class TNodeData, class TEdgeData> 01341 int TNodeEdgeNet<TNodeData, TEdgeData>::AddNode(int NId) { 01342 if (NId == -1) { 01343 NId = MxNId; MxNId++; 01344 } else { 01345 IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId)); 01346 MxNId = TMath::Mx(NId+1, MxNId()); 01347 } 01348 NodeH.AddDat(NId, TNode(NId)); 01349 return NId; 01350 } 01351 01352 template <class TNodeData, class TEdgeData> 01353 int TNodeEdgeNet<TNodeData, TEdgeData>::AddNode(int NId, const TNodeData& NodeDat) { 01354 if (NId == -1) { 01355 NId = MxNId; MxNId++; 01356 } else { 01357 IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId)); 01358 MxNId = TMath::Mx(NId+1, MxNId()); 01359 } 01360 NodeH.AddDat(NId, TNode(NId, NodeDat)); 01361 return NId; 01362 } 01363 01364 template <class TNodeData, class TEdgeData> 01365 void TNodeEdgeNet<TNodeData, TEdgeData>::DelNode(const int& NId) { 01366 const TNode& Node = GetNode(NId); 01367 for (int out = 0; out < Node.GetOutDeg(); out++) { 01368 const int EId = Node.GetOutEId(out); 01369 const TEdge& Edge = GetEdge(EId); 01370 IAssert(Edge.GetSrcNId() == NId); 01371 GetNode(Edge.GetDstNId()).InEIdV.DelIfIn(EId); 01372 EdgeH.DelKey(EId); 01373 } 01374 for (int in = 0; in < Node.GetInDeg(); in++) { 01375 const int EId = Node.GetInEId(in); 01376 const TEdge& Edge = GetEdge(EId); 01377 IAssert(Edge.GetDstNId() == NId); 01378 GetNode(Edge.GetSrcNId()).OutEIdV.DelIfIn(EId); 01379 EdgeH.DelKey(EId); 01380 } 01381 NodeH.DelKey(NId); 01382 } 01383 01384 template <class TNodeData, class TEdgeData> 01385 void TNodeEdgeNet<TNodeData, TEdgeData>::SetNDat(const int& NId, const TNodeData& NodeDat) { 01386 IAssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist.", NId).CStr()); 01387 NodeH.GetDat(NId).NodeDat = NodeDat; 01388 } 01389 01390 template <class TNodeData, class TEdgeData> 01391 int TNodeEdgeNet<TNodeData, TEdgeData>::GetUniqEdges(const bool& IsDir) const { 01392 TIntPrSet UniqESet(GetEdges()); 01393 for (TEdgeI EI = BegEI(); EI < EndEI(); EI++) { 01394 const int Src = EI.GetSrcNId(); 01395 const int Dst = EI.GetDstNId(); 01396 if (IsDir) { UniqESet.AddKey(TIntPr(Src, Dst)); } 01397 else { UniqESet.AddKey(TIntPr(TMath::Mn(Src, Dst), TMath::Mx(Src, Dst))); } 01398 } 01399 return UniqESet.Len(); 01400 } 01401 01402 template <class TNodeData, class TEdgeData> 01403 int TNodeEdgeNet<TNodeData, TEdgeData>::AddEdge(const int& SrcNId, const int& DstNId, int EId) { 01404 if (EId == -1) { EId = MxEId; MxEId++; } 01405 else { MxEId = TMath::Mx(EId+1, MxEId()); } 01406 IAssertR(!IsEdge(EId), TStr::Fmt("EdgeId %d already exists", EId)); 01407 IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr()); 01408 EdgeH.AddDat(EId, TEdge(EId, SrcNId, DstNId)); 01409 GetNode(SrcNId).OutEIdV.AddSorted(EId); 01410 GetNode(DstNId).InEIdV.AddSorted(EId); 01411 return EId; 01412 } 01413 01414 template <class TNodeData, class TEdgeData> 01415 int TNodeEdgeNet<TNodeData, TEdgeData>::AddEdge(const int& SrcNId, const int& DstNId, int EId, const TEdgeData& EdgeDat) { 01416 if (EId == -1) { EId = MxEId; MxEId++; } 01417 else { MxEId = TMath::Mx(EId+1, MxEId()); } 01418 IAssertR(!IsEdge(EId), TStr::Fmt("EdgeId %d already exists", EId)); 01419 IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr()); 01420 EdgeH.AddDat(EId, TEdge(EId, SrcNId, DstNId, EdgeDat)); 01421 GetNode(SrcNId).OutEIdV.AddSorted(EId); 01422 GetNode(DstNId).InEIdV.AddSorted(EId); 01423 return EId; 01424 } 01425 01426 template <class TNodeData, class TEdgeData> 01427 void TNodeEdgeNet<TNodeData, TEdgeData>::DelEdge(const int& EId) { 01428 IAssert(IsEdge(EId)); 01429 const int SrcNId = GetEdge(EId).GetSrcNId(); 01430 const int DstNId = GetEdge(EId).GetDstNId(); 01431 GetNode(SrcNId).OutEIdV.DelIfIn(EId); 01432 GetNode(DstNId).InEIdV.DelIfIn(EId); 01433 EdgeH.DelKey(EId); 01434 } 01435 01436 template <class TNodeData, class TEdgeData> 01437 void TNodeEdgeNet<TNodeData, TEdgeData>::DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) { 01438 int EId; 01439 IAssert(IsEdge(SrcNId, DstNId, EId, IsDir)); 01440 GetNode(SrcNId).OutEIdV.DelIfIn(EId); 01441 GetNode(DstNId).InEIdV.DelIfIn(EId); 01442 EdgeH.DelKey(EId); 01443 } 01444 01445 template <class TNodeData, class TEdgeData> 01446 bool TNodeEdgeNet<TNodeData, TEdgeData>::IsEdge(const int& SrcNId, const int& DstNId, int& EId, const bool& IsDir) const { 01447 if (! IsNode(SrcNId)) { return false; } 01448 if (! IsNode(DstNId)) { return false; } 01449 const TNode& SrcNode = GetNode(SrcNId); 01450 for (int edge = 0; edge < SrcNode.GetOutDeg(); edge++) { 01451 const TEdge& Edge = GetEdge(SrcNode.GetOutEId(edge)); 01452 if (DstNId == Edge.GetDstNId()) { 01453 EId = Edge.GetId(); return true; } 01454 } 01455 if (! IsDir) { 01456 for (int edge = 0; edge < SrcNode.GetInDeg(); edge++) { 01457 const TEdge& Edge = GetEdge(SrcNode.GetInEId(edge)); 01458 if (DstNId == Edge.GetSrcNId()) { 01459 EId = Edge.GetId(); return true; } 01460 } 01461 } 01462 return false; 01463 } 01464 01465 template <class TNodeData, class TEdgeData> 01466 void TNodeEdgeNet<TNodeData, TEdgeData>::SetEDat(const int& EId, const TEdgeData& EdgeDat) { 01467 IAssertR(IsEdge(EId), TStr::Fmt("EdgeId %d does not exist.", EId).CStr()); 01468 GetEI(EId).GetDat() = EdgeDat; 01469 } 01470 01471 template <class TNodeData, class TEdgeData> 01472 void TNodeEdgeNet<TNodeData, TEdgeData>::SetAllEDat(const TEdgeData& EdgeDat) { 01473 for (TEdgeI EI = BegEI(); EI < EndEI(); EI++) { 01474 EI() = EdgeDat; 01475 } 01476 } 01477 01478 01479 template <class TNodeData, class TEdgeData> 01480 void TNodeEdgeNet<TNodeData, TEdgeData>::GetNIdV(TIntV& NIdV) const { 01481 NIdV.Gen(GetNodes(), 0); 01482 for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N);) { 01483 NIdV.Add(NodeH.GetKey(N)); 01484 } 01485 } 01486 01487 template <class TNodeData, class TEdgeData> 01488 void TNodeEdgeNet<TNodeData, TEdgeData>::GetEIdV(TIntV& EIdV) const { 01489 EIdV.Gen(GetEdges(), 0); 01490 for (int E=EdgeH.FFirstKeyId(); EdgeH.FNextKeyId(E);) { 01491 EIdV.Add(EdgeH.GetKey(E)); 01492 } 01493 } 01494 01495 template <class TNodeData, class TEdgeData> 01496 void TNodeEdgeNet<TNodeData, TEdgeData>::Defrag(const bool& OnlyNodeLinks) { 01497 for (int kid = NodeH.FFirstKeyId(); NodeH.FNextKeyId(kid);) { 01498 TNode& Node = NodeH[kid]; 01499 Node.InEIdV.Pack(); Node.OutEIdV.Pack(); 01500 } 01501 if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) { NodeH.Defrag(); } 01502 if (! OnlyNodeLinks && ! EdgeH.IsKeyIdEqKeyN()) { EdgeH.Defrag(); } 01503 } 01504 01505 template <class TNodeData, class TEdgeData> 01506 bool TNodeEdgeNet<TNodeData, TEdgeData>::IsOk(const bool& ThrowExcept) const { 01507 bool RetVal = true; 01508 for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) { 01509 const TNode& Node = NodeH[N]; 01510 if (! Node.OutEIdV.IsSorted()) { 01511 const TStr Msg = TStr::Fmt("Out-edge list of node %d is not sorted.", Node.GetId()); 01512 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01513 } 01514 if (! Node.InEIdV.IsSorted()) { 01515 const TStr Msg = TStr::Fmt("In-edge list of node %d is not sorted.", Node.GetId()); 01516 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01517 } 01518 // check out-edge ids 01519 int prevEId = -1; 01520 for (int e = 0; e < Node.GetOutDeg(); e++) { 01521 if (! IsEdge(Node.GetOutEId(e))) { 01522 const TStr Msg = TStr::Fmt("Out-edge id %d of node %d does not exist.", Node.GetOutEId(e), Node.GetId()); 01523 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01524 } 01525 if (e > 0 && prevEId == Node.GetOutEId(e)) { 01526 const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge id %d.", Node.GetId(), Node.GetOutEId(e)); 01527 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01528 } 01529 prevEId = Node.GetOutEId(e); 01530 } 01531 // check in-edge ids 01532 prevEId = -1; 01533 for (int e = 0; e < Node.GetInDeg(); e++) { 01534 if (! IsEdge(Node.GetInEId(e))) { 01535 const TStr Msg = TStr::Fmt("Out-edge id %d of node %d does not exist.", Node.GetInEId(e), Node.GetId()); 01536 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01537 } 01538 if (e > 0 && prevEId == Node.GetInEId(e)) { 01539 const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge id %d.", Node.GetId(), Node.GetInEId(e)); 01540 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01541 } 01542 prevEId = Node.GetInEId(e); 01543 } 01544 } 01545 for (int E = EdgeH.FFirstKeyId(); EdgeH.FNextKeyId(E); ) { 01546 const TEdge& Edge = EdgeH[E]; 01547 if (! IsNode(Edge.GetSrcNId())) { 01548 const TStr Msg = TStr::Fmt("Edge %d source node %d does not exist.", Edge.GetId(), Edge.GetSrcNId()); 01549 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01550 } 01551 if (! IsNode(Edge.GetDstNId())) { 01552 const TStr Msg = TStr::Fmt("Edge %d destination node %d does not exist.", Edge.GetId(), Edge.GetDstNId()); 01553 if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; 01554 } 01555 } 01556 return RetVal; 01557 } 01558 01560 // Common Node-Edge Network Types 01561 typedef TNodeEdgeNet<TInt, TInt> TIntNENet; 01562 typedef TPt<TIntNENet> PIntNENet; 01563 typedef TNodeEdgeNet<TFlt, TFlt> TFltNENet; 01564 typedef TPt<TFltNENet> PFltNENet;