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