SNAP Library 2.4, User Reference  2015-05-11 19:40:56
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
graph.cpp
Go to the documentation of this file.
1 // Undirected Graph
3 bool TUNGraph::HasFlag(const TGraphFlag& Flag) const {
4  return HasGraphFlag(TUNGraph::TNet, Flag);
5 }
6 
7 // Add a node of ID NId to the graph.
8 int TUNGraph::AddNode(int NId) {
9  if (NId == -1) {
10  NId = MxNId; MxNId++;
11  } else {
12  IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
13  MxNId = TMath::Mx(NId+1, MxNId());
14  }
15  NodeH.AddDat(NId, TNode(NId));
16  return NId;
17 }
18 
19 // Add a node of ID NId to the graph and create edges to all nodes in vector NbrNIdV.
20 int TUNGraph::AddNode(const int& NId, const TIntV& NbrNIdV) {
21  int NewNId;
22  if (NId == -1) {
23  NewNId = MxNId; MxNId++;
24  } else {
25  IAssertR(! IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
26  NewNId = NId;
27  MxNId = TMath::Mx(NewNId+1, MxNId());
28  }
29  TNode& Node = NodeH.AddDat(NewNId);
30  Node.Id = NewNId;
31  Node.NIdV = NbrNIdV;
32  Node.NIdV.Sort();
33  NEdges += Node.GetDeg();
34  for (int i = 0; i < NbrNIdV.Len(); i++) {
35  GetNode(NbrNIdV[i]).NIdV.AddSorted(NewNId);
36  }
37  return NewNId;
38 }
39 
40 // Add a node of ID NId to the graph and create edges to all nodes in the vector NIdVId in the vector pool Pool).
41 int TUNGraph::AddNode(const int& NId, const TVecPool<TInt>& Pool, const int& NIdVId) {
42  int NewNId;
43  if (NId == -1) {
44  NewNId = MxNId; MxNId++;
45  } else {
46  IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
47  NewNId = NId;
48  MxNId = TMath::Mx(NewNId+1, MxNId());
49  }
50  TNode& Node = NodeH.AddDat(NewNId);
51  Node.Id = NewNId;
52  Node.NIdV.GenExt(Pool.GetValVPt(NIdVId), Pool.GetVLen(NIdVId));
53  Node.NIdV.Sort();
54  NEdges += Node.GetDeg();
55  return NewNId;
56 }
57 
58 // Delete node of ID NId from the graph.
59 void TUNGraph::DelNode(const int& NId) {
60  { AssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist", NId));
61  TNode& Node = GetNode(NId);
62  NEdges -= Node.GetDeg();
63  for (int e = 0; e < Node.GetDeg(); e++) {
64  const int nbr = Node.GetNbrNId(e);
65  if (nbr == NId) { continue; }
66  TNode& N = GetNode(nbr);
67  const int n = N.NIdV.SearchBin(NId);
68  IAssert(n != -1); // if NId points to N, then N also should point back
69  if (n!= -1) { N.NIdV.Del(n); }
70  } }
71  NodeH.DelKey(NId);
72 }
73 
74 int TUNGraph::GetEdges() const {
75  //int Edges = 0;
76  //for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
77  // Edges += NodeH[N].GetDeg();
78  //}
79  //return Edges/2;
80  return NEdges;
81 }
82 
83 // Add an edge between SrcNId and DstNId to the graph.
84 int TUNGraph::AddEdge(const int& SrcNId, const int& DstNId) {
85  IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
86  if (IsEdge(SrcNId, DstNId)) { return -2; } // edge already exists
87  GetNode(SrcNId).NIdV.AddSorted(DstNId);
88  if (SrcNId!=DstNId) { // not a self edge
89  GetNode(DstNId).NIdV.AddSorted(SrcNId); }
90  NEdges++;
91  return -1; // edge id
92 }
93 
94 // Delete an edge between node IDs SrcNId and DstNId from the graph.
95 void TUNGraph::DelEdge(const int& SrcNId, const int& DstNId) {
96  IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
97  { TNode& N = GetNode(SrcNId);
98  const int n = N.NIdV.SearchBin(DstNId);
99  if (n!= -1) { N.NIdV.Del(n); NEdges--; } }
100  if (SrcNId != DstNId) { // not a self edge
101  TNode& N = GetNode(DstNId);
102  const int n = N.NIdV.SearchBin(SrcNId);
103  if (n!= -1) { N.NIdV.Del(n); }
104  }
105 }
106 
107 // Test whether an edge between node IDs SrcNId and DstNId exists the graph.
108 bool TUNGraph::IsEdge(const int& SrcNId, const int& DstNId) const {
109  if (! IsNode(SrcNId) || ! IsNode(DstNId)) return false;
110  return GetNode(SrcNId).IsNbrNId(DstNId);
111 }
112 
113 // Return an iterator referring to edge (SrcNId, DstNId) in the graph.
114 TUNGraph::TEdgeI TUNGraph::GetEI(const int& SrcNId, const int& DstNId) const {
115  const int MnNId = TMath::Mn(SrcNId, DstNId);
116  const int MxNId = TMath::Mx(SrcNId, DstNId);
117  const TNodeI SrcNI = GetNI(MnNId);
118  const int NodeN = SrcNI.NodeHI.GetDat().NIdV.SearchBin(MxNId);
119  IAssert(NodeN != -1);
120  return TEdgeI(SrcNI, EndNI(), NodeN);
121 }
122 
123 
124 // Get a vector IDs of all nodes in the graph.
125 void TUNGraph::GetNIdV(TIntV& NIdV) const {
126  NIdV.Gen(GetNodes(), 0);
127  for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
128  NIdV.Add(NodeH.GetKey(N)); }
129 }
130 
131 // Defragment the graph.
132 void TUNGraph::Defrag(const bool& OnlyNodeLinks) {
133  for (int n = NodeH.FFirstKeyId(); NodeH.FNextKeyId(n); ) {
134  NodeH[n].NIdV.Pack();
135  }
136  if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) {
137  NodeH.Defrag();
138  }
139 }
140 
141 // Check the graph data structure for internal consistency.
142 bool TUNGraph::IsOk(const bool& ThrowExcept) const {
143  bool RetVal = true;
144  for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
145  const TNode& Node = NodeH[N];
146  if (! Node.NIdV.IsSorted()) {
147  const TStr Msg = TStr::Fmt("Neighbor list of node %d is not sorted.", Node.GetId());
148  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); }
149  RetVal=false;
150  }
151  int prevNId = -1;
152  for (int e = 0; e < Node.GetDeg(); e++) {
153  if (! IsNode(Node.GetNbrNId(e))) {
154  const TStr Msg = TStr::Fmt("Edge %d --> %d: node %d does not exist.",
155  Node.GetId(), Node.GetNbrNId(e), Node.GetNbrNId(e));
156  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); }
157  RetVal=false;
158  }
159  if (e > 0 && prevNId == Node.GetNbrNId(e)) {
160  const TStr Msg = TStr::Fmt("Node %d has duplicate edge %d --> %d.",
161  Node.GetId(), Node.GetId(), Node.GetNbrNId(e));
162  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); }
163  RetVal=false;
164  }
165  prevNId = Node.GetNbrNId(e);
166  }
167  }
168  int EdgeCnt = 0;
169  for (TEdgeI EI = BegEI(); EI < EndEI(); EI++) { EdgeCnt++; }
170  if (EdgeCnt != GetEdges()) {
171  const TStr Msg = TStr::Fmt("Number of edges counter is corrupted: GetEdges():%d, EdgeCount:%d.", GetEdges(), EdgeCnt);
172  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); }
173  RetVal=false;
174  }
175  return RetVal;
176 }
177 
178 // Print the graph in a human readable form to an output stream OutF.
179 void TUNGraph::Dump(FILE *OutF) const {
180  const int NodePlaces = (int) ceil(log10((double) GetNodes()));
181  fprintf(OutF, "-------------------------------------------------\nUndirected Node Graph: nodes: %d, edges: %d\n", GetNodes(), GetEdges());
182  for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
183  const TNode& Node = NodeH[N];
184  fprintf(OutF, " %*d [%d] ", NodePlaces, Node.GetId(), Node.GetDeg());
185  for (int edge = 0; edge < Node.GetDeg(); edge++) {
186  fprintf(OutF, " %*d", NodePlaces, Node.GetNbrNId(edge)); }
187  fprintf(OutF, "\n");
188  }
189  fprintf(OutF, "\n");
190 }
191 
192 // Return a small graph on 5 nodes and 5 edges.
194  PUNGraph Graph = TUNGraph::New();
195  for (int i = 0; i < 5; i++) { Graph->AddNode(i); }
196  Graph->AddEdge(0,1); Graph->AddEdge(0,2);
197  Graph->AddEdge(0,3); Graph->AddEdge(0,4);
198  Graph->AddEdge(1,2);
199  return Graph;
200 }
201 
203 // Directed Node Graph
204 bool TNGraph::HasFlag(const TGraphFlag& Flag) const {
205  return HasGraphFlag(TNGraph::TNet, Flag);
206 }
207 
208 int TNGraph::AddNode(int NId) {
209  if (NId == -1) {
210  NId = MxNId; MxNId++;
211  } else {
212  IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
213  MxNId = TMath::Mx(NId+1, MxNId());
214  }
215  NodeH.AddDat(NId, TNode(NId));
216  return NId;
217 }
218 
219 // add a node with a list of neighbors
220 // (use TNGraph::IsOk to check whether the graph is consistent)
221 int TNGraph::AddNode(const int& NId, const TIntV& InNIdV, const TIntV& OutNIdV) {
222  int NewNId;
223  if (NId == -1) {
224  NewNId = MxNId; MxNId++;
225  } else {
226  IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
227  NewNId = NId;
228  MxNId = TMath::Mx(NewNId+1, MxNId());
229  }
230  TNode& Node = NodeH.AddDat(NewNId);
231  Node.Id = NewNId;
232  Node.InNIdV = InNIdV;
233  Node.OutNIdV = OutNIdV;
234  Node.InNIdV.Sort();
235  Node.OutNIdV.Sort();
236  return NewNId;
237 }
238 
239 // add a node from a vector pool
240 // (use TNGraph::IsOk to check whether the graph is consistent)
241 int TNGraph::AddNode(const int& NId, const TVecPool<TInt>& Pool, const int& SrcVId, const int& DstVId) {
242  int NewNId;
243  if (NId == -1) {
244  NewNId = MxNId; MxNId++;
245  } else {
246  IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
247  NewNId = NId;
248  MxNId = TMath::Mx(NewNId+1, MxNId());
249  }
250  TNode& Node = NodeH.AddDat(NewNId);
251  Node.Id = NewNId;
252  Node.InNIdV.GenExt(Pool.GetValVPt(SrcVId), Pool.GetVLen(SrcVId));
253  Node.OutNIdV.GenExt(Pool.GetValVPt(DstVId), Pool.GetVLen(DstVId));
254  Node.InNIdV.Sort();
255  Node.OutNIdV.Sort();
256  return NewNId;
257 }
258 
259 void TNGraph::DelNode(const int& NId) {
260  { TNode& Node = GetNode(NId);
261  for (int e = 0; e < Node.GetOutDeg(); e++) {
262  const int nbr = Node.GetOutNId(e);
263  if (nbr == NId) { continue; }
264  TNode& N = GetNode(nbr);
265  const int n = N.InNIdV.SearchBin(NId);
266  if (n!= -1) { N.InNIdV.Del(n); }
267  }
268  for (int e = 0; e < Node.GetInDeg(); e++) {
269  const int nbr = Node.GetInNId(e);
270  if (nbr == NId) { continue; }
271  TNode& N = GetNode(nbr);
272  const int n = N.OutNIdV.SearchBin(NId);
273  if (n!= -1) { N.OutNIdV.Del(n); }
274  } }
275  NodeH.DelKey(NId);
276 }
277 
278 int TNGraph::GetEdges() const {
279  int edges=0;
280  for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
281  edges+=NodeH[N].GetOutDeg();
282  }
283  return edges;
284 }
285 
286 int TNGraph::AddEdge(const int& SrcNId, const int& DstNId) {
287  IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
288  //IAssert(! IsEdge(SrcNId, DstNId));
289  if (IsEdge(SrcNId, DstNId)) { return -2; }
290  GetNode(SrcNId).OutNIdV.AddSorted(DstNId);
291  GetNode(DstNId).InNIdV.AddSorted(SrcNId);
292  return -1; // edge id
293 }
294 
295 void TNGraph::DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) {
296  IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
297  { TNode& N = GetNode(SrcNId);
298  const int n = N.OutNIdV.SearchBin(DstNId);
299  if (n!= -1) { N.OutNIdV.Del(n); } }
300  { TNode& N = GetNode(DstNId);
301  const int n = N.InNIdV.SearchBin(SrcNId);
302  if (n!= -1) { N.InNIdV.Del(n); } }
303  if (! IsDir) {
304  { TNode& N = GetNode(SrcNId);
305  const int n = N.InNIdV.SearchBin(DstNId);
306  if (n!= -1) { N.InNIdV.Del(n); } }
307  { TNode& N = GetNode(DstNId);
308  const int n = N.OutNIdV.SearchBin(SrcNId);
309  if (n!= -1) { N.OutNIdV.Del(n); } }
310  }
311 }
312 
313 bool TNGraph::IsEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) const {
314  if (! IsNode(SrcNId) || ! IsNode(DstNId)) { return false; }
315  if (IsDir) { return GetNode(SrcNId).IsOutNId(DstNId); }
316  else { return GetNode(SrcNId).IsOutNId(DstNId) || GetNode(DstNId).IsOutNId(SrcNId); }
317 }
318 
319 TNGraph::TEdgeI TNGraph::GetEI(const int& SrcNId, const int& DstNId) const {
320  const TNodeI SrcNI = GetNI(SrcNId);
321  const int NodeN = SrcNI.NodeHI.GetDat().OutNIdV.SearchBin(DstNId);
322  IAssert(NodeN != -1);
323  return TEdgeI(SrcNI, EndNI(), NodeN);
324 }
325 
326 void TNGraph::GetNIdV(TIntV& NIdV) const {
327  NIdV.Gen(GetNodes(), 0);
328  for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
329  NIdV.Add(NodeH.GetKey(N)); }
330 }
331 
332 void TNGraph::Defrag(const bool& OnlyNodeLinks) {
333  for (int n = NodeH.FFirstKeyId(); NodeH.FNextKeyId(n); ) {
334  TNode& Node = NodeH[n];
335  Node.InNIdV.Pack(); Node.OutNIdV.Pack();
336  }
337  if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) { NodeH.Defrag(); }
338 }
339 
340 // for each node check that their neighbors are also nodes
341 bool TNGraph::IsOk(const bool& ThrowExcept) const {
342  bool RetVal = true;
343  for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
344  const TNode& Node = NodeH[N];
345  if (! Node.OutNIdV.IsSorted()) {
346  const TStr Msg = TStr::Fmt("Out-neighbor list of node %d is not sorted.", Node.GetId());
347  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
348  }
349  if (! Node.InNIdV.IsSorted()) {
350  const TStr Msg = TStr::Fmt("In-neighbor list of node %d is not sorted.", Node.GetId());
351  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
352  }
353  // check out-edges
354  int prevNId = -1;
355  for (int e = 0; e < Node.GetOutDeg(); e++) {
356  if (! IsNode(Node.GetOutNId(e))) {
357  const TStr Msg = TStr::Fmt("Out-edge %d --> %d: node %d does not exist.",
358  Node.GetId(), Node.GetOutNId(e), Node.GetOutNId(e));
359  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
360  }
361  if (e > 0 && prevNId == Node.GetOutNId(e)) {
362  const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge %d --> %d.",
363  Node.GetId(), Node.GetId(), Node.GetOutNId(e));
364  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
365  }
366  prevNId = Node.GetOutNId(e);
367  }
368  // check in-edges
369  prevNId = -1;
370  for (int e = 0; e < Node.GetInDeg(); e++) {
371  if (! IsNode(Node.GetInNId(e))) {
372  const TStr Msg = TStr::Fmt("In-edge %d <-- %d: node %d does not exist.",
373  Node.GetId(), Node.GetInNId(e), Node.GetInNId(e));
374  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
375  }
376  if (e > 0 && prevNId == Node.GetInNId(e)) {
377  const TStr Msg = TStr::Fmt("Node %d has duplidate in-edge %d <-- %d.",
378  Node.GetId(), Node.GetId(), Node.GetInNId(e));
379  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
380  }
381  prevNId = Node.GetInNId(e);
382  }
383  }
384  return RetVal;
385 }
386 
387 void TNGraph::Dump(FILE *OutF) const {
388  const int NodePlaces = (int) ceil(log10((double) GetNodes()));
389  fprintf(OutF, "-------------------------------------------------\nDirected Node Graph: nodes: %d, edges: %d\n", GetNodes(), GetEdges());
390  for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
391  const TNode& Node = NodeH[N];
392  fprintf(OutF, " %*d]\n", NodePlaces, Node.GetId());
393  fprintf(OutF, " in [%d]", Node.GetInDeg());
394  for (int edge = 0; edge < Node.GetInDeg(); edge++) {
395  fprintf(OutF, " %*d", NodePlaces, Node.GetInNId(edge)); }
396  fprintf(OutF, "\n out[%d]", Node.GetOutDeg());
397  for (int edge = 0; edge < Node.GetOutDeg(); edge++) {
398  fprintf(OutF, " %*d", NodePlaces, Node.GetOutNId(edge)); }
399  fprintf(OutF, "\n");
400  }
401  fprintf(OutF, "\n");
402 }
403 
405  PNGraph G = TNGraph::New();
406  for (int i = 0; i < 5; i++) { G->AddNode(i); }
407  G->AddEdge(0,1); G->AddEdge(1,2); G->AddEdge(0,2);
408  G->AddEdge(1,3); G->AddEdge(3,4); G->AddEdge(2,3);
409  return G;
410 }
411 
413 // Node Edge Graph
414 bool TNEGraph::HasFlag(const TGraphFlag& Flag) const {
415  return HasGraphFlag(TNEGraph::TNet, Flag);
416 }
417 
418 bool TNEGraph::TNodeI::IsInNId(const int& NId) const {
419  const TNode& Node = NodeHI.GetDat();
420  for (int edge = 0; edge < Node.GetInDeg(); edge++) {
421  if (NId == Graph->GetEdge(Node.GetInEId(edge)).GetSrcNId())
422  return true;
423  }
424  return false;
425 }
426 
427 bool TNEGraph::TNodeI::IsOutNId(const int& NId) const {
428  const TNode& Node = NodeHI.GetDat();
429  for (int edge = 0; edge < Node.GetOutDeg(); edge++) {
430  if (NId == Graph->GetEdge(Node.GetOutEId(edge)).GetDstNId())
431  return true;
432  }
433  return false;
434 }
435 
436 int TNEGraph::AddNode(int NId) {
437  if (NId == -1) {
438  NId = MxNId; MxNId++;
439  } else {
440  IAssertR(!IsNode(NId), TStr::Fmt("NodeId %d already exists", NId));
441  MxNId = TMath::Mx(NId+1, MxNId());
442  }
443  NodeH.AddDat(NId, TNode(NId));
444  return NId;
445 }
446 
447 void TNEGraph::DelNode(const int& NId) {
448  const TNode& Node = GetNode(NId);
449  for (int out = 0; out < Node.GetOutDeg(); out++) {
450  const int EId = Node.GetOutEId(out);
451  const TEdge& Edge = GetEdge(EId);
452  IAssert(Edge.GetSrcNId() == NId);
453  GetNode(Edge.GetDstNId()).InEIdV.DelIfIn(EId);
454  EdgeH.DelKey(EId);
455  }
456  for (int in = 0; in < Node.GetInDeg(); in++) {
457  const int EId = Node.GetInEId(in);
458  const TEdge& Edge = GetEdge(EId);
459  IAssert(Edge.GetDstNId() == NId);
460  GetNode(Edge.GetSrcNId()).OutEIdV.DelIfIn(EId);
461  EdgeH.DelKey(EId);
462  }
463  NodeH.DelKey(NId);
464 }
465 
466 int TNEGraph::AddEdge(const int& SrcNId, const int& DstNId, int EId) {
467  if (EId == -1) { EId = MxEId; MxEId++; }
468  else { MxEId = TMath::Mx(EId+1, MxEId()); }
469  IAssertR(!IsEdge(EId), TStr::Fmt("EdgeId %d already exists", EId));
470  IAssertR(IsNode(SrcNId) && IsNode(DstNId), TStr::Fmt("%d or %d not a node.", SrcNId, DstNId).CStr());
471  EdgeH.AddDat(EId, TEdge(EId, SrcNId, DstNId));
472  GetNode(SrcNId).OutEIdV.AddSorted(EId);
473  GetNode(DstNId).InEIdV.AddSorted(EId);
474  return EId;
475 }
476 
477 void TNEGraph::DelEdge(const int& EId) {
478  IAssert(IsEdge(EId));
479  const int SrcNId = GetEdge(EId).GetSrcNId();
480  const int DstNId = GetEdge(EId).GetDstNId();
481  GetNode(SrcNId).OutEIdV.DelIfIn(EId);
482  GetNode(DstNId).InEIdV.DelIfIn(EId);
483  EdgeH.DelKey(EId);
484 }
485 
486 // delete all edges between the two nodes
487 void TNEGraph::DelEdge(const int& SrcNId, const int& DstNId, const bool& IsDir) {
488  int EId;
489  IAssert(IsEdge(SrcNId, DstNId, EId, IsDir)); // there is at least one edge
490  while (IsEdge(SrcNId, DstNId, EId, IsDir)) {
491  GetNode(SrcNId).OutEIdV.DelIfIn(EId);
492  GetNode(DstNId).InEIdV.DelIfIn(EId);
493  }
494  EdgeH.DelKey(EId);
495 }
496 
497 bool TNEGraph::IsEdge(const int& SrcNId, const int& DstNId, int& EId, const bool& IsDir) const {
498  const TNode& SrcNode = GetNode(SrcNId);
499  for (int edge = 0; edge < SrcNode.GetOutDeg(); edge++) {
500  const TEdge& Edge = GetEdge(SrcNode.GetOutEId(edge));
501  if (DstNId == Edge.GetDstNId()) {
502  EId = Edge.GetId(); return true; }
503  }
504  if (! IsDir) {
505  for (int edge = 0; edge < SrcNode.GetInDeg(); edge++) {
506  const TEdge& Edge = GetEdge(SrcNode.GetInEId(edge));
507  if (DstNId == Edge.GetSrcNId()) {
508  EId = Edge.GetId(); return true; }
509  }
510  }
511  return false;
512 }
513 
514 void TNEGraph::GetNIdV(TIntV& NIdV) const {
515  NIdV.Gen(GetNodes(), 0);
516  for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
517  NIdV.Add(NodeH.GetKey(N)); }
518 }
519 
520 void TNEGraph::GetEIdV(TIntV& EIdV) const {
521  EIdV.Gen(GetEdges(), 0);
522  for (int E=EdgeH.FFirstKeyId(); EdgeH.FNextKeyId(E); ) {
523  EIdV.Add(EdgeH.GetKey(E));
524  }
525 }
526 
527 void TNEGraph::Defrag(const bool& OnlyNodeLinks) {
528  for (int kid = NodeH.FFirstKeyId(); NodeH.FNextKeyId(kid); ) {
529  TNode& Node = NodeH[kid];
530  Node.InEIdV.Pack(); Node.OutEIdV.Pack();
531  }
532  if (! OnlyNodeLinks && ! NodeH.IsKeyIdEqKeyN()) { NodeH.Defrag(); }
533  if (! OnlyNodeLinks && ! EdgeH.IsKeyIdEqKeyN()) { EdgeH.Defrag(); }
534 }
535 
536 bool TNEGraph::IsOk(const bool& ThrowExcept) const {
537 bool RetVal = true;
538  for (int N = NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) {
539  const TNode& Node = NodeH[N];
540  if (! Node.OutEIdV.IsSorted()) {
541  const TStr Msg = TStr::Fmt("Out-edge list of node %d is not sorted.", Node.GetId());
542  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
543  }
544  if (! Node.InEIdV.IsSorted()) {
545  const TStr Msg = TStr::Fmt("In-edge list of node %d is not sorted.", Node.GetId());
546  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
547  }
548  // check out-edge ids
549  int prevEId = -1;
550  for (int e = 0; e < Node.GetOutDeg(); e++) {
551  if (! IsEdge(Node.GetOutEId(e))) {
552  const TStr Msg = TStr::Fmt("Out-edge id %d of node %d does not exist.", Node.GetOutEId(e), Node.GetId());
553  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
554  }
555  if (e > 0 && prevEId == Node.GetOutEId(e)) {
556  const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge id %d.", Node.GetId(), Node.GetOutEId(e));
557  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
558  }
559  prevEId = Node.GetOutEId(e);
560  }
561  // check in-edge ids
562  prevEId = -1;
563  for (int e = 0; e < Node.GetInDeg(); e++) {
564  if (! IsEdge(Node.GetInEId(e))) {
565  const TStr Msg = TStr::Fmt("Out-edge id %d of node %d does not exist.", Node.GetInEId(e), Node.GetId());
566  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
567  }
568  if (e > 0 && prevEId == Node.GetInEId(e)) {
569  const TStr Msg = TStr::Fmt("Node %d has duplidate out-edge id %d.", Node.GetId(), Node.GetInEId(e));
570  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
571  }
572  prevEId = Node.GetInEId(e);
573  }
574  }
575  for (int E = EdgeH.FFirstKeyId(); EdgeH.FNextKeyId(E); ) {
576  const TEdge& Edge = EdgeH[E];
577  if (! IsNode(Edge.GetSrcNId())) {
578  const TStr Msg = TStr::Fmt("Edge %d source node %d does not exist.", Edge.GetId(), Edge.GetSrcNId());
579  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
580  }
581  if (! IsNode(Edge.GetDstNId())) {
582  const TStr Msg = TStr::Fmt("Edge %d destination node %d does not exist.", Edge.GetId(), Edge.GetDstNId());
583  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false;
584  }
585  }
586  return RetVal;
587 }
588 
589 void TNEGraph::Dump(FILE *OutF) const {
590  const int NodePlaces = (int) ceil(log10((double) GetNodes()));
591  const int EdgePlaces = (int) ceil(log10((double) GetEdges()));
592  fprintf(OutF, "-------------------------------------------------\nDirected Node-Edge Graph: nodes: %d, edges: %d\n", GetNodes(), GetEdges());
593  for (TNodeI NodeI = BegNI(); NodeI < EndNI(); NodeI++) {
594  fprintf(OutF, " %*d]\n", NodePlaces, NodeI.GetId());
595  fprintf(OutF, " in[%d]", NodeI.GetInDeg());
596  for (int edge = 0; edge < NodeI.GetInDeg(); edge++) {
597  fprintf(OutF, " %*d", EdgePlaces, NodeI.GetInEId(edge)); }
598  fprintf(OutF, "\n out[%d]", NodeI.GetOutDeg());
599  for (int edge = 0; edge < NodeI.GetOutDeg(); edge++) {
600  fprintf(OutF, " %*d", EdgePlaces, NodeI.GetOutEId(edge)); }
601  fprintf(OutF, "\n");
602  }
603  for (TEdgeI EdgeI = BegEI(); EdgeI < EndEI(); EdgeI++) {
604  fprintf(OutF, " %*d] %*d -> %*d\n", EdgePlaces, EdgeI.GetId(), NodePlaces, EdgeI.GetSrcNId(), NodePlaces, EdgeI.GetDstNId());
605  }
606  fprintf(OutF, "\n");
607 }
608 
609 // Return a small graph on 5 nodes and 6 edges.
611  PNEGraph Graph = TNEGraph::New();
612  for (int i = 0; i < 5; i++) { Graph->AddNode(i); }
613  Graph->AddEdge(0,1); Graph->AddEdge(0,2);
614  Graph->AddEdge(0,3); Graph->AddEdge(0,4);
615  Graph->AddEdge(1,2); Graph->AddEdge(1,2);
616  return Graph;
617 }
618 
620 // Bipartite graph
621 int TBPGraph::AddNode(int NId, const bool& LeftNode) {
622  if (NId == -1) { NId = MxNId; MxNId++; }
623  else if (IsLNode(NId)) { IAssertR(LeftNode, TStr::Fmt("Node with id %s already exists on the 'left'.", NId)); return NId; }
624  else if (IsRNode(NId)) { IAssertR(! LeftNode, TStr::Fmt("Node with id %s already exists on the 'right'.", NId)); return NId; }
625  else { MxNId = TMath::Mx(NId+1, MxNId()); }
626  if (LeftNode) { LeftH.AddDat(NId, TNode(NId)); }
627  else { RightH.AddDat(NId, TNode(NId)); }
628  return NId;
629 }
630 
631 // Delete node of ID NId from the bipartite graph.
632 void TBPGraph::DelNode(const int& NId) {
633  AssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist", NId));
634  THash<TInt, TNode>& SrcH = IsLNode(NId) ? LeftH : RightH;
635  THash<TInt, TNode>& DstH = IsLNode(NId) ? RightH : LeftH;
636  { TNode& Node = SrcH.GetDat(NId);
637  for (int e = 0; e < Node.GetOutDeg(); e++) {
638  const int nbr = Node.GetOutNId(e);
639  IAssertR(nbr != NId, "Bipartite graph has a loop!");
640  TNode& N = DstH.GetDat(nbr);
641  const int n = N.NIdV.SearchBin(NId);
642  IAssert(n!= -1);
643  N.NIdV.Del(n);
644  } }
645  SrcH.DelKey(NId);
646 }
647 
648 int TBPGraph::GetEdges() const {
649  int Edges = 0;
650  for (int N=LeftH.FFirstKeyId(); LeftH.FNextKeyId(N); ) {
651  Edges += LeftH[N].GetDeg(); }
652  return Edges;
653 }
654 
655 int TBPGraph::AddEdge(const int& LeftNId, const int& RightNId) {
656  const bool IsLL = IsLNode(LeftNId), IsLR = IsRNode(LeftNId);
657  const bool IsRL = IsLNode(RightNId), IsRR = IsRNode(RightNId);
658  IAssertR((IsLL||IsLR)&&(IsRL||IsRR), TStr::Fmt("%d or %d is not a node.", LeftNId, RightNId).CStr());
659  IAssertR(LeftNId!=RightNId, "No self-edges are allowed.");
660  IAssertR((IsLL&&!IsLR&&!IsRL&&IsRR)||(!IsLL&&IsLR&&IsRL&&!IsRR), "One node should be on the 'left' and the other on the 'right'.");
661  const int LNId = IsLL ? LeftNId : RightNId; // the real left node
662  const int RNId = IsLL ? RightNId : LeftNId; // the real right node
663  if (LeftH.GetDat(LNId).IsOutNId(RNId)) { return -2; } // edge already exists
664  LeftH.GetDat(LNId).NIdV.AddSorted(RNId);
665  RightH.GetDat(RNId).NIdV.AddSorted(LNId);
666  return -1; // edge id
667 }
668 
669 void TBPGraph::DelEdge(const int& LeftNId, const int& RightNId) {
670  const bool IsLL = IsLNode(LeftNId), IsLR = IsRNode(LeftNId);
671  const bool IsRL = IsLNode(RightNId), IsRR = IsRNode(RightNId);
672  IAssertR((IsLL||IsLR)&&(IsRL||IsRR), TStr::Fmt("%d or %d is not a node.", LeftNId, RightNId).CStr());
673  IAssertR(LeftNId!=RightNId, "No self-edges are allowed.");
674  IAssertR((IsLL&&!IsLR&&!IsRL&&IsRR)||(!IsLL&&IsLR&&IsRL&&!IsRR), "One node should be on the 'left' and the other on the 'right'.");
675  const int LNId = IsLL ? LeftNId : RightNId; // the real left node
676  const int RNId = IsLL ? RightNId : LeftNId; // the real right node
677  { TIntV& NIdV = LeftH.GetDat(LNId).NIdV;
678  const int n = NIdV.SearchBin(RNId);
679  if (n != -1) { NIdV.Del(n); } }
680  { TIntV& NIdV = RightH.GetDat(RNId).NIdV;
681  const int n = NIdV.SearchBin(LNId);
682  if (n != -1) { NIdV.Del(n); } }
683 }
684 
685 bool TBPGraph::IsEdge(const int& LeftNId, const int& RightNId) const {
686  if (! IsNode(LeftNId) || ! IsNode(RightNId)) { return false; }
687  return IsLNode(LeftNId) ? LeftH.GetDat(LeftNId).IsOutNId(RightNId) : RightH.GetDat(LeftNId).IsOutNId(RightNId);
688 }
689 
690 TBPGraph::TEdgeI TBPGraph::GetEI(const int& LeftNId, const int& RightNId) const {
691  const bool IsLL = IsLNode(LeftNId), IsLR = IsRNode(LeftNId);
692  const bool IsRL = IsLNode(RightNId), IsRR = IsRNode(RightNId);
693  IAssertR((IsLL||IsLR)&&(IsRL||IsRR), TStr::Fmt("%d or %d is not a node.", LeftNId, RightNId).CStr());
694  IAssertR(LeftNId!=RightNId, "No self-edges are allowed.");
695  IAssertR((IsLL&&!IsLR&&!IsRL&&IsRR)||(!IsLL&&IsLR&&IsRL&&!IsRR), "One node should be on the 'left' and the other on the 'right'.");
696  const int LNId = IsLL ? LeftNId : RightNId; // the real left node
697  const int RNId = IsLL ? RightNId : LeftNId; // the real right node
698  const TNodeI SrcNI = GetNI(LNId);
699  const int NodeN = SrcNI.LeftHI.GetDat().NIdV.SearchBin(RNId);
700  IAssertR(NodeN != -1, "Right edge endpoint does not exists!");
701  return TEdgeI(SrcNI, EndNI(), NodeN);
702 }
703 
705  const int NNodes = GetNodes();
706  if (Rnd.GetUniDevInt(NNodes) < GetLNodes()) {
707  return GetRndLNId(Rnd); }
708  else {
709  return GetRndRNId(Rnd); }
710 }
711 
713  return LeftH.GetKey(LeftH.GetRndKeyId(Rnd, 0.8));
714 }
715 
717  return RightH.GetKey(RightH.GetRndKeyId(Rnd, 0.8));
718 }
719 
720 void TBPGraph::GetNIdV(TIntV& NIdV) const {
721  NIdV.Gen(GetNodes(), 0);
722  for (int N=LeftH.FFirstKeyId(); LeftH.FNextKeyId(N); ) {
723  NIdV.Add(LeftH.GetKey(N)); }
724  for (int N=RightH.FFirstKeyId(); RightH.FNextKeyId(N); ) {
725  NIdV.Add(RightH.GetKey(N)); }
726 }
727 
728 void TBPGraph::GetLNIdV(TIntV& NIdV) const {
729  NIdV.Gen(GetLNodes(), 0);
730  for (int N=LeftH.FFirstKeyId(); LeftH.FNextKeyId(N); ) {
731  NIdV.Add(LeftH.GetKey(N)); }
732 }
733 
734 void TBPGraph::GetRNIdV(TIntV& NIdV) const {
735  NIdV.Gen(GetRNodes(), 0);
736  for (int N=RightH.FFirstKeyId(); RightH.FNextKeyId(N); ) {
737  NIdV.Add(RightH.GetKey(N)); }
738 }
739 
740 void TBPGraph::Reserve(const int& Nodes, const int& Edges) {
741  if (Nodes>0) { LeftH.Gen(Nodes/2); RightH.Gen(Nodes/2); }
742 }
743 
744 void TBPGraph::Defrag(const bool& OnlyNodeLinks) {
745  for (int n = LeftH.FFirstKeyId(); LeftH.FNextKeyId(n); ) {
746  LeftH[n].NIdV.Pack(); }
747  for (int n = RightH.FFirstKeyId(); RightH.FNextKeyId(n); ) {
748  RightH[n].NIdV.Pack(); }
749  if (! OnlyNodeLinks && ! LeftH.IsKeyIdEqKeyN()) { LeftH.Defrag(); }
750  if (! OnlyNodeLinks && ! RightH.IsKeyIdEqKeyN()) { RightH.Defrag(); }
751 }
752 
753 bool TBPGraph::IsOk(const bool& ThrowExcept) const {
754  bool RetVal = false;
755  // edge lists are sorted
756  for (int n = LeftH.FFirstKeyId(); LeftH.FNextKeyId(n); ) {
757  if (! LeftH[n].NIdV.IsSorted()) {
758  const TStr Msg = TStr::Fmt("Neighbor list of node %d is not sorted.", LeftH[n].GetId());
759  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; }
760  }
761  for (int n = RightH.FFirstKeyId(); RightH.FNextKeyId(n); ) {
762  if (! RightH[n].NIdV.IsSorted()) {
763  const TStr Msg = TStr::Fmt("Neighbor list of node %d is not sorted.", RightH[n].GetId());
764  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; }
765  }
766  // nodes only appear on one side
767  for (int n = LeftH.FFirstKeyId(); LeftH.FNextKeyId(n); ) {
768  if (RightH.IsKey(LeftH[n].GetId())) {
769  const TStr Msg = TStr::Fmt("'Left' node %d also appears on the 'right'.", LeftH[n].GetId());
770  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; }
771  }
772  for (int n = RightH.FFirstKeyId(); RightH.FNextKeyId(n); ) {
773  if (LeftH.IsKey(RightH[n].GetId())) {
774  const TStr Msg = TStr::Fmt("'Right' node %d also appears on the 'left'.", RightH[n].GetId());
775  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; }
776  }
777  // edges only point from left to right and right to left
778  for (int n = LeftH.FFirstKeyId(); LeftH.FNextKeyId(n); ) {
779  for (int e = 0; e < LeftH[n].NIdV.Len(); e++) {
780  if (! RightH.IsKey(LeftH[n].NIdV[e]) || ! RightH.GetDat(LeftH[n].NIdV[e]).NIdV.IsIn(LeftH[n].GetId())) {
781  const TStr Msg = TStr::Fmt("'Left' node %d does not point to the 'right' node %d.", LeftH[n].GetId(), LeftH[n].NIdV[e]());
782  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; }
783  }
784  }
785  for (int n = RightH.FFirstKeyId(); RightH.FNextKeyId(n); ) {
786  for (int e = 0; e < RightH[n].NIdV.Len(); e++) {
787  if (! LeftH.IsKey(RightH[n].NIdV[e]) || ! LeftH.GetDat(RightH[n].NIdV[e]).NIdV.IsIn(RightH[n].GetId())) {
788  const TStr Msg = TStr::Fmt("'Left' node %d does not point to the 'right' node %d.", RightH[n].GetId(), RightH[n].NIdV[e]());
789  if (ThrowExcept) { EAssertR(false, Msg); } else { ErrNotify(Msg.CStr()); } RetVal=false; }
790  }
791  }
792  return RetVal;
793 }
794 
795 void TBPGraph::Dump(FILE *OutF) const {
796  const int NodePlaces = (int) ceil(log10((double) GetNodes()));
797  fprintf(OutF, "-------------------------------------------------\nBipartite Graph: nodes: %d+%d=%d, edges: %d\n", GetLNodes(), GetRNodes(), GetNodes(), GetEdges());
798  for (int N = LeftH.FFirstKeyId(); LeftH.FNextKeyId(N); ) {
799  const TNode& Node = LeftH[N];
800  fprintf(OutF, " %*d [%d] ", NodePlaces, Node.GetId(), Node.GetDeg());
801  for (int edge = 0; edge < Node.GetDeg(); edge++) {
802  fprintf(OutF, " %*d", NodePlaces, Node.GetNbrNId(edge)); }
803  fprintf(OutF, "\n");
804  }
805  fprintf(OutF, "\n");
806  /*// Also dump the 'right' side
807  fprintf(OutF, "\n");
808  for (int N = RightH.FFirstKeyId(); RightH.FNextKeyId(N); ) {
809  const TNode& Node = RightH[N];
810  fprintf(OutF, " %*d [%d] ", NodePlaces, Node.GetId(), Node.GetDeg());
811  for (int edge = 0; edge < Node.GetDeg(); edge++) {
812  fprintf(OutF, " %*d", NodePlaces, Node.GetNbrNId(edge)); }
813  fprintf(OutF, "\n");
814  }
815  fprintf(OutF, "\n"); //*/
816 }
817 
819  PBPGraph BP = TBPGraph::New();
820  BP->AddNode(0, true);
821  BP->AddNode(1, true);
822  BP->AddNode(2, false);
823  BP->AddNode(3, false);
824  BP->AddNode(4, false);
825  BP->AddEdge(0, 2);
826  BP->AddEdge(0, 3);
827  BP->AddEdge(1, 2);
828  BP->AddEdge(1, 3);
829  BP->AddEdge(1, 4);
830  return BP;
831 }
bool HasFlag(const TGraphFlag &Flag) const
Allows for run-time checking the type of the graph (see the TGraphFlag for flags).
Definition: graph.cpp:204
#define IAssert(Cond)
Definition: bd.h:262
static PBPGraph GetSmallGraph()
Returns a small graph on 2 'left', 3 'right' nodes and 4 edges.
Definition: graph.cpp:818
static const T & Mn(const T &LVal, const T &RVal)
Definition: xmath.h:36
Edge iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:114
int GetDeg() const
Definition: graph.h:852
bool DelIfIn(const TVal &Val)
Removes the first occurrence of element Val.
Definition: ds.h:1115
THashIter NodeHI
Definition: graph.h:66
int GetOutDeg() const
Definition: graph.h:314
void Reserve(const int &Nodes, const int &Edges)
Reserves memory for a biparite graph of Nodes nodes and Edges edges.
Definition: graph.cpp:740
int GetSrcNId() const
Definition: graph.h:599
bool IsKeyIdEqKeyN() const
Definition: hash.h:191
void GetNIdV(TIntV &NIdV) const
Gets a vector IDs of all nodes in the graph.
Definition: graph.cpp:326
#define IAssertR(Cond, Reason)
Definition: bd.h:265
bool IsInNId(const int &NId) const
Tests whether node with ID NId points to the current node.
Definition: graph.cpp:418
void DelNode(const int &NId)
Deletes node of ID NId from the graph.
Definition: graph.cpp:447
int AddEdge(const int &SrcNId, const int &DstNId, int EId=-1)
Adds an edge with ID EId between node IDs SrcNId and DstNId to the graph.
Definition: graph.cpp:466
bool IsOk(const bool &ThrowExcept=true) const
Checks the graph data structure for internal consistency.
Definition: graph.cpp:536
TEdgeI EndEI() const
Returns an iterator referring to the past-the-end edge in the graph.
Definition: graph.h:232
void GetRNIdV(TIntV &NIdV) const
Gets a vector IDs of all 'right' nodes in the bipartite graph.
Definition: graph.cpp:734
Definition: dt.h:11
static PUNGraph GetSmallGraph()
Returns a small graph on 5 nodes and 5 edges.
Definition: graph.cpp:193
void Del(const TSizeTy &ValN)
Removes the element at position ValN.
Definition: ds.h:1094
TNode & GetNode(const int &NId)
Definition: graph.h:140
int GetRndNId(TRnd &Rnd=TInt::Rnd)
Returns an ID of a random node in the graph.
Definition: graph.cpp:704
void Dump(FILE *OutF=stdout) const
Print the graph in a human readable form to an output stream OutF.
Definition: graph.cpp:387
static const T & Mx(const T &LVal, const T &RVal)
Definition: xmath.h:32
static PNGraph New()
Static constructor that returns a pointer to the graph. Call: PNGraph Graph = TNGraph::New().
Definition: graph.h:411
TNodeI GetNI(const int &NId) const
Returns an iterator referring to the node of ID NId in the graph.
Definition: graph.h:467
TEdgeI BegEI() const
Returns an iterator referring to the first edge in the graph.
Definition: graph.h:774
void GetNIdV(TIntV &NIdV) const
Gets a vector IDs of all nodes in the graph.
Definition: graph.cpp:125
int GetNbrNId(const int &NodeN) const
Definition: graph.h:857
int GetEdges() const
Returns the number of edges in the graph.
Definition: graph.cpp:278
Node iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:866
int AddNode(int NId=-1)
Adds a node of ID NId to the graph.
Definition: graph.cpp:8
THash< TInt, TNode > NodeH
Definition: graph.h:397
int GetEdges() const
Returns the number of edges in the graph.
Definition: graph.cpp:74
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:535
int GetId() const
Definition: graph.h:578
Node iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:63
int GetInDeg() const
Definition: graph.h:580
void GenExt(TVal *_ValT, const TSizeTy &_Vals)
Constructs a vector of _Vals elements of memory array _ValT.
Definition: ds.h:497
TInt NEdges
Definition: graph.h:137
bool IsOk(const bool &ThrowExcept=true) const
Checks the graph data structure for internal consistency.
Definition: graph.cpp:341
int GetOutEId(const int &EdgeN) const
Definition: graph.h:583
int AddNode(int NId=-1, const bool &LeftNode=true)
Adds a node of ID NId to the graph.
Definition: graph.cpp:621
Directed multigraph.
Definition: graph.h:563
TEdgeI EndEI() const
Returns an iterator referring to the past-the-end edge in the graph.
Definition: graph.h:776
int GetNodes() const
Returns the number of nodes in the graph.
Definition: graph.h:424
THashIter NodeHI
Definition: graph.h:330
int AddNode(int NId=-1)
Adds a node of ID NId to the graph.
Definition: graph.cpp:208
void Dump(FILE *OutF=stdout) const
Print the graph in a human readable form to an output stream OutF.
Definition: graph.cpp:179
Edge iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:664
const TDat & GetDat(const TKey &Key) const
Definition: hash.h:220
THashIter NodeHI
Definition: graph.h:607
int GetId() const
Definition: graph.h:47
int GetRndLNId(TRnd &Rnd=TInt::Rnd)
Returns an ID of a random 'left' node in the graph.
Definition: graph.cpp:712
TNodeI BegNI() const
Returns an iterator referring to the first node in the graph.
Definition: graph.h:738
int GetNodes() const
Returns the number of nodes in the graph.
Definition: graph.h:165
TSizeTy AddSorted(const TVal &Val, const bool &Asc=true, const TSizeTy &_MxVals=-1)
Adds element Val to a sorted vector.
Definition: ds.h:1027
void ErrNotify(const char *NotifyCStr)
Definition: bd.h:74
THash< TInt, TNode > NodeH
Definition: graph.h:695
void Defrag()
Definition: hash.h:509
int GetOutDeg() const
Definition: graph.h:581
TNode & GetNode(const int &NId)
Definition: graph.h:399
int GetOutNId(const int &NodeN) const
Definition: graph.h:856
int GetInDeg() const
Definition: graph.h:313
THash< TInt, TEdge > EdgeH
Definition: graph.h:696
int GetDstNId() const
Definition: graph.h:600
void DelNode(const int &NId)
Deletes node of ID NId from the graph.
Definition: graph.cpp:259
TNodeI EndNI() const
Returns an iterator referring to the past-the-end node in the graph.
Definition: graph.h:740
TEdgeI GetEI(const int &EId) const
Not supported/implemented!
int GetInEId(const int &EdgeN) const
Definition: graph.h:582
TNodeI GetNI(const int &NId) const
Returns an iterator referring to the node of ID NId in the graph.
Definition: graph.h:742
int GetId() const
Definition: graph.h:311
void DelKey(const TKey &Key)
Definition: hash.h:358
void GetNIdV(TIntV &NIdV) const
Gets a vector IDs of all nodes in the graph.
Definition: graph.cpp:514
int GetNodes() const
Returns the number of nodes in the graph.
Definition: graph.h:720
THashIter LeftHI
Definition: graph.h:869
TEdge & GetEdge(const int &EId)
Definition: graph.h:690
Undirected graph.
Definition: graph.h:32
bool IsOutNId(const int &NId) const
Tests whether the current node points to node with ID NId.
Definition: graph.cpp:427
TVal * GetValVPt(const int &VId) const
Returns pointer to the first element of the vector with id VId.
Definition: ds.h:1617
void Sort(const bool &Asc=true)
Sorts the elements of the vector.
Definition: ds.h:1218
#define HasGraphFlag(TGraph, Flag)
For quick testing of the properties of the graph/network object (see TGraphFlag). ...
Definition: gbase.h:38
Edge iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:372
int GetEdges() const
Returns the number of edges in the graph.
Definition: graph.cpp:648
TInt MxNId
Definition: graph.h:137
int AddEdge(const int &SrcNId, const int &DstNId)
Adds an edge from node IDs SrcNId to node DstNId to the graph.
Definition: graph.cpp:286
static PNEGraph GetSmallGraph()
Returns a small multigraph on 5 nodes and 6 edges.
Definition: graph.cpp:610
int GetVLen(const int &VId) const
Returns the number of elements in the vector with id VId.
Definition: ds.h:1615
void DelEdge(const int &SrcNId, const int &DstNId, const bool &IsDir=true)
Deletes an edge from node IDs SrcNId to DstNId from the graph.
Definition: graph.cpp:295
bool IsEdge(const int &SrcNId, const int &DstNId, const bool &IsDir=true) const
Tests whether an edge from node IDs SrcNId to DstNId exists in the graph.
Definition: graph.cpp:313
const TVal & GetDat(const TVal &Val) const
Returns reference to the first occurrence of element Val.
Definition: ds.h:792
TNodeI GetNI(const int &NId) const
Returns an iterator referring to the node of ID NId in the graph.
Definition: graph.h:208
bool HasFlag(const TGraphFlag &Flag) const
Allows for run-time checking the type of the graph (see the TGraphFlag for flags).
Definition: graph.cpp:414
bool FNextKeyId(int &KeyId) const
Definition: hash.h:432
bool IsNode(const int &NId) const
Tests whether ID NId is a node.
Definition: graph.h:461
bool IsEdge(const int &LeftNId, const int &RightNId) const
Tests whether an edge between node IDs LeftNId and RightNId exists in the graph.
Definition: graph.cpp:685
TIntV NIdV
Definition: graph.h:40
TEdgeI BegEI() const
Returns an iterator referring to the first edge in the graph.
Definition: graph.h:230
void GetLNIdV(TIntV &NIdV) const
Gets a vector IDs of all 'left' nodes in the bipartite graph.
Definition: graph.cpp:728
static PUNGraph New()
Static constructor that returns a pointer to the graph. Call: PUNGraph Graph = TUNGraph::New().
Definition: graph.h:152
int FFirstKeyId() const
Definition: hash.h:232
int GetOutNId(const int &NodeN) const
Definition: graph.h:316
int AddNode(int NId=-1)
Adds a node of ID NId to the graph.
Definition: graph.cpp:436
void DelEdge(const int &SrcNId, const int &DstNId)
Deletes an edge between node IDs SrcNId and DstNId from the graph.
Definition: graph.cpp:95
TIntV OutEIdV
Definition: graph.h:571
void Dump(FILE *OutF=stdout) const
Print the graph in a human readable form to an output stream OutF.
Definition: graph.cpp:589
TIntV NIdV
Definition: graph.h:843
TSizeTy SearchBin(const TVal &Val) const
Returns the position of an element with value Val.
Definition: ds.h:1418
void Defrag(const bool &OnlyNodeLinks=false)
Defragments the graph.
Definition: graph.cpp:332
int AddEdge(const int &SrcNId, const int &DstNId)
Adds an edge between node IDs SrcNId and DstNId to the graph.
Definition: graph.cpp:84
TNode & GetNode(const int &NId)
Definition: graph.h:688
static PNEGraph New()
Static constructor that returns a pointer to the graph. Call: PNEGraph Graph = TNEGraph::New().
Definition: graph.h:707
int AddEdge(const int &LeftNId, const int &RightNId)
Adds an edge between a node LeftNId on the left and a node RightNId on the right side of the bipartit...
Definition: graph.cpp:655
void DelEdge(const int &LeftNId, const int &RightNId)
Deletes an edge between a node LeftNId on the left and a node RightNId on the right side of the bipar...
Definition: graph.cpp:669
Directed graph.
Definition: graph.h:296
bool IsNbrNId(const int &NId) const
Definition: graph.h:54
int GetNbrNId(const int &NodeN) const
Definition: graph.h:53
void DelNode(const int &NId)
Deletes node of ID NId from the graph.
Definition: graph.cpp:632
bool IsEdge(const int &EId) const
Tests whether an edge with edge ID EId exists in the graph.
Definition: graph.h:766
TNodeI EndNI() const
Returns an iterator referring to the past-the-end node in the graph.
Definition: graph.h:465
static PNGraph GetSmallGraph()
Returns a small graph on 5 nodes and 6 edges.
Definition: graph.cpp:404
int GetRndRNId(TRnd &Rnd=TInt::Rnd)
Returns an ID of a random 'right' node in the graph.
Definition: graph.cpp:716
Definition: dt.h:412
THash< TInt, TNode > NodeH
Definition: graph.h:138
void GetEIdV(TIntV &EIdV) const
Gets a vector IDs of all edges in the graph.
Definition: graph.cpp:520
static TStr Fmt(const char *FmtStr,...)
Definition: dt.cpp:1599
bool IsSorted(const bool &Asc=true) const
Checks whether the vector is sorted in ascending (if Asc=true) or descending (if Asc=false) order...
Definition: ds.h:1223
void Pack()
The vector reduces its capacity (frees memory) to match its size.
Definition: ds.h:987
int GetId() const
Definition: graph.h:851
enum TGraphFlag_ TGraphFlag
Graph Flags, used for quick testing of graph types.
int GetEdges() const
Returns the number of edges in the graph.
Definition: graph.h:747
Node iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:327
void Defrag(const bool &OnlyNodeLinks=false)
Defragments the graph.
Definition: graph.cpp:132
#define EAssertR(Cond, MsgStr)
Definition: bd.h:283
TNodeI EndNI() const
Returns an iterator referring to the past-the-end node in the graph.
Definition: graph.h:206
int GetOutDeg() const
Definition: graph.h:854
const TNEGraph * Graph
Definition: graph.h:608
TIntV InNIdV
Definition: graph.h:304
static PBPGraph New()
Static constructor that returns a pointer to the graph. Call: PBPGraph BPGraph = TBPGraph::New();.
Definition: graph.h:960
TInt MxNId
Definition: graph.h:694
bool IsNode(const int &NId) const
Tests whether ID NId is a node.
Definition: graph.h:202
TInt MxNId
Definition: graph.h:396
#define AssertR(Cond, Reason)
Definition: bd.h:258
bool HasFlag(const TGraphFlag &Flag) const
Allows for run-time checking the type of the graph (see the TGraphFlag for flags).
Definition: graph.cpp:3
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements.
Definition: ds.h:486
void GetNIdV(TIntV &NIdV) const
Gets a vector IDs of all nodes in the bipartite graph.
Definition: graph.cpp:720
int GetUniDevInt(const int &Range=0)
Definition: dt.cpp:39
bool IsOk(const bool &ThrowExcept=true) const
Checks the graph data structure for internal consistency.
Definition: graph.cpp:142
TIntV OutNIdV
Definition: graph.h:304
void Defrag(const bool &OnlyNodeLinks=false)
Defragments the graph.
Definition: graph.cpp:527
void Dump(FILE *OutF=stdout) const
Print the biparite graph in a human readable form to an output stream OutF.
Definition: graph.cpp:795
char * CStr()
Definition: dt.h:476
void Defrag(const bool &OnlyNodeLinks=false)
Defragments the biparite graph.
Definition: graph.cpp:744
bool IsEdge(const int &SrcNId, const int &DstNId) const
Tests whether an edge between node IDs SrcNId and DstNId exists in the graph.
Definition: graph.cpp:108
void DelEdge(const int &EId)
Deletes an edge with edge ID EId from the graph.
Definition: graph.cpp:477
TEdgeI GetEI(const int &EId) const
Not supported/implemented!
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:559
int GetInNId(const int &NodeN) const
Definition: graph.h:315
int GetDeg() const
Definition: graph.h:48
bool IsOutNId(const int &NId) const
Definition: graph.h:319
TInt MxEId
Definition: graph.h:694
TDat & AddDat(const TKey &Key)
Definition: hash.h:196
bool IsOk(const bool &ThrowExcept=true) const
Checks the bipartite graph data structure for internal consistency.
Definition: graph.cpp:753
void DelNode(const int &NId)
Deletes node of ID NId from the graph.
Definition: graph.cpp:59
Edge iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:916
Node iterator. Only forward iteration (operator++) is supported.
Definition: graph.h:604
void Pack()
Definition: hash.h:243
const TKey & GetKey(const int &KeyId) const
Definition: hash.h:210
TEdgeI GetEI(const int &EId) const
Not supported/implemented!
bool IsNode(const int &NId) const
Tests whether ID NId is a node.
Definition: graph.h:736
TIntV InEIdV
Definition: graph.h:571
int GetId() const
Definition: graph.h:598