///////////////////////////////////////////////// // Trawling the web for emerging communities // graph, left points to right TTrawling::TTrawling(const PNGraph& Graph, const int& MinSupport) : MinSup(MinSupport) { TIntH ItemCntH; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { IAssert(NI.GetOutDeg()==0 || NI.GetInDeg()==0); // edges only point from left to right if (NI.GetOutDeg()==0) { continue; } for (int e = 0; e < NI.GetOutDeg(); e++) { ItemCntH.AddDat(NI.GetOutNId(e)) += 1; } } TIntV RightV; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { IAssert(NI.GetOutDeg()==0 || NI.GetInDeg()==0); // edges only point from left to right if (NI.GetOutDeg()==0) { continue; } RightV.Clr(false); for (int e = 0; e < NI.GetOutDeg(); e++) { const int itm = NI.GetOutNId(e); // only include items that already are above minimum support if (ItemCntH.GetDat(itm) >= MinSup) { RightV.Add(itm); } } if (! RightV.Empty()) { NIdSetH.AddDat(NI.GetId(), RightV); } } // for (int n = 0; n < NIdSetH.Len(); n++) { const TIntV& Set = NIdSetH[n]; for (int s = 0; s < Set.Len(); s++) { SetNIdH.AddDat(Set[s]).Add(n); } } }
double DirectedModularity(PNGraph& graph, std::vector<int>& communities) { if (graph->GetNodes() != communities.size()) { throw std::logic_error("Number of nodes does not match community size."); } int num_edges = graph->GetEdges(); double score = 0.0; int num_unique = 10; std::map<int, double> outdeg_sums; std::map<int, double> indeg_sums; for (TNGraph::TNodeI node = graph->BegNI(); node < graph->EndNI(); node++) { int comm = communities[node.GetId()]; outdeg_sums[comm] += node.GetOutDeg(); indeg_sums[comm] += node.GetInDeg(); } for (auto& kv : outdeg_sums) { score -= (kv.second / num_edges) * indeg_sums[kv.first]; } for (TNGraph::TNodeI node = graph->BegNI(); node < graph->EndNI(); node++) { int node_ID = node.GetId(); for (int e = 0; e < node.GetOutDeg(); ++e) { int nbr = node.GetOutNId(e); if (communities[node_ID] == communities[nbr]) { score += 1.0; } } } return score / num_edges; }
void TSubGraphsEnum::RecurBfs1(const int& NId, const int& Depth) { if (Depth == 0) { TIntPrV EdgeV; EdgeH.GetKeyV(EdgeV); EdgeV.Sort(); SgV.Add(EdgeV); return; } const TNGraph::TNodeI NI = NGraph ->GetNI(NId); for (int e = 0; e < NI.GetOutDeg(); e++) { const TIntPr Edge(NId, NI.GetOutNId(e)); if (! EdgeH.IsKey(Edge)) { EdgeH.AddKey(Edge); RecurBfs1(NI.GetOutNId(e), Depth-1); EdgeH.DelKey(Edge); } } for (int e = 0; e < NI.GetInDeg(); e++) { const TIntPr Edge(NI.GetInNId(e), NId); if (! EdgeH.IsKey(Edge)) { EdgeH.AddKey(Edge); RecurBfs1(NI.GetInNId(e), Depth-1); EdgeH.DelKey(Edge); } } }
void TGraphCascade::PruneGraph() { // iterate over nodes int Nodes = NodeNmIdH.Len(); TIntV NodeIdV; NodeNmIdH.GetDatV(NodeIdV); TStrV NodeNmV; NodeNmIdH.GetKeyV(NodeNmV); for (int NodeN = 0; NodeN < Nodes; NodeN++) { int NodeId = NodeIdV[NodeN]; if (!EnabledNodeIdH.IsKey(NodeId)) { // if a node is not enabled: // - connect its parents to its children TNGraph::TNodeI NI = Graph.GetNI(NodeId); for (int ParentN = 0; ParentN < NI.GetInDeg(); ParentN++) { for (int ChildN = 0; ChildN < NI.GetOutDeg(); ChildN++) { if (!Graph.IsEdge(NI.GetInNId(ParentN), NI.GetOutNId(ChildN))) { Graph.AddEdge(NI.GetInNId(ParentN), NI.GetOutNId(ChildN)); } } } //printf("deleting node %s %d\n", NodeNmV[NodeN].CStr(), NodeId); // - delete it (deletes edges) Graph.DelNode(NodeId); } } // generate search sequence from sinks to sources TopologicalSort(NIdSweep); //Print(NIdSweep); }
// burn each link independently (forward with FwdBurnProb, backward with BckBurnProb) void TForestFire::BurnExpFire() { const double OldFwdBurnProb = FwdBurnProb; const double OldBckBurnProb = BckBurnProb; const int NInfect = InfectNIdV.Len(); const TNGraph& G = *Graph; TIntH BurnedNIdH; // burned nodes TIntV BurningNIdV = InfectNIdV; // currently burning nodes TIntV NewBurnedNIdV; // nodes newly burned in current step bool HasAliveNbrs; // has unburned neighbors int NBurned = NInfect, NDiedFire=0; for (int i = 0; i < InfectNIdV.Len(); i++) { BurnedNIdH.AddDat(InfectNIdV[i]); } NBurnedTmV.Clr(false); NBurningTmV.Clr(false); NewBurnedTmV.Clr(false); for (int time = 0; ; time++) { NewBurnedNIdV.Clr(false); // for each burning node for (int node = 0; node < BurningNIdV.Len(); node++) { const int& BurningNId = BurningNIdV[node]; const TNGraph::TNodeI Node = G.GetNI(BurningNId); HasAliveNbrs = false; NDiedFire = 0; // burn forward links (out-links) for (int e = 0; e < Node.GetOutDeg(); e++) { const int OutNId = Node.GetOutNId(e); if (! BurnedNIdH.IsKey(OutNId)) { // not yet burned HasAliveNbrs = true; if (Rnd.GetUniDev() < FwdBurnProb) { BurnedNIdH.AddDat(OutNId); NewBurnedNIdV.Add(OutNId); NBurned++; } } } // burn backward links (in-links) if (BckBurnProb > 0.0) { for (int e = 0; e < Node.GetInDeg(); e++) { const int InNId = Node.GetInNId(e); if (! BurnedNIdH.IsKey(InNId)) { // not yet burned HasAliveNbrs = true; if (Rnd.GetUniDev() < BckBurnProb) { BurnedNIdH.AddDat(InNId); NewBurnedNIdV.Add(InNId); NBurned++; } } } } if (! HasAliveNbrs) { NDiedFire++; } } NBurnedTmV.Add(NBurned); NBurningTmV.Add(BurningNIdV.Len() - NDiedFire); NewBurnedTmV.Add(NewBurnedNIdV.Len()); //BurningNIdV.AddV(NewBurnedNIdV); // node is burning eternally BurningNIdV.Swap(NewBurnedNIdV); // node is burning just 1 time step if (BurningNIdV.Empty()) break; FwdBurnProb = FwdBurnProb * ProbDecay; BckBurnProb = BckBurnProb * ProbDecay; } BurnedNIdV.Gen(BurnedNIdH.Len(), 0); for (int i = 0; i < BurnedNIdH.Len(); i++) { BurnedNIdV.Add(BurnedNIdH.GetKey(i)); } FwdBurnProb = OldFwdBurnProb; BckBurnProb = OldBckBurnProb; }
void TempMotifCounter::GetAllNeighbors(int node, TIntV& nbrs) { nbrs = TIntV(); TNGraph::TNodeI NI = static_graph_->GetNI(node); for (int i = 0; i < NI.GetOutDeg(); i++) { nbrs.Add(NI.GetOutNId(i)); } for (int i = 0; i < NI.GetInDeg(); i++) { int nbr = NI.GetInNId(i); if (!NI.IsOutNId(nbr)) { nbrs.Add(nbr); } } }
uint64 TGraphCascade::SampleNodeTimestamp(const int& NodeId, const uint64& Time, const int& SampleN) { if (Timestamps.GetDat(NodeId) > 0) { return Timestamps.GetDat(NodeId); } else if (Sample.GetDat(NodeId).Len() > SampleN) { return Sample.GetDat(NodeId)[SampleN]; } TNGraph::TNodeI NI = Graph.GetNI(NodeId); int Parents = NI.GetInDeg(); if (Parents == 0) { throw TExcept::New("Root node has not been observed yet - cannot run simulation"); } uint64 MaxParentTime = 0; for (int ParentN = 0; ParentN < Parents; ParentN++) { int ParentId = NI.GetInNId(ParentN); // check if parent was observed or has samples available if (Timestamps.GetDat(ParentId) == 0 && Sample.GetDat(ParentId).Empty()) { throw TExcept::New("Parent node unobserved and sample not available! Missing data or bad graph"); } // get SampleN from each parent uint64 ParentTime = SampleNodeTimestamp(ParentId, Time, SampleN); // update max MaxParentTime = (MaxParentTime > ParentTime) ? MaxParentTime : ParentTime; } int TimeDiff = (int)(((int64)(Time)-(int64)(MaxParentTime)) / TimeUnit); int MinDuration = MAX(TimeDiff, 0); if (!CDF.IsKey(NodeId)) { // model is missing and the node has not been observed // this probably indicates that the node is always missing // model its duration as 0, so it should have been observed after // its last parent return MaxParentTime; } TFltV& NodeCDF = CDF.GetDat(NodeId); int MaxDuration = NodeCDF.Len(); if (TimeDiff > MaxDuration) { return Time + 1; } // out of model bounds double CDFRemain = MinDuration == 0 ? 1.0 : (1.0 - NodeCDF[MinDuration - 1]); if (CDFRemain < 1e-16) { return Time + 1; } // numerically out of model bounds // inverse cdf sample, conditioned on elapsed time double Samp = (1.0 - CDFRemain) + Rnd.GetUniDev() * CDFRemain; // find the first CDF bin that exceeds Samp // SPEEDUP possible with bisection int BinIdx = MaxDuration; for (int BinN = MinDuration; BinN < MaxDuration; BinN++) { if (NodeCDF[BinN] >= Samp) { BinIdx = BinN; break; } } // compute time return MaxParentTime + (uint64)((BinIdx)* TimeUnit); }
int main(int argc, char* argv[]) { // create a graph and save it { PNGraph Graph = TNGraph::New(); for (int i = 0; i < 10; i++) { Graph->AddNode(i); } for (int i = 0; i < 10; i++) { Graph->AddEdge(i, TInt::Rnd.GetUniDevInt(10)); } TSnap::SaveEdgeList(Graph, "graph.txt", "Edge list format"); } // load a graph PNGraph Graph; Graph = TSnap::LoadEdgeList<PNGraph>("graph.txt", 0, 1); // traverse nodes for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { printf("NodeId: %d, InDegree: %d, OutDegree: %d\n", NI.GetId(), NI.GetInDeg(), NI.GetOutDeg()); printf("OutNodes: "); for (int e = 0; e < NI.GetOutDeg(); e++) { printf(" %d", NI.GetOutNId(e)); } printf("\nInNodes: "); for (int e = 0; e < NI.GetInDeg(); e++) { printf(" %d", NI.GetInNId(e)); } printf("\n\n"); } // graph statistic TSnap::PrintInfo(Graph, "Graph info"); PNGraph MxWcc = TSnap::GetMxWcc(Graph); TSnap::PrintInfo(MxWcc, "Largest Weakly connected component"); // random graph PNGraph RndGraph = TSnap::GenRndGnm<PNGraph>(100, 1000); TGStat GraphStat(RndGraph, TSecTm(1), TGStat::AllStat(), "Gnm graph"); GraphStat.PlotAll("RndGraph", "Random graph on 1000 nodes"); // Forest Fire graph { TFfGGen ForestFire(false, 1, 0.35, 0.30, 1.0, 0.0, 0.0); ForestFire.GenGraph(100); PNGraph FfGraph = ForestFire.GetGraph(); } // network TPt<TNodeEDatNet<TStr, TStr> > Net = TNodeEDatNet<TStr, TStr>::New(); Net->AddNode(0, "zero"); Net->AddNode(1, "one"); Net->AddEdge(0, 1, "zero to one"); return 0; }
// improved version void GetMergeSortedV1(TIntV& NeighbourV, TNGraph::TNodeI NI) { int j = 0; int k = 0; int prev = -1; int indeg = NI.GetInDeg(); int outdeg = NI.GetOutDeg(); //while (j < NI.GetInDeg() && k < NI.GetOutDeg()) { if (indeg > 0 && outdeg > 0) { int v1 = NI.GetInNId(j); int v2 = NI.GetOutNId(k); while (1) { if (v1 <= v2) { if (prev != v1) { NeighbourV.Add(v1); prev = v1; } j += 1; if (j >= indeg) { break; } v1 = NI.GetInNId(j); } else { if (prev != v2) { NeighbourV.Add(v2); prev = v2; } k += 1; if (k >= outdeg) { break; } v2 = NI.GetOutNId(k); } } } while (j < indeg) { int v = NI.GetInNId(j); if (prev != v) { NeighbourV.Add(v); prev = v; } j += 1; } while (k < outdeg) { int v = NI.GetOutNId(k); if (prev != v) { NeighbourV.Add(v); prev = v; } k += 1; } }
void MergeNbrs(TIntV* NeighbourV, TIntV* list1, TNGraph::TNodeI NI2) { int j = 0; int k = 0; int prev = -1; int lenA = list1->Len(); int lenB = NI2.GetInDeg(); if (lenA > 0 && lenB > 0) { int v1 = (*list1)[j]; int v2 = NI2.GetInNId(k); while (1) { if (v1 <= v2) { if (prev != v1) { NeighbourV->Add(v1); prev = v1; } j += 1; if (j >= lenA) { break; } v1 = (*list1)[j]; } else { if (prev != v2) { NeighbourV->Add(v2); prev = v2; } k += 1; if (k >= lenB) { break; } v2 = NI2.GetInNId(k); } } } while (j < lenA) { int v = (*list1)[j]; if (prev != v) { NeighbourV->Add(v); prev = v; } j += 1; } while (k < lenB) { int v = NI2.GetInNId(k); if (prev != v) { NeighbourV->Add(v); prev = v; } k += 1; } }
void TGraphKey::TakeSig(const PNGraph& Graph, const int& MnSvdGraph, const int& MxSvdGraph) { const int Edges = Graph->GetEdges(); Nodes = Graph->GetNodes(); VariantId = 0; SigV.Gen(2+Nodes, 0); // degree sequence TIntPrV DegV(Nodes, 0); for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { DegV.Add(TIntPr(NodeI.GetInDeg(), NodeI.GetOutDeg())); } DegV.Sort(false); SigV.Add(TFlt(Nodes)); SigV.Add(TFlt(Edges)); for (int i = 0; i < DegV.Len(); i++) { SigV.Add(DegV[i].Val1()); SigV.Add(DegV[i].Val2()); } // singular values signature // it turns out that it is cheaper to do brute force isomorphism // checking than to calculate SVD and then check isomorphism if (Nodes >= MnSvdGraph && Nodes < MxSvdGraph) { // perform full SVD TFltVV AdjMtx(Nodes+1, Nodes+1); TFltV SngValV; TFltVV LSingV, RSingV; TIntH NodeIdH; // create adjecency matrix for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { NodeIdH.AddKey(NodeI.GetId()); } for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { const int NodeId = NodeIdH.GetKeyId(NodeI.GetId()) + 1; for (int e = 0; e < NodeI.GetOutDeg(); e++) { const int DstNId = NodeIdH.GetKeyId(NodeI.GetOutNId(e)) + 1; // no self edges if (NodeId != DstNId) AdjMtx.At(NodeId, DstNId) = 1; } } try { // can fail to converge but results seem to be good TSvd::Svd(AdjMtx, LSingV, SngValV, RSingV); } catch(...) { printf("\n***No SVD convergence: G(%d, %d): SngValV.Len():%d\n", Nodes(), Graph->GetEdges(), SngValV.Len()); } // round singular values SngValV.Sort(false); for (int i = 0; i < SngValV.Len(); i++) { SigV.Add(TMath::Round(SngValV[i], RoundTo)); } } //printf("SIG:\n"); for (int i = 0; i < SigV.Len(); i++) { printf("\t%f\n", SigV[i]); } SigV.Pack(); }
// initial version void GetMergeSortedV(TIntV& NeighbourV, TNGraph::TNodeI NI) { int ind, j, k; ind = j = k = 0; while (j < NI.GetInDeg() && k < NI.GetOutDeg()) { int v1 = NI.GetInNId(j); int v2 = NI.GetOutNId(k); if (v1 <= v2) { if ((ind == 0) || (NeighbourV[ind-1] != v1)) { NeighbourV.Add(v1); ind += 1; } j += 1; } else { if ((ind == 0) || (NeighbourV[ind-1] != v2)) { NeighbourV.Add(v2); ind += 1; } k += 1; } } while (j < NI.GetInDeg()) { int v = NI.GetInNId(j); if ((ind == 0) || (NeighbourV[ind-1] != v)) { NeighbourV.Add(v); ind += 1; } j += 1; } while (k < NI.GetOutDeg()) { int v = NI.GetOutNId(k); if ((ind == 0) || (NeighbourV[ind-1] != v)) { NeighbourV.Add(v); ind += 1; } k += 1; } }
// Rok #5 void GetMergeSortedV(TIntV& NeighbourV, TNGraph::TNodeI NI) { int j = 0; int k = 0; int prev = -1; while (j < NI.GetInDeg() && k < NI.GetOutDeg()) { int v1 = NI.GetInNId(j); int v2 = NI.GetOutNId(k); if (v1 <= v2) { if (prev != v1) { NeighbourV.Add(v1); prev = v1; } j += 1; } else { if (prev != v2) { NeighbourV.Add(v2); prev = v2; } k += 1; } } while (j < NI.GetInDeg()) { int v = NI.GetInNId(j); if (prev != v) { NeighbourV.Add(v); prev = v; } j += 1; } while (k < NI.GetOutDeg()) { int v = NI.GetOutNId(k); if (prev != v) { NeighbourV.Add(v); prev = v; } k += 1; } }
PJsonVal TGraphCascade::GetGraph() const { PJsonVal G = TJsonVal::NewObj(); for (TNGraph::TNodeI NI = Graph.BegNI(); NI < Graph.EndNI(); NI++) { TStr NodeNm = NodeIdNmH.GetDat(NI.GetId()); PJsonVal ParentsArr = TJsonVal::NewArr(); int InDeg = NI.GetInDeg(); for (int ParentN = 0; ParentN < InDeg; ParentN++) { TStr ParentNm = NodeIdNmH.GetDat(NI.GetInNId(ParentN)); ParentsArr->AddToArr(ParentNm); } G->AddToObj(NodeNm, ParentsArr); } return G; }
void plotParitialDegDistribution(const PNGraph& graph, std::vector<int>& nodeList) { std::map<int, int> inDegDistMap; std::map<int, int> outDegDistMap; for (int i = 0; i < nodeList.size(); ++i) { int curNodeId = nodeList[i]; if (!graph->IsNode(curNodeId)) continue; TNGraph::TNodeI ni = graph->GetNI(curNodeId); int curNodeInDeg = ni.GetInDeg(); if (inDegDistMap.find(curNodeInDeg) == inDegDistMap.end()) { inDegDistMap.insert(std::pair<int, int>(curNodeInDeg, 0)); } inDegDistMap[curNodeInDeg]++; int curNodeOutDeg = ni.GetOutDeg(); if (outDegDistMap.find(curNodeOutDeg) == outDegDistMap.end()) { outDegDistMap.insert(std::pair<int, int>(curNodeOutDeg, 0)); } outDegDistMap[curNodeOutDeg]++; } TFltPrV inDegDist; for (std::map<int, int>::iterator itr = inDegDistMap.begin(); itr != inDegDistMap.end(); itr++) { inDegDist.Add(TFltPr(itr->first, itr->second)); } TFltPrV outDegDist; for (std::map<int, int>::iterator itr = outDegDistMap.begin(); itr != outDegDistMap.end(); itr++) { outDegDist.Add(TFltPr(itr->first, itr->second)); } TGnuPlot plot1("inDegDistParitial", ""); plot1.AddPlot(inDegDist, gpwPoints, ""); plot1.SetScale(gpsLog10XY); plot1.SavePng(); TGnuPlot plot2("outDegDistParitial", ""); plot2.AddPlot(outDegDist, gpwPoints, ""); plot2.SetScale(gpsLog10XY); plot2.SavePng(); TGnuPlot plot3("DegDistParitial", ""); plot3.AddCmd("set key right top"); plot3.AddPlot(inDegDist, gpwPoints, "In Degree"); plot3.AddPlot(outDegDist, gpwPoints, "Out Degree"); plot3.SetScale(gpsLog10XY); plot3.SavePng(); }
void getInNeighborNodeIDs(const PNGraph& graph, int destNodeID, std::set<int>& nodeIdSet) { std::queue<int> q; q.push(destNodeID); nodeIdSet.insert(destNodeID); for (int level = 0; level < 2; ++level) { int levelCount = q.size(); for (int i = 0; i < levelCount; ++i) { int curNodeId = q.front(); q.pop(); // Scan neigbors; TNGraph::TNodeI curNode = graph->GetNI(curNodeId); int inDeg = curNode.GetInDeg(); for (int j = 0; j < inDeg; ++j) { int curNeighborNodeID = curNode.GetInNId(j); q.push(curNeighborNodeID); nodeIdSet.insert(curNeighborNodeID); } } } }
double TCascade::GetProb(const PNGraph& G) { double P = 0; for (int n = 0; n < Len(); n++) { const int DstNId = GetNode(n); const double DstTm = GetTm(DstNId); TNGraph::TNodeI NI = G->GetNI(DstNId); double MxProb = log(Eps); int BestParent = -1; for (int e = 0; e < NI.GetInDeg(); e++) { const int SrcNId = NI.GetInNId(e); if (IsNode(SrcNId) && GetTm(SrcNId) < DstTm) { const double Prob = log(TransProb(SrcNId, DstNId)); if (MxProb < Prob) { MxProb = Prob; BestParent = SrcNId; } } } NIdHitH.GetDat(DstNId).Parent = BestParent; P += MxProb; } return P; }
void TSubGraphsEnum::RecurBfs(const int& NId, const int& Depth, TSimpleGraph& PrevG) { if (Depth == 0) { TIntPrV& EdgeV = PrevG(); EdgeV.Sort(); for (int i = 1; i < EdgeV.Len(); i++) { if (EdgeV[i-1] == EdgeV[i]) { return; } } SgV.Add(PrevG); return; } const TNGraph::TNodeI NI = NGraph ->GetNI(NId); for (int e = 0; e < NI.GetOutDeg(); e++) { TSimpleGraph CurG = PrevG; CurG.AddEdge(NI.GetId(), NI.GetOutNId(e)); RecurBfs(NI.GetOutNId(e), Depth-1, CurG); } for (int e = 0; e < NI.GetInDeg(); e++) { TSimpleGraph CurG = PrevG; CurG.AddEdge(NI.GetInNId(e), NI.GetId()); RecurBfs(NI.GetInNId(e), Depth-1, CurG); } }
PNEANet KNNJaccard(PNGraph Graph, int K) { PNEANet KNN = TNEANet::New(); int sum_neighbors = 0; int ct; int end; end = Graph->GetNodes(); TIntV* Neighbors_old = new TIntV(); TIntV* Neighbors = new TIntV(); TIntV* temp; TIntV NIdV; Graph->GetNIdV (NIdV); int size = NIdV.Len(); for (int ind = 0; ind < size; ind++) { KNN->AddNode(NIdV[ind]); } KNN->AddFltAttrE("sim"); for (int ind = 0; ind < size; ind++) { TNGraph::TNodeI NI = Graph->GetNI(NIdV[ind]); if (NI.GetInDeg() > 0) { continue; } if (NI.GetOutDeg() == 0) { continue; } ct ++; TVec<TPair<TFlt, TInt> > TopK; for (int i = 0; i < K; i++) { TopK.Add(TPair<TFlt,TInt>(0.0, -1)); } Neighbors->Clr(false); Neighbors_old->Clr(false); for (int i = 0; i < NI.GetOutDeg(); i++) { TNGraph::TNodeI Inst_NI = Graph->GetNI(NI.GetOutNId(i)); MergeNbrs(Neighbors, Neighbors_old, Inst_NI); temp = Neighbors_old; temp->Clr(false); Neighbors_old = Neighbors; Neighbors = temp; } int num = Neighbors_old->Len(); sum_neighbors += num; //Swap neighbors and Neighbors_old temp = Neighbors_old; Neighbors_old = Neighbors; Neighbors = temp; for (int j = 0; j< Neighbors->Len(); j++) { TNGraph::TNodeI Auth_NI = Graph->GetNI((*Neighbors)[j]); float similarity = JaccardSim(NI, Auth_NI); if (TopK[K-1].GetVal1() < similarity) { int index = 0; for (int i = K-2; i >= 0; i--) if (TopK[i].GetVal1() < similarity) { TopK.SetVal(i+1, TopK[i]); } else { index = i+1; break; } TopK.SetVal(index, TPair<TFlt, TInt>(similarity, (*Neighbors)[j])); } } for (int i = 0; i < K; i++) { int EId = KNN->AddEdge(NI.GetId(), TopK[i].GetVal2()); KNN->AddFltAttrDatE(EId, TopK[i].GetVal1(), "sim"); } // if (ct%10000 == 0) // cout<<ct<<" avg neighbor degree = "<<sum_neighbors*1.0/ct<<" "<<currentDateTime()<<endl; } return KNN; }
PNEANet KNNJaccardParallel(PNGraph Graph,int K) { PNEANet KNN = TNEANet::New(); TIntV NIdV; Graph->GetNIdV (NIdV); int size = NIdV.Len(); for (int ind = 0; ind < size; ind++) { KNN->AddNode(NIdV[ind]); } KNN->AddFltAttrE("sim"); TVec<TVec<TPair<TFlt, TInt>, int >, int > TopKList; TVec<TVec<TPair<TFlt, TInt>, int >, int > ThTopK; // for each thread TIntV NodeList; TIntV ThNodeList;// for each thread int NumThreads = omp_get_max_threads(); omp_set_num_threads(NumThreads); #pragma omp parallel private(ThNodeList, ThTopK) { TIntV* Neighbors_old = new TIntV(); TIntV* Neighbors = new TIntV(); TIntV* temp; #pragma omp for schedule(dynamic,1000) for (int ind = 0; ind < size; ind++) { TNGraph::TNodeI NI = Graph->GetNI(NIdV[ind]); if (NI.GetInDeg() > 0) { continue; } if (NI.GetOutDeg() == 0) { continue; } TVec<TPair<TFlt, TInt>, int > TopK; for (int i = 0; i < K; i++) { TopK.Add(TPair<TFlt,TInt>(0.0, -1)); } Neighbors->Clr(false); Neighbors_old->Clr(false); for (int i = 0; i < NI.GetOutDeg(); i++) { TNGraph::TNodeI Inst_NI = Graph->GetNI(NI.GetOutNId(i)); MergeNbrs(Neighbors, Neighbors_old, Inst_NI); temp = Neighbors_old; temp->Clr(false); Neighbors_old = Neighbors; Neighbors = temp; } // Swap neighbors and Neighbors_old temp = Neighbors_old; Neighbors_old = Neighbors; Neighbors = temp; for(int j = 0; j< Neighbors->Len(); j++) { TNGraph::TNodeI Auth_NI = Graph->GetNI((*Neighbors)[j]); float similarity = JaccardSim(NI, Auth_NI); if (TopK[K-1].GetVal1() < similarity) { int index = 0; for (int i = K-2; i >= 0; i--) if (TopK[i].GetVal1() < similarity) { TopK.SetVal(i+1, TopK[i]); } else { index = i+1; break; } TopK.SetVal(index, TPair<TFlt, TInt>(similarity, (*Neighbors)[j])); } } ThTopK.Add(TopK); ThNodeList.Add(NIdV[ind]); // if (ct%10000 == 0) // cout<<ct<<" avg neighbor degree = "<<sum_neighbors*1.0/ct<<" "<<currentDateTime()<<endl; } #pragma omp critical { for (int j = 0; j < ThTopK.Len(); j++) { TopKList.Add(ThTopK[j]); NodeList.Add(ThNodeList[j]); } } } int size2 = NodeList.Len(); for (int i= 0; i < size2 ; i++) { for (int j = 0; j < K; j++) { if (TopKList[i][j].GetVal2() <= -1) { break; } int EId = KNN->AddEdge(NodeList[i], TopKList[i][j].GetVal2()); KNN->AddFltAttrDatE(EId, TopKList[i][j].GetVal1(), "sim"); } } return KNN; }
// Test node, edge creation TEST(TNGraph, ManipulateNodesEdges) { int NNodes = 10000; int NEdges = 100000; const char *FName = "test.graph.dat"; PNGraph Graph; PNGraph Graph1; PNGraph Graph2; int i; int n; int NCount; int x,y; int Deg, InDeg, OutDeg; Graph = TNGraph::New(); EXPECT_EQ(1,Graph->Empty()); // create the nodes for (i = 0; i < NNodes; i++) { Graph->AddNode(i); } EXPECT_EQ(0,Graph->Empty()); EXPECT_EQ(NNodes,Graph->GetNodes()); // create random edges NCount = NEdges; while (NCount > 0) { x = (long) (drand48() * NNodes); y = (long) (drand48() * NNodes); // Graph->GetEdges() is not correct for the loops (x == y), // skip the loops in this test if (x != y && !Graph->IsEdge(x,y)) { n = Graph->AddEdge(x, y); NCount--; } } EXPECT_EQ(NEdges,Graph->GetEdges()); EXPECT_EQ(0,Graph->Empty()); EXPECT_EQ(1,Graph->IsOk()); for (i = 0; i < NNodes; i++) { EXPECT_EQ(1,Graph->IsNode(i)); } EXPECT_EQ(0,Graph->IsNode(NNodes)); EXPECT_EQ(0,Graph->IsNode(NNodes+1)); EXPECT_EQ(0,Graph->IsNode(2*NNodes)); // nodes iterator NCount = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } EXPECT_EQ(NNodes,NCount); // edges per node iterator NCount = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { for (int e = 0; e < NI.GetOutDeg(); e++) { NCount++; } } EXPECT_EQ(NEdges,NCount); // edges iterator NCount = 0; for (TNGraph::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { NCount++; } EXPECT_EQ(NEdges,NCount); // node degree for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { Deg = NI.GetDeg(); InDeg = NI.GetInDeg(); OutDeg = NI.GetOutDeg(); EXPECT_EQ(Deg,InDeg+OutDeg); } // assignment Graph1 = TNGraph::New(); *Graph1 = *Graph; EXPECT_EQ(NNodes,Graph1->GetNodes()); EXPECT_EQ(NEdges,Graph1->GetEdges()); EXPECT_EQ(0,Graph1->Empty()); EXPECT_EQ(1,Graph1->IsOk()); // saving and loading { TFOut FOut(FName); Graph->Save(FOut); FOut.Flush(); } { TFIn FIn(FName); Graph2 = TNGraph::Load(FIn); } EXPECT_EQ(NNodes,Graph2->GetNodes()); EXPECT_EQ(NEdges,Graph2->GetEdges()); EXPECT_EQ(0,Graph2->Empty()); EXPECT_EQ(1,Graph2->IsOk()); // remove all the nodes and edges for (i = 0; i < NNodes; i++) { n = Graph->GetRndNId(); Graph->DelNode(n); } EXPECT_EQ(0,Graph->GetNodes()); EXPECT_EQ(0,Graph->GetEdges()); EXPECT_EQ(1,Graph->IsOk()); EXPECT_EQ(1,Graph->Empty()); Graph1->Clr(); EXPECT_EQ(0,Graph1->GetNodes()); EXPECT_EQ(0,Graph1->GetEdges()); EXPECT_EQ(1,Graph1->IsOk()); EXPECT_EQ(1,Graph1->Empty()); }
// Node selects N~geometric(1.0-FwdBurnProb)-1 out-links and burns them. Then same for in-links. // geometirc(p) has mean 1/(p), so for given FwdBurnProb, we burn 1/(1-FwdBurnProb) void TForestFire::BurnGeoFire() { const double OldFwdBurnProb = FwdBurnProb; const double OldBckBurnProb = BckBurnProb; const int& NInfect = InfectNIdV.Len(); const TNGraph& G = *Graph; TIntH BurnedNIdH; // burned nodes TIntV BurningNIdV = InfectNIdV; // currently burning nodes TIntV NewBurnedNIdV; // nodes newly burned in current step bool HasAliveInNbrs, HasAliveOutNbrs; // has unburned neighbors TIntV AliveNIdV; // NIds of alive neighbors int NBurned = NInfect, time; for (int i = 0; i < InfectNIdV.Len(); i++) { BurnedNIdH.AddDat(InfectNIdV[i]); } NBurnedTmV.Clr(false); NBurningTmV.Clr(false); NewBurnedTmV.Clr(false); for (time = 0;; time++) { NewBurnedNIdV.Clr(false); for (int node = 0; node < BurningNIdV.Len(); node++) { const int& BurningNId = BurningNIdV[node]; const TNGraph::TNodeI Node = G.GetNI(BurningNId); // find unburned links HasAliveOutNbrs = false; AliveNIdV.Clr(false); // unburned links for (int e = 0; e < Node.GetOutDeg(); e++) { const int OutNId = Node.GetOutNId(e); if (!BurnedNIdH.IsKey(OutNId)) { HasAliveOutNbrs = true; AliveNIdV.Add(OutNId); } } // number of links to burn (geometric coin). Can also burn 0 links const int BurnNFwdLinks = Rnd.GetGeoDev(1.0 - FwdBurnProb) - 1; if (HasAliveOutNbrs && BurnNFwdLinks > 0) { AliveNIdV.Shuffle(Rnd); for (int i = 0; i < TMath::Mn(BurnNFwdLinks, AliveNIdV.Len()); i++) { BurnedNIdH.AddDat(AliveNIdV[i]); NewBurnedNIdV.Add(AliveNIdV[i]); NBurned++; } } // backward links if (BckBurnProb > 0.0) { // find unburned links HasAliveInNbrs = false; AliveNIdV.Clr(false); for (int e = 0; e < Node.GetInDeg(); e++) { const int InNId = Node.GetInNId(e); if (!BurnedNIdH.IsKey(InNId)) { HasAliveInNbrs = true; AliveNIdV.Add(InNId); } } // number of links to burn (geometric coin). Can also burn 0 links const int BurnNBckLinks = Rnd.GetGeoDev(1.0 - BckBurnProb) - 1; if (HasAliveInNbrs && BurnNBckLinks > 0) { AliveNIdV.Shuffle(Rnd); for (int i = 0; i < TMath::Mn(BurnNBckLinks, AliveNIdV.Len()); i++) { BurnedNIdH.AddDat(AliveNIdV[i]); NewBurnedNIdV.Add(AliveNIdV[i]); NBurned++; } } } } NBurnedTmV.Add(NBurned); NBurningTmV.Add(BurningNIdV.Len()); NewBurnedTmV.Add(NewBurnedNIdV.Len()); // BurningNIdV.AddV(NewBurnedNIdV); // node is burning eternally BurningNIdV.Swap(NewBurnedNIdV); // node is burning just 1 time step if (BurningNIdV.Empty()) break; FwdBurnProb = FwdBurnProb * ProbDecay; BckBurnProb = BckBurnProb * ProbDecay; } BurnedNIdV.Gen(BurnedNIdH.Len(), 0); for (int i = 0; i < BurnedNIdH.Len(); i++) { BurnedNIdV.Add(BurnedNIdH.GetKey(i)); } FwdBurnProb = OldFwdBurnProb; BckBurnProb = OldBckBurnProb; }