SNAP Library 4.1, Developer Reference  2018-07-26 16:30:42
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
subgraph.h
Go to the documentation of this file.
1 
5 namespace TSnap {
7 
9 // Convert between graph types and get subgraphs
10 
11 // node subgraphs
13 
18 template<class PGraph> PGraph GetSubGraph(const PGraph& Graph, const TIntV& NIdV);
20 
25 template<class PGraph> PGraph GetSubGraphRenumber(const PGraph& Graph, const TIntV& NIdV);
27 
35 PUNGraph GetSubGraph(const PUNGraph& Graph, const TIntV& NIdV, const bool& RenumberNodes=false);
36 // Returns an induced subgraph of a directed graph Graph with NIdV nodes with an optional node renumbering. ##TSnap::GetSubGraph-2
37 PNGraph GetSubGraph(const PNGraph& Graph, const TIntV& NIdV, const bool& RenumberNodes=false);
38 // TODO ROK 2012/08/15 PNGraph GetSubGraph is not documented by doxygen.
39 // It is combined with PUNGraph GetSubGraph.
40 
41 // edge subgraphs
43 
52 template<class PGraph> PGraph GetESubGraph(const PGraph& Graph, const TIntV& EIdV);
53 // Returns a subgraph of graph Graph with EdgeV edges. ##TSnap::GetESubGraph-1
54 template<class PGraph> PGraph GetESubGraph(const PGraph& Graph, const TIntPrV& EdgeV);
55 // TODO ROK 2012/08/15 PGraph GetESubGraph TIntPrV is not documented by doxygen.
56 // It is combined with PGraph GetESubGraph TIntV.
58 
71 template<class PGraph, class TEdgeDat> PGraph GetEDatSubGraph(const PGraph& Graph, const TEdgeDat& EDat, const int& Cmp);
73 
87 template<class PGraph, class TEdgeDat> PGraph GetEDatSubGraph(const PGraph& Graph, const TIntV& NIdV, const TEdgeDat& EDat, const int& Cmp);
88 
89 // convert between the graphs. Does NOT copy the data
91 
102 template<class POutGraph, class PInGraph> POutGraph ConvertGraph(const PInGraph& InGraph, const bool& RenumberNodes=false);
104 
115 template<class POutGraph, class PInGraph> POutGraph ConvertSubGraph(const PInGraph& InGraph, const TIntV& NIdV, const bool& RenumberNodes=false);
116 // TODO RS 2012/08/14 find out why TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV, true) aborts
118 
129 template<class POutGraph, class PInGraph> POutGraph ConvertESubGraph(const PInGraph& InGraph, const TIntV& EIdV, const bool& RenumberNodes=false);
130 // does not work on multigraphs
131 
132 // get random (induced) subgraphs
134 
137 template<class PGraph> PGraph GetRndSubGraph(const PGraph& Graph, const int& NNodes);
139 
142 template<class PGraph> PGraph GetRndESubGraph(const PGraph& Graph, const int& NEdges);
143 
144 // get egonet of a center node
146 PUNGraph GetEgonet(const PUNGraph& Graph, const int CtrNId, int& ArndEdges);
148 PNGraph GetEgonet(const PNGraph& Graph, const int CtrNId, int& InEdges, int& OutEdges);
149 
151 // Implementation
152 namespace TSnapDetail {
153 // Slow for small sub-graphs as it traverses all the edges of Graph
154 template <class PGraph, bool IsMultiGraph>
155 struct TGetSubGraph {
156  static PGraph Do(const PGraph& Graph, const TIntV& NIdV) {
157  PGraph NewGraphPt = PGraph::TObj::New();
158  typename PGraph::TObj& NewGraph = *NewGraphPt;
159  NewGraph.Reserve(NIdV.Len(), -1);
160  for (int n = 0; n < NIdV.Len(); n++) {
161  if (Graph->IsNode(NIdV[n])) {
162  NewGraph.AddNode(Graph->GetNI(NIdV[n])); }
163  }
164  for (typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
165  if (NewGraph.IsNode(EI.GetSrcNId()) && NewGraph.IsNode(EI.GetDstNId())) {
166  NewGraph.AddEdge(EI); }
167  }
168  NewGraph.Defrag();
169  return NewGraphPt;
170  }
171 };
172 
173 template <class PGraph>
174 struct TGetSubGraph<PGraph, false> { // not multigraph
175  static PGraph Do(const PGraph& Graph, const TIntV& NIdV) {
176  CAssert(! HasGraphFlag(typename PGraph::TObj, gfMultiGraph));
177  PGraph NewGraphPt = PGraph::TObj::New();
178  typename PGraph::TObj& NewGraph = *NewGraphPt;
179  NewGraph.Reserve(NIdV.Len(), -1);
180  TIntSet NodeSet;
181  for (int n = 0; n < NIdV.Len(); n++) {
182  if (! HasGraphFlag(typename PGraph::TObj, gfNodeDat)) {
183  if (Graph->IsNode(NIdV[n])) { NewGraph.AddNode(NIdV[n]); NodeSet.AddKey(NIdV[n]); } }
184  else {
185  if (Graph->IsNode(NIdV[n])) { NewGraph.AddNode(Graph->GetNI(NIdV[n])); NodeSet.AddKey(NIdV[n]); } }
186  }
187  for (int n = 0; n < NodeSet.Len(); n++) {
188  const int SrcNId = NodeSet[n];
189  const typename PGraph::TObj::TNodeI NI = Graph->GetNI(SrcNId);
190  for (int edge = 0; edge < NI.GetOutDeg(); edge++) {
191  const int OutNId = NI.GetOutNId(edge);
192  if (NewGraph.IsNode(OutNId)) {
193  if (! HasGraphFlag(typename PGraph::TObj, gfEdgeDat)) {
194  NewGraph.AddEdge(SrcNId, OutNId); }
195  else {
196  NewGraph.AddEdge(Graph->GetEI(SrcNId, OutNId)); } // also copy data
197  }
198  }
199  }
200  NewGraph.Defrag();
201  return NewGraphPt;
202  }
203 };
204 }; // TSnapDetail
205 
206 template<class PGraph>
207 PGraph GetSubGraph(const PGraph& Graph, const TIntV& NIdV) {
209  ::Do(Graph, NIdV);
210 }
211 
212 template<class PGraph>
213 PGraph GetSubGraphRenumber(const PGraph& Graph, const TIntV& NIdV) {
214  return GetSubGraph(Graph, NIdV, true);
215 }
216 
217 template<class PGraph>
218 PGraph GetESubGraph(const PGraph& Graph, const TIntV& EIdV) {
219  CAssert(HasGraphFlag(typename PGraph::TObj, gfMultiGraph));
220  PGraph NewGraphPt = PGraph::TObj::New();
221  typename PGraph::TObj& NewGraph = *NewGraphPt;
222  NewGraph.Reserve(-1, EIdV.Len());
223  for (int edge = 0; edge < EIdV.Len(); edge++) {
224  const int EId = EIdV[edge];
225  IAssert(Graph->IsEdge(EId));
226  const typename PGraph::TObj::TEdgeI EI = Graph->GetEI(EId);
227  if (! NewGraph.IsNode(EI.GetSrcNId())) {
228  NewGraph.AddNode(Graph->GetNI(EI.GetSrcNId()));
229  }
230  if (! NewGraph.IsNode(EI.GetDstNId())) {
231  NewGraph.AddNode(Graph->GetNI(EI.GetDstNId()));
232  }
233  NewGraph.AddEdge(EI);
234  }
235  return NewGraphPt;
236 }
237 
238 template<class PGraph>
239 PGraph GetESubGraph(const PGraph& Graph, const TIntPrV& EdgeV) {
240  PGraph NewGraphPt = PGraph::TObj::New();
241  typename PGraph::TObj& NewGraph = *NewGraphPt;
242  NewGraph.Reserve(-1, EdgeV.Len());
243 
244  for (int edge = 0; edge < EdgeV.Len(); edge++) {
245  const int SrcNId = EdgeV[edge].Val1;
246  const int DstNId = EdgeV[edge].Val2;
247  if (! NewGraph.IsNode(SrcNId)) {
248  NewGraph.AddNode(Graph->GetNI(SrcNId));
249  }
250  if (! NewGraph.IsNode(DstNId)) {
251  NewGraph.AddNode(Graph->GetNI(DstNId));
252  }
253 
254  NewGraph.AddEdge(SrcNId, DstNId);
255  }
256  return NewGraphPt;
257 }
258 
259 // Get a subgraph on NIdV nodes, where edge data is Cmp (-1:less, 0:equal, 1:greater) than EDat
260 template<class PGraph, class TEdgeDat>
261 PGraph GetEDatSubGraph(const PGraph& Graph, const TEdgeDat& EDat, const int& Cmp) {
262  CAssert(HasGraphFlag(typename PGraph::TObj, gfEdgeDat));
263  PGraph NewGraphPt = PGraph::TObj::New();
264  typename PGraph::TObj& NewGraph = *NewGraphPt;
265  for (typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
266  if ((Cmp==1 && EI()>EDat) || (Cmp==-1 && EI()<EDat) || (Cmp==0 && EI()==EDat)) {
267  if (! NewGraph.IsNode(EI.GetSrcNId())) {
268  NewGraph.AddNode(Graph->GetNI(EI.GetSrcNId()));
269  }
270  if (! NewGraph.IsNode(EI.GetDstNId())) {
271  NewGraph.AddNode(Graph->GetNI(EI.GetDstNId()));
272  }
273  NewGraph.AddEdge(EI);
274  }
275  }
276  return NewGraphPt;
277 }
278 
279 // Get a subgraph on NIdV nodes, where edge data is Cmp (-1:less, 0:equal, 1:greater) than EDat
280 template<class PGraph, class TEdgeDat>
281 PGraph GetEDatSubGraph(const PGraph& Graph, const TIntV& NIdV, const TEdgeDat& EDat, const int& Cmp) {
282  CAssert(HasGraphFlag(typename PGraph::TObj, gfEdgeDat));
283  PGraph NewGraphPt = PGraph::TObj::New();
284  typename PGraph::TObj& NewGraph = *NewGraphPt;
285  NewGraph.Reserve(NIdV.Len(), -1);
286  for (int n = 0; n < NIdV.Len(); n++) {
287  NewGraph.AddNode(Graph->GetNI(NIdV[n]));
288  }
289  for (typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
290  if (NewGraph.IsNode(EI.GetSrcNId()) && NewGraph.IsNode(EI.GetDstNId()) &&
291  ((Cmp==1 && EI()>EDat)|| (Cmp==-1 && EI()<EDat) || (Cmp==0 && EI()==EDat))) {
292  NewGraph.AddEdge(EI); }
293  }
294  NewGraph.Defrag();
295  return NewGraphPt;
296 }
297 
298 // Converts between different types of graphs/networks
299 // Node/edge data is not copied between the graphs.
300 template<class POutGraph, class PInGraph>
301 POutGraph ConvertGraph(const PInGraph& InGraph, const bool& RenumberNodes) {
302  POutGraph OutGraphPt = POutGraph::TObj::New();
303  typename POutGraph::TObj& OutGraph = *OutGraphPt;
304  OutGraph.Reserve(InGraph->GetNodes(), InGraph->GetEdges());
305  if (! RenumberNodes) {
306  for (typename PInGraph::TObj::TNodeI NI = InGraph->BegNI(); NI < InGraph->EndNI(); NI++) {
307  OutGraph.AddNode(NI.GetId());
308  }
309  for (typename PInGraph::TObj::TEdgeI EI = InGraph->BegEI(); EI < InGraph->EndEI(); EI++) {
310  OutGraph.AddEdge(EI.GetSrcNId(), EI.GetDstNId());
311  if (! HasGraphFlag(typename PInGraph::TObj, gfDirected) && HasGraphFlag(typename POutGraph::TObj, gfDirected)) { // add edge in the other direction
312  OutGraph.AddEdge(EI.GetDstNId(), EI.GetSrcNId()); }
313  }
314  } else { // renumber nodes so that node ids are 0...N-1
315  TIntSet NIdSet(InGraph->GetNodes());
316  for (typename PInGraph::TObj::TNodeI NI = InGraph->BegNI(); NI < InGraph->EndNI(); NI++) {
317  const int nid = NIdSet.AddKey(NI.GetId());
318  OutGraph.AddNode(nid);
319  }
320  for (typename PInGraph::TObj::TEdgeI EI = InGraph->BegEI(); EI < InGraph->EndEI(); EI++) {
321  const int SrcNId = NIdSet.GetKeyId(EI.GetSrcNId());
322  const int DstNId = NIdSet.GetKeyId(EI.GetDstNId());
323  OutGraph.AddEdge(SrcNId, DstNId);
324  if (! HasGraphFlag(typename PInGraph::TObj, gfDirected) && HasGraphFlag(typename POutGraph::TObj, gfDirected)) {
325  OutGraph.AddEdge(DstNId, SrcNId); }
326  }
327  }
328  //OutGraph.Defrag();
329  return OutGraphPt;
330 }
331 
332 namespace TSnapDetail {
333 // Slow for small sub-graphs as it traverses all the edges of Graph
334 template <class POutGraph, class PInGraph, bool IsMultiGraph>
336  static POutGraph Do(const PInGraph& InGraph, const TIntV& NIdV, const bool& RenumberNodes) {
337  POutGraph OutGraphPt = POutGraph::TObj::New();
338  typename POutGraph::TObj& OutGraph = *OutGraphPt;
339  if (! RenumberNodes) {
340  for (int n = 0; n < NIdV.Len(); n++) {
341  OutGraph.AddNode(NIdV[n]);
342  }
343  for (typename PInGraph::TObj::TEdgeI EI = InGraph->BegEI(); EI < InGraph->EndEI(); EI++) {
344  if (! OutGraph.IsNode(EI.GetSrcNId()) || ! OutGraph.IsNode(EI.GetDstNId())) { continue; }
345  OutGraph.AddEdge(EI.GetSrcNId(), EI.GetDstNId());
346  if (! HasGraphFlag(typename PInGraph::TObj, gfDirected) && HasGraphFlag(typename POutGraph::TObj, gfDirected)) {
347  OutGraph.AddEdge(EI.GetDstNId(), EI.GetSrcNId());
348  }
349  }
350  } else { // renumber nodes so that node ids are 0...N-1
351  TIntSet NIdSet(InGraph->GetNodes());
352  for (int n = 0; n < NIdV.Len(); n++) {
353  const int NId = NIdSet.AddKey(NIdV[n]);
354  OutGraph.AddNode(NId);
355  }
356  for (typename PInGraph::TObj::TEdgeI EI = InGraph->BegEI(); EI < InGraph->EndEI(); EI++) {
357  const int SrcNId = NIdSet.GetKeyId(EI.GetSrcNId());
358  const int DstNId = NIdSet.GetKeyId(EI.GetDstNId());
359  if (! OutGraph.IsNode(SrcNId) || ! OutGraph.IsNode(DstNId)) { continue; }
360  OutGraph.AddEdge(SrcNId, DstNId);
361  if (! HasGraphFlag(typename PInGraph::TObj, gfDirected) && HasGraphFlag(typename POutGraph::TObj, gfDirected)) {
362  OutGraph.AddEdge(DstNId, SrcNId);
363  }
364  }
365  }
366  OutGraph.Defrag();
367  return OutGraphPt;
368  }
369 };
370 
371 template <class POutGraph, class PInGraph>
372 struct TConvertSubGraph<POutGraph, PInGraph, false> { // InGraph is not multigraph
373  static POutGraph Do(const PInGraph& InGraph, const TIntV& NIdV, const bool& RenumberNodes) {
374  POutGraph OutGraphPt = POutGraph::TObj::New();
375  typename POutGraph::TObj& OutGraph = *OutGraphPt;
376  if (! RenumberNodes) {
377  for (int n = 0; n < NIdV.Len(); n++) {
378  OutGraph.AddNode(NIdV[n]); }
379  for (int n = 0; n < NIdV.Len(); n++) {
380  typename PInGraph::TObj::TNodeI NI = InGraph->GetNI(NIdV[n]);
381  for (int e = 0; e < NI.GetOutDeg(); e++) {
382  const int dst = NI.GetOutNId(e);
383  if (! OutGraph.IsNode(dst)) { continue; }
384  OutGraph.AddEdge(NIdV[n], dst);
385  }
386  }
387  } else { // renumber nodes so that node ids are 0...N-1
388  TIntSet NIdSet(InGraph->GetNodes());
389  for (int n = 0; n < NIdV.Len(); n++) {
390  const int NId = NIdSet.AddKey(NIdV[n]);
391  OutGraph.AddNode(NId);
392  }
393  for (int n = 0; n < NIdV.Len(); n++) {
394  typename PInGraph::TObj::TNodeI NI = InGraph->GetNI(NIdV[n]);
395  const int src = NIdSet.GetKey(NIdV[n]);
396  for (int e = 0; e < NI.GetOutDeg(); e++) {
397  const int dst = NIdSet.GetKey(NI.GetOutNId(e));
398  if (! OutGraph.IsNode(dst)) { continue; }
399  OutGraph.AddEdge(src, dst);
400  }
401  }
402  }
403  OutGraph.Defrag();
404  return OutGraphPt;
405  }
406 };
407 } // TSnapDetail
408 
409 // May be slow as it traverses all the edges of the in-graph to create the sub-graph
410 template<class POutGraph, class PInGraph>
411 POutGraph ConvertSubGraph(const PInGraph& InGraph, const TIntV& NIdV, const bool& RenumberNodes) {
413 }
414 
415 template<class POutGraph, class PInGraph>
416 POutGraph ConvertESubGraph(const PInGraph& InGraph, const TIntV& EIdV, const bool& RenumberNodes) {
417  CAssert(HasGraphFlag(typename PInGraph::TObj, gfMultiGraph)); // needs to have explicit edges
418  POutGraph NewGraphPt = POutGraph::TObj::New();
419  typename POutGraph::TObj& NewGraph = *NewGraphPt;
420  NewGraph.Reserve(-1, EIdV.Len());
421  if (! RenumberNodes) {
422  for (int edge = 0; edge < EIdV.Len(); edge++) {
423  const int EId = EIdV[edge];
424  IAssert(InGraph->IsEdge(EId));
425  const typename PInGraph::TObj::TEdgeI EI = InGraph->GetEI(EId);
426  const int SrcNId = EI.GetSrcNId();
427  const int DstNId = EI.GetDstNId();
428  if (! NewGraph.IsNode(SrcNId)) {
429  NewGraph.AddNode(SrcNId); }
430  if (! NewGraph.IsNode(DstNId)) {
431  NewGraph.AddNode(DstNId); }
432  NewGraph.AddEdge(SrcNId, DstNId);
433  }
434  } else {
435  // renumber nodes so that node ids are 0...N-1
436  TIntSet NIdSet(InGraph->GetNodes());
437  for (int edge = 0; edge < EIdV.Len(); edge++) {
438  const int EId = EIdV[edge];
439  IAssert(InGraph->IsEdge(EId));
440  const typename PInGraph::TObj::TEdgeI EI = InGraph->GetEI(EId);
441  const int SrcNId = NIdSet.AddKey(EI.GetSrcNId()); // map node ids
442  const int DstNId = NIdSet.AddKey(EI.GetDstNId());
443  if (! NewGraph.IsNode(SrcNId)) {
444  NewGraph.AddNode(SrcNId); }
445  if (! NewGraph.IsNode(DstNId)) {
446  NewGraph.AddNode(DstNId); }
447  NewGraph.AddEdge(SrcNId, DstNId);
448  }
449  }
450  return NewGraphPt;
451 }
452 
453 template<class PGraph>
454 PGraph GetRndSubGraph(const PGraph& Graph, const int& NNodes) {
455  IAssert(NNodes <= Graph->GetNodes());
456  TIntV NIdV;
457  Graph->GetNIdV(NIdV);
458  NIdV.Shuffle(TInt::Rnd);
459  NIdV.Del(NNodes, NIdV.Len()-1);
460  IAssert(NIdV.Len() == NNodes);
461  return GetSubGraph(Graph, NIdV);
462 }
463 
464 template<class PGraph>
465 PGraph GetRndESubGraph(const PGraph& Graph, const int& NEdges) {
466  CAssert(! HasGraphFlag(typename PGraph::TObj, gfMultiGraph));
467  TIntPrV EdgeV(Graph->GetEdges(), 0);
468  for (typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
469  EdgeV.Add(TIntPr(EI.GetSrcNId(), EI.GetDstNId()));
470  }
471  EdgeV.Shuffle(TInt::Rnd);
472  EdgeV.Del(NEdges, EdgeV.Len()-1);
473  IAssert(EdgeV.Len() == NEdges);
474  return GetESubGraph(Graph, EdgeV);
475 }
476 
477 } // namespace TSnap
#define IAssert(Cond)
Definition: bd.h:262
TPair< TInt, TInt > TIntPr
Definition: ds.h:83
void Defrag()
Definition: shash.h:1366
void Del(const TSizeTy &ValN)
Removes the element at position ValN.
Definition: ds.h:1189
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:575
PUNGraph GetEgonet(const PUNGraph &Graph, const int CtrNId, int &ArndEdges)
Returns the egonet of node CtrNId as center in undirected graph Graph. And returns number of edges ar...
Definition: subgraph.cpp:82
static TRnd Rnd
Definition: dt.h:1143
have explicit edges (multigraph): TNEGraph, TNodeEdgeNet
Definition: gbase.h:14
POutGraph ConvertSubGraph(const PInGraph &InGraph, const TIntV &NIdV, const bool &RenumberNodes=false)
Returns an induced subgraph of graph InGraph with NIdV nodes with an optional node renumbering...
Definition: subgraph.h:411
#define HasGraphFlag(TGraph, Flag)
For quick testing of the properties of the graph/network object (see TGraphFlag). ...
Definition: gbase.h:41
static PGraph Do(const PGraph &Graph, const TIntV &NIdV)
Definition: subgraph.h:156
network with data on edges
Definition: gbase.h:16
PGraph GetRndESubGraph(const PGraph &Graph, const int &NEdges)
Returns a random subgraph of graph Graph with NEdges edges.
Definition: subgraph.h:465
PUNGraph GetSubGraph(const PUNGraph &Graph, const TIntV &NIdV, const bool &RenumberNodes)
Returns an induced subgraph of an undirected graph Graph with NIdV nodes with an optional node renumb...
Definition: subgraph.cpp:7
static POutGraph Do(const PInGraph &InGraph, const TIntV &NIdV, const bool &RenumberNodes)
Definition: subgraph.h:336
static PGraph Do(const PGraph &Graph, const TIntV &NIdV)
Definition: subgraph.h:175
int AddKey(const TKey &Key)
Definition: shash.h:1254
static POutGraph Do(const PInGraph &InGraph, const TIntV &NIdV, const bool &RenumberNodes)
Definition: subgraph.h:373
PGraph GetSubGraphRenumber(const PGraph &Graph, const TIntV &NIdV)
Returns an induced subgraph of graph Graph with NIdV nodes with an node renumbering.
Definition: subgraph.h:213
directed graph (TNGraph, TNEGraph), else graph is undirected TUNGraph
Definition: gbase.h:13
#define CAssert(Cond)
Definition: bd.h:302
int Len() const
Definition: shash.h:1121
PGraph GetEDatSubGraph(const PGraph &Graph, const TEdgeDat &EDat, const int &Cmp)
Returns a subgraph of graph Graph with edges where edge data matches the parameters.
Definition: subgraph.h:261
POutGraph ConvertESubGraph(const PInGraph &InGraph, const TIntV &EIdV, const bool &RenumberNodes=false)
Returns a subgraph of graph InGraph with EIdV edges with an optional node renumbering.
Definition: subgraph.h:416
void Shuffle(TRnd &Rnd)
Randomly shuffles the elements of the vector.
Definition: ds.h:1335
Definition: bd.h:196
bool Cmp(const int &RelOp, const TRec &Rec1, const TRec &Rec2)
Definition: bd.h:426
PGraph GetESubGraph(const PGraph &Graph, const TIntV &EIdV)
Returns a subgraph of graph Graph with EIdV edges.
Definition: subgraph.h:218
PGraph GetRndSubGraph(const PGraph &Graph, const int &NNodes)
Returns an induced random subgraph of graph Graph with NNodes nodes.
Definition: subgraph.h:454
network with data on nodes
Definition: gbase.h:15
POutGraph ConvertGraph(const PInGraph &InGraph, const bool &RenumberNodes=false)
Performs conversion of graph InGraph with an optional node renumbering.
Definition: subgraph.h:301
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:602