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); } } }
// 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 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); }
int getNumOfIndependentPaths(const PNGraph& graph, int srcNodeID, int dstNodeID) { int ret = 0; while (true) { PNGraph bfsGraph = TSnap::GetBfsTree(graph, srcNodeID, true, false); if (!bfsGraph->IsNode(dstNodeID)) { return ret; } printf("%d hops\n", TSnap::GetShortPath(bfsGraph, srcNodeID, dstNodeID, true)); // Go back from dstNode to src int itrNodeId = dstNodeID; while (itrNodeId != srcNodeID) { TNGraph::TNodeI curNode = bfsGraph->GetNI(itrNodeId); int parentNodeId = curNode.GetInNId(0); // Delete Edges // graph->DelEdge(parentNodeId, itrNodeId, true); // Delete Node if (itrNodeId != dstNodeID && itrNodeId != srcNodeID) { graph->DelNode(itrNodeId); } itrNodeId = parentNodeId; } ++ret; } }
// 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); }
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); } }
// 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 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; }
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; }
// 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; }