9 template <
class PGraph>
double GetClustCf(
const PGraph& Graph,
int SampleNodes=-1);
15 template <
class PGraph>
double GetClustCf(
const PGraph& Graph,
TFltPrV& DegToCCfV,
int SampleNodes=-1);
21 template <
class PGraph>
double GetClustCf(
const PGraph& Graph,
TFltPrV& DegToCCfV,
int64& ClosedTriadsX,
int64& OpenTriadsX,
int SampleNodes=-1);
25 template <
class PGraph>
double GetNodeClustCf(
const PGraph& Graph,
const int& NId);
38 template <
class PGraph>
int64 GetTriads(
const PGraph& Graph,
int SampleNodes=-1);
43 template <
class PGraph>
int64 GetTriads(
const PGraph& Graph,
int64& ClosedTriadsX,
int64& OpenTriadsX,
int SampleNodes);
49 template <
class PGraph>
void GetTriads(
const PGraph& Graph,
TIntTrV& NIdCOTriadV,
int SampleNodes=-1);
54 template <
class PGraph>
int GetTriadEdges(
const PGraph& Graph,
int SampleEdges=-1);
61 template <
class PGraph>
int GetNodeTriads(
const PGraph& Graph,
const int& NId);
69 template <
class PGraph>
int GetNodeTriads(
const PGraph& Graph,
const int& NId,
int& ClosedNTriadsX,
int& OpenNTriadsX);
79 template <
class PGraph>
80 int GetNodeTriads(
const PGraph& Graph,
const int& NId,
const TIntSet& GroupSet,
int& InGroupEdgesX,
int& InOutGroupEdgesX,
int& OutGroupEdgesX);
87 template<
class PGraph>
int GetCmnNbrs(
const PGraph& Graph,
const int& NId1,
const int& NId2);
89 template<
class PGraph>
int GetCmnNbrs(
const PGraph& Graph,
const int& NId1,
const int& NId2,
TIntV& NbrV);
91 template<
class PGraph>
int GetLen2Paths(
const PGraph& Graph,
const int& NId1,
const int& NId2);
95 template<
class PGraph>
int GetLen2Paths(
const PGraph& Graph,
const int& NId1,
const int& NId2,
TIntV& NbrV);
100 template <
class PGraph>
double GetClustCf(
const PGraph& Graph,
int SampleNodes) {
102 GetTriads(Graph, NIdCOTriadV, SampleNodes);
103 if (NIdCOTriadV.
Empty()) {
return 0.0; }
105 for (
int i = 0; i < NIdCOTriadV.
Len(); i++) {
106 const double OpenCnt = NIdCOTriadV[i].Val2()+NIdCOTriadV[i].Val3();
108 SumCcf += NIdCOTriadV[i].Val2() / OpenCnt; }
111 return SumCcf / double(NIdCOTriadV.
Len());
114 template <
class PGraph>
double GetClustCf(
const PGraph& Graph,
TFltPrV& DegToCCfV,
int SampleNodes) {
116 GetTriads(Graph, NIdCOTriadV, SampleNodes);
119 for (
int i = 0; i < NIdCOTriadV.
Len(); i++) {
120 const int D = NIdCOTriadV[i].Val2()+NIdCOTriadV[i].Val3();
121 const double Ccf = D!=0 ? NIdCOTriadV[i].Val2() / double(D) : 0.0;
122 TFltPr& SumCnt = DegSumCnt.
AddDat(Graph->GetNI(NIdCOTriadV[i].Val1).GetDeg());
128 DegToCCfV.
Gen(DegSumCnt.
Len(), 0);
129 for (
int d = 0; d < DegSumCnt.
Len(); d++) {
130 DegToCCfV.
Add(
TFltPr(DegSumCnt.
GetKey(d).
Val, double(DegSumCnt[d].Val1()/DegSumCnt[d].Val2())));
133 return SumCcf / double(NIdCOTriadV.
Len());
136 template <
class PGraph>
139 GetTriads(Graph, NIdCOTriadV, SampleNodes);
142 int64 closedTriads = 0;
143 int64 openTriads = 0;
144 for (
int i = 0; i < NIdCOTriadV.
Len(); i++) {
145 const int D = NIdCOTriadV[i].Val2()+NIdCOTriadV[i].Val3();
146 const double Ccf = D!=0 ? NIdCOTriadV[i].Val2() / double(D) : 0.0;
147 closedTriads += NIdCOTriadV[i].Val2;
148 openTriads += NIdCOTriadV[i].Val3;
149 TFltPr& SumCnt = DegSumCnt.
AddDat(Graph->GetNI(NIdCOTriadV[i].Val1).GetDeg());
155 DegToCCfV.
Gen(DegSumCnt.
Len(), 0);
156 for (
int d = 0; d < DegSumCnt.
Len(); d++) {
157 DegToCCfV.
Add(
TFltPr(DegSumCnt.
GetKey(d).
Val, DegSumCnt[d].Val1()/DegSumCnt[d].Val2()));
161 ClosedTriads = closedTriads/
int64(3);
162 OpenTriads = openTriads;
164 return SumCcf / double(NIdCOTriadV.
Len());
167 template <
class PGraph>
172 return (Open+Closed)==0 ? 0 : double(Open)/double(Open+Closed);
175 template <
class PGraph>
180 for (
int i = 0; i < NIdCOTriadV.
Len(); i++) {
181 const int D = NIdCOTriadV[i].Val2()+NIdCOTriadV[i].Val3();
182 const double CCf = D!=0 ? NIdCOTriadV[i].Val2() / double(D) : 0.0;
183 NIdCCfH.
AddDat(NIdCOTriadV[i].Val1, CCf);
187 template <
class PGraph>
189 int64 OpenTriads, ClosedTriads;
190 return GetTriads(Graph, ClosedTriads, OpenTriads, SampleNodes);
193 template <
class PGraph>
196 GetTriads(Graph, NIdCOTriadV, SampleNodes);
199 for (
int i = 0; i < NIdCOTriadV.
Len(); i++) {
200 closedTriads += NIdCOTriadV[i].Val2;
201 openTriads += NIdCOTriadV[i].Val3;
205 ClosedTriads =
int64(closedTriads/3);
206 OpenTriads =
int64(openTriads);
211 template <
class PGraph>
213 const bool IsDir = Graph->HasFlag(
gfDirected);
218 Graph->GetNIdV(NIdV);
220 if (SampleNodes == -1) {
221 SampleNodes = Graph->GetNodes(); }
222 NIdCOTriadV.
Clr(
false);
223 NIdCOTriadV.
Reserve(SampleNodes);
224 for (
int node = 0; node < SampleNodes; node++) {
225 typename PGraph::TObj::TNodeI NI = Graph->GetNI(NIdV[node]);
226 if (NI.GetDeg() < 2) {
227 NIdCOTriadV.
Add(
TIntTr(NI.GetId(), 0, 0));
232 for (
int e = 0; e < NI.GetOutDeg(); e++) {
233 if (NI.GetOutNId(e) != NI.GetId()) {
234 NbrH.
AddKey(NI.GetOutNId(e)); }
237 for (
int e = 0; e < NI.GetInDeg(); e++) {
238 if (NI.GetInNId(e) != NI.GetId()) {
239 NbrH.
AddKey(NI.GetInNId(e)); }
243 int OpenCnt=0, CloseCnt=0;
244 for (
int srcNbr = 0; srcNbr < NbrH.
Len(); srcNbr++) {
245 const typename PGraph::TObj::TNodeI SrcNode = Graph->GetNI(NbrH.
GetKey(srcNbr));
246 for (
int dstNbr = srcNbr+1; dstNbr < NbrH.
Len(); dstNbr++) {
247 const int dstNId = NbrH.
GetKey(dstNbr);
248 if (SrcNode.IsNbrNId(dstNId)) { CloseCnt++; }
253 NIdCOTriadV.
Add(
TIntTr(NI.GetId(), CloseCnt, OpenCnt));
258 template <
class PGraph>
260 const bool IsDir = Graph->HasFlag(
gfDirected);
263 for(
typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
265 for (
int e = 0; e < NI.GetOutDeg(); e++) {
266 if (NI.GetOutNId(e) != NI.GetId()) {
267 NbrH.
AddKey(NI.GetOutNId(e)); }
270 for (
int e = 0; e < NI.GetInDeg(); e++) {
271 if (NI.GetInNId(e) != NI.GetId()) {
272 NbrH.
AddKey(NI.GetInNId(e)); }
275 for (
int e = 0; e < NI.GetOutDeg(); e++) {
276 if (!IsDir && NI.GetId()<NI.GetOutNId(e)) {
continue; }
277 const typename PGraph::TObj::TNodeI SrcNode = Graph->GetNI(NI.GetOutNId(e));
279 for (
int e1 = 0; e1 < SrcNode.GetOutDeg(); e1++) {
280 if (NbrH.
IsKey(SrcNode.GetOutNId(e1))) { Triad=
true;
break; }
282 if (IsDir && ! Triad) {
283 for (
int e1 = 0; e1 < SrcNode.GetInDeg(); e1++) {
284 if (NbrH.
IsKey(SrcNode.GetInNId(e1))) { Triad=
true;
break; }
287 if (Triad) { TriadEdges++; }
294 template <
class PGraph>
296 int ClosedTriads=0, OpenTriads=0;
301 template <
class PGraph>
302 int GetNodeTriads(
const PGraph& Graph,
const int& NId,
int& ClosedTriads,
int& OpenTriads) {
303 const typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
304 ClosedTriads=0; OpenTriads=0;
305 if (NI.GetDeg() < 2) {
return 0; }
308 for (
int e = 0; e < NI.GetOutDeg(); e++) {
309 if (NI.GetOutNId(e) != NI.GetId()) {
310 NbrSet.
AddKey(NI.GetOutNId(e)); }
313 for (
int e = 0; e < NI.GetInDeg(); e++) {
314 if (NI.GetInNId(e) != NI.GetId()) {
315 NbrSet.AddKey(NI.GetInNId(e)); }
319 for (
int srcNbr = 0; srcNbr < NbrSet.Len(); srcNbr++) {
320 const typename PGraph::TObj::TNodeI SrcNode = Graph->GetNI(NbrSet.GetKey(srcNbr));
321 for (
int dstNbr = srcNbr+1; dstNbr < NbrSet.Len(); dstNbr++) {
322 const int dstNId = NbrSet.GetKey(dstNbr);
323 if (SrcNode.IsNbrNId(dstNId)) { ClosedTriads++; }
324 else { OpenTriads++; }
334 template <
class PGraph>
335 int GetNodeTriads(
const PGraph& Graph,
const int& NId,
const TIntSet& GroupSet,
int& InGroupEdges,
int& InOutGroupEdges,
int& OutGroupEdges) {
336 const typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
337 const bool IsDir = Graph->HasFlag(
gfDirected);
338 InGroupEdges=0; InOutGroupEdges=0; OutGroupEdges=0;
339 if (NI.GetDeg() < 2) {
return 0; }
342 for (
int e = 0; e < NI.GetOutDeg(); e++) {
343 if (NI.GetOutNId(e) != NI.GetId()) {
344 NbrSet.
AddKey(NI.GetOutNId(e)); }
347 for (
int e = 0; e < NI.GetInDeg(); e++) {
348 if (NI.GetInNId(e) != NI.GetId()) {
349 NbrSet.AddKey(NI.GetInNId(e)); }
353 for (
int srcNbr = 0; srcNbr < NbrSet.Len(); srcNbr++) {
354 const int NbrId = NbrSet.GetKey(srcNbr);
355 const bool NbrIn = GroupSet.
IsKey(NbrId);
356 const typename PGraph::TObj::TNodeI SrcNode = Graph->GetNI(NbrId);
357 for (
int dstNbr = srcNbr+1; dstNbr < NbrSet.Len(); dstNbr++) {
358 const int DstNId = NbrSet.GetKey(dstNbr);
359 if (SrcNode.IsNbrNId(DstNId)) {
360 bool DstIn = GroupSet.
IsKey(DstNId);
361 if (NbrIn && DstIn) { InGroupEdges++; }
362 else if (NbrIn || DstIn) { InOutGroupEdges++; }
363 else { OutGroupEdges++; }
371 template <
class PGraph>
374 for (
typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
376 TriadCntH.
AddDat(Triads) += 1;
382 template<
class PGraph>
383 int GetCmnNbrs(
const PGraph& Graph,
const int& NId1,
const int& NId2) {
389 template<
class PGraph>
391 if (! Graph->IsNode(NId1) || ! Graph->IsNode(NId2)) { NbrV.
Clr(
false);
return 0; }
392 typename PGraph::TObj::TNodeI NI1 = Graph->GetNI(NId1);
393 typename PGraph::TObj::TNodeI NI2 = Graph->GetNI(NId2);
396 TIntSet NSet1(NI1.GetDeg()), NSet2(NI2.GetDeg());
397 for (
int i = 0; i < NI1.GetDeg(); i++) {
398 const int nid = NI1.GetNbrNId(i);
399 if (nid!=NId1 && nid!=NId2) {
402 for (
int i = 0; i < NI2.GetDeg(); i++) {
403 const int nid = NI2.GetNbrNId(i);
404 if (NSet1.IsKey(nid)) {
414 if (! Graph->IsNode(NId1) || ! Graph->IsNode(NId2)) { NbrV.Clr(
false);
return 0; }
423 if (j < NI2.
GetDeg() && nid==NI2.
GetNbrNId(j) && nid!=NId1 && nid!=NId2) {
424 IAssert(NbrV.Empty() || NbrV.Last() < nid);
435 template<
class PGraph>
436 int GetLen2Paths(
const PGraph& Graph,
const int& NId1,
const int& NId2) {
443 template<
class PGraph>
445 const typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId1);
448 for (
int e = 0; e < NI.GetOutDeg(); e++) {
449 const typename PGraph::TObj::TNodeI MidNI = Graph->GetNI(NI.GetOutNId(e));
450 if (MidNI.IsOutNId(NId2)) {
451 NbrV.
Add(MidNI.GetId());
462 template <
class PGraph>
470 double GetC(
const int& ConstraintN)
const {
return NodePrCH[ConstraintN]; }
472 double GetEdgeC(
const int& NId1,
const int& NId2)
const;
473 double GetNodeC(
const int& NId)
const;
481 template <
class PGraph>
489 template <
class PGraph>
491 if (NodePrCH.IsKey(
TIntPr(NId1, NId2))) {
492 return NodePrCH.GetDat(
TIntPr(NId1, NId2)); }
497 template <
class PGraph>
499 typename PGraph::TObj::TNodeI NI1 = Graph->GetNI(NId);
500 if (NI1.GetOutDeg() == 0) {
return 0.0; }
502 for (
int k = 0; k<NI1.GetOutDeg(); k++) {
503 KeyId = NodePrCH.GetKeyId(
TIntPr(NI1.GetId(), NI1.GetOutNId(k)));
504 if (KeyId > -1) {
break; }
506 if (KeyId < 0) {
return 0.0; }
507 double Constraint = NodePrCH[KeyId];
508 for (
int i = KeyId-1; i >-1 && NodePrCH.GetKey(i).Val1()==NId; i--) {
509 Constraint += NodePrCH[i];
511 for (
int i = KeyId+1; i < NodePrCH.Len() && NodePrCH.GetKey(i).Val1()==NId; i++) {
512 Constraint += NodePrCH[i];
517 template <
class PGraph>
519 if (NId1==NId2 || NodePrCH.IsKey(
TIntPr(NId1, NId2))) {
522 typename PGraph::TObj::TNodeI NI1 = Graph->GetNI(NId1);
523 double Constraint = 0.0;
524 if (NI1.IsOutNId(NId2)) {
525 Constraint += 1.0/(double) NI1.GetOutDeg();
527 const double SrcC = 1.0/(double) NI1.GetOutDeg();
528 for (
int e = 0; e < NI1.GetOutDeg(); e++) {
529 const int MidNId = NI1.GetOutNId(e);
530 if (MidNId == NId1 || MidNId == NId2) {
continue; }
531 const typename PGraph::TObj::TNodeI MidNI = Graph->GetNI(MidNId);
532 if (MidNI.IsOutNId(NId2)) {
533 Constraint += SrcC * (1.0/(double)MidNI.GetOutDeg());
536 if (Constraint==0) {
return; }
538 NodePrCH.AddDat(
TIntPr(NId1, NId2), Constraint);
541 template <
class PGraph>
544 for (
typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
545 AddConstraint(EI.GetSrcNId(), EI.GetDstNId());
546 AddConstraint(EI.GetDstNId(), EI.GetSrcNId());
549 for (
typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
550 for (
int i = 0; i < NI.GetDeg(); i++) {
551 const int NId1 = NI.GetNbrNId(i);
552 for (
int j = 0; j < NI.GetDeg(); j++) {
553 const int NId2 = NI.GetNbrNId(j);
554 AddConstraint(NId1, NId2);
558 NodePrCH.SortByKey();
562 template <
class PGraph>
564 typename PGraph::TObj::TNodeI StartNI = Graph->GetNI(NId);
566 for (
int e = 0; e < StartNI.GetOutDeg(); e++) {
567 typename PGraph::TObj::TNodeI MidNI = Graph->GetNI(StartNI.GetOutNId(e));
568 AddConstraint(NId, MidNI.GetId());
569 for (
int i = 0; i < MidNI.GetOutDeg(); i++) {
570 const int EndNId = MidNI.GetOutNId(i);
571 if (! SeenSet.
IsKey(EndNId)) {
572 AddConstraint(NId, EndNId);
579 template <
class PGraph>
581 printf(
"Edge network constraint: (%d, %d)\n", Graph->GetNodes(), Graph->GetEdges());
582 for (
int e = 0; e < NodePrCH.Len(); e++) {
583 printf(
" %4d %4d : %f\n", NodePrCH.GetKey(e).Val1(), NodePrCH.GetKey(e).Val2(), NodePrCH[e].Val);
590 template <
class PGraph>
600 NetConstraint.
Dump();
601 printf(
"middle node network constraint: %f\n", NetConstraint.
GetNodeC(0));
void Clr(const bool &DoDel=true, const int &NoDelLim=-1)
static const T & Mn(const T &LVal, const T &RVal)
TPair< TInt, TInt > TIntPr
int64 GetTriads(const PGraph &Graph, int64 &ClosedTriads, int64 &OpenTriads, int SampleNodes=-1)
Computes the number of Closed and Open triads.
double GetNodeClustCf(const PGraph &Graph, const int &NId)
Returns clustering coefficient of a particular node.
int GetLen2Paths(const PGraph &Graph, const int &NId1, const int &NId2)
Returns the number of length 2 directed paths between a pair of nodes NId1, NId2 (NId1 –> U –> NId2...
int AddNode(int NId=-1)
Adds a node of ID NId to the graph.
TSizeTy Len() const
Returns the number of elements in the vector.
Node iterator. Only forward iteration (operator++) is supported.
int GetCmnNbrs< PUNGraph >(const PUNGraph &Graph, const int &NId1, const int &NId2, TIntV &NbrV)
static double Sqr(const double &x)
TNetConstraint(const PGraph &GraphPt, const bool &CalcaAll=true)
bool IsKey(const TKey &Key) const
const TKey & GetKey(const int &KeyId) const
bool Empty() const
Tests whether the vector is empty.
have explicit edges (multigraph): TNEGraph, TNodeEdgeNet
int GetDeg() const
Returns degree of the current node.
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
void Sort(const bool &Asc=true)
Sorts the elements of the vector.
#define HasGraphFlag(TGraph, Flag)
For quick testing of the properties of the graph/network object (see TGraphFlag). ...
unsigned long long uint64
void AddConstraint(const int &NId1, const int &NId2)
double GetNodeC(const int &NId) const
static PUNGraph New()
Static constructor that returns a pointer to the graph. Call: PUNGraph Graph = TUNGraph::New().
int AddKey(const TKey &Key)
int GetNodeTriads(const PGraph &Graph, const int &NId)
Returns the number of undirected triads a node NId participates in.
double GetC(const int &ConstraintN) const
TPair< TFlt, TFlt > TFltPr
int AddEdge(const int &SrcNId, const int &DstNId)
Adds an edge between node IDs SrcNId and DstNId to the graph.
directed graph (TNGraph, TNEGraph), else graph is undirected TUNGraph
double GetEdgeC(const int &NId1, const int &NId2) const
int GetTriadEdges(const PGraph &Graph, int SampleEdges=-1)
Counts the number of edges that participate in at least one triad.
void Shuffle(TRnd &Rnd)
Randomly shuffles the elements of the vector.
void GetTriadParticip(const PGraph &Graph, TIntPrV &TriadCntV)
Triangle Participation Ratio: For each node counts how many triangles it participates in and then ret...
void GetKeyDatPrV(TVec< TPair< TKey, TDat > > &KeyDatPrV) const
double GetClustCf(const PGraph &Graph, int SampleNodes=-1)
Computes the average clustering coefficient as defined in Watts and Strogatz, Collective dynamics of ...
int GetNbrNId(const int &NodeN) const
Returns ID of NodeN-th neighboring node.
void Clr(const bool &DoDel=true, const int &NoDelLim=-1, const bool &ResetDat=true)
TIntPr GetNodePr(const int &ConstraintN) const
TTriple< TInt, TInt, TInt > TIntTr
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements.
void Reserve(const TSizeTy &_MxVals)
Reserves enough memory for the vector to store _MxVals elements.
THash< TIntPr, TFlt > NodePrCH
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
TDat & AddDat(const TKey &Key)
int GetCmnNbrs(const PGraph &Graph, const int &NId1, const int &NId2)
Returns a number of shared neighbors between a pair of nodes NId1 and NId2.
const TKey & GetKey(const int &KeyId) const