PNGraph GetEgonet(const PNGraph& Graph, const int CtrNId, int& InEdges, int& OutEdges) { PNGraph NewGraphPt = TNGraph::New(); TNGraph& NewGraph = *NewGraphPt; NewGraph.AddNode(CtrNId); const TNGraph::TNodeI& CtrNode = Graph->GetNI(CtrNId); for (int i = 0; i < CtrNode.GetDeg(); ++i) { NewGraph.AddNode(CtrNode.GetNbrNId(i)); } InEdges = 0; OutEdges = 0; for (int i = 0; i < CtrNode.GetDeg(); ++i) { int NbrNId = CtrNode.GetNbrNId(i); const TNGraph::TNodeI& NbrNode = Graph->GetNI(NbrNId); for (int j = 0; j < NbrNode.GetInDeg(); ++j) { int NbrNbrNId = NbrNode.GetInNId(j); if (NewGraph.IsNode(NbrNbrNId)) { NewGraph.AddEdge(NbrNbrNId, NbrNId); } else { InEdges++; } } for (int j = 0; j < NbrNode.GetOutDeg(); ++j) { int NbrNbrNId = NbrNode.GetOutNId(j); if (!NewGraph.IsNode(NbrNbrNId)) { OutEdges++; } } } return NewGraphPt; }
bool CheckReciprocity(const PNGraph& G){ for (int i = 0; i < G->GetNodes(); i++){ if (G->GetNI(i).GetInDeg() != G->GetNI(i).GetOutDeg()) return false; } return true; }
void OnlyD3CEdges(PNGraph& dir_graph, PNGraph& d3c_graph, bool recip_edges) { // Add all of the nodes into the new graph for (TNGraph::TNodeI node = dir_graph->BegNI(); node < dir_graph->EndNI(); node++) { int curr_node = node.GetId(); d3c_graph->AddNode(curr_node); } for (TNGraph::TNodeI node = dir_graph->BegNI(); node < dir_graph->EndNI(); node++) { int curr_node = node.GetId(); auto curr_node_it = dir_graph->GetNI(curr_node); for (int out_edge = 0; out_edge < curr_node_it.GetOutDeg(); ++out_edge) { int out_node = curr_node_it.GetOutNId(out_edge); for (int in_edge = 0; in_edge < curr_node_it.GetInDeg(); ++in_edge) { int in_node = curr_node_it.GetInNId(in_edge); if (out_node == in_node && !recip_edges) { continue; } if (dir_graph->IsEdge(out_node, in_node) || recip_edges) { if (!d3c_graph->IsEdge(out_node, in_node)) { d3c_graph->AddEdge(out_node, in_node); } if (!d3c_graph->IsEdge(in_node, curr_node)) { d3c_graph->AddEdge(in_node, curr_node); } if (!d3c_graph->IsEdge(curr_node, out_node)) { d3c_graph->AddEdge(curr_node, out_node); } } } } } #ifdef _VERBOSE_ std::cout << "Original graph edge count: " << dir_graph->GetEdges() << std::endl << "D3C graph edge count: " << d3c_graph->GetEdges() << std::endl; #endif }
void OnlyD3CEdgesNoBack(PNGraph& dir_graph, PNGraph& d3c_graph) { // Add all of the nodes into the new graph for (TNGraph::TNodeI node = dir_graph->BegNI(); node < dir_graph->EndNI(); node++) { int curr_node = node.GetId(); d3c_graph->AddNode(curr_node); } for (TNGraph::TNodeI node = dir_graph->BegNI(); node < dir_graph->EndNI(); node++) { int curr_node = node.GetId(); auto curr_node_it = dir_graph->GetNI(curr_node); for (int out_edge = 0; out_edge < curr_node_it.GetOutDeg(); ++out_edge) { int out_node = curr_node_it.GetOutNId(out_edge); for (int in_edge = 0; in_edge < curr_node_it.GetInDeg(); ++in_edge) { int in_node = curr_node_it.GetInNId(in_edge); if (dir_graph->IsEdge(out_node, in_node) && out_node != in_node) { if (!d3c_graph->IsEdge(in_node, out_node) && !d3c_graph->IsEdge(curr_node, in_node) && !d3c_graph->IsEdge(out_node, curr_node)) { if (!d3c_graph->IsEdge(out_node, in_node)) { d3c_graph->AddEdge(out_node, in_node); } if (!d3c_graph->IsEdge(in_node, curr_node)) { d3c_graph->AddEdge(in_node, curr_node); } if (!d3c_graph->IsEdge(curr_node, out_node)) { d3c_graph->AddEdge(curr_node, out_node); } } } } } } }
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; } }
// RenumberNodes ... Renumber node ids in the subgraph to 0...N-1 PNGraph GetSubGraph(const PNGraph& Graph, const TIntV& NIdV, const bool& RenumberNodes) { //if (! RenumberNodes) { return TSnap::GetSubGraph(Graph, NIdV); } PNGraph NewGraphPt = TNGraph::New(); TNGraph& NewGraph = *NewGraphPt; NewGraph.Reserve(NIdV.Len(), -1); TIntSet NIdSet(NIdV.Len()); for (int n = 0; n < NIdV.Len(); n++) { if (Graph->IsNode(NIdV[n])) { NIdSet.AddKey(NIdV[n]); if (! RenumberNodes) { NewGraph.AddNode(NIdV[n]); } else { NewGraph.AddNode(NIdSet.GetKeyId(NIdV[n])); } } } if (! RenumberNodes) { for (int n = 0; n < NIdSet.Len(); n++) { const int SrcNId = NIdSet[n]; const TNGraph::TNodeI NI = Graph->GetNI(SrcNId); for (int edge = 0; edge < NI.GetOutDeg(); edge++) { const int OutNId = NI.GetOutNId(edge); if (NIdSet.IsKey(OutNId)) { NewGraph.AddEdge(SrcNId, OutNId); } } } } else { for (int n = 0; n < NIdSet.Len(); n++) { const int SrcNId = NIdSet[n]; const TNGraph::TNodeI NI = Graph->GetNI(SrcNId); for (int edge = 0; edge < NI.GetOutDeg(); edge++) { const int OutNId = NI.GetOutNId(edge); if (NIdSet.IsKey(OutNId)) { NewGraph.AddEdge(NIdSet.GetKeyId(SrcNId), NIdSet.GetKeyId(OutNId)); } } } } return NewGraphPt; }
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 TIncrementalClustering::KeepAtMostOneChildPerNode(PNGraph& G, TQuoteBase *QB, TDocBase *DB) { TIntSet::TIter EndNode = AffectedNodes.EndI(); for (TIntSet::TIter NodeId = AffectedNodes.BegI(); NodeId < EndNode; NodeId++) { TNGraph::TNodeI Node = G->GetNI(NodeId.GetKey()); TQuote SourceQuote; if (QB->GetQuote(Node.GetId(), SourceQuote)) { TInt NodeDegree = Node.GetOutDeg(); if (NodeDegree > 1) { TFlt MaxScore = 0; TInt MaxNodeId = 0; TIntV NodeV; // first pass: check to see if we are pointing to any old nodes - if so, they get higher // priority over the new ones for edge selection. bool ContainsOldNode = false; for (int i = 0; i < NodeDegree; ++i) { if (!NewQuotes.IsKey(Node.GetOutNId(i))) { ContainsOldNode = true; } } // modified edge selection: filter out new nodes if old ones exist. for (int i = 0; i < NodeDegree; ++i) { TInt CurNode = Node.GetOutNId(i); NodeV.Add(CurNode); TQuote DestQuote; if (QB->GetQuote(CurNode, DestQuote)) { TFlt EdgeScore = 0; if (!ContainsOldNode || !NewQuotes.IsKey(Node.GetOutNId(i))) { EdgeScore = ComputeEdgeScore(SourceQuote, DestQuote, DB); } if (EdgeScore > MaxScore) { MaxScore = EdgeScore; MaxNodeId = CurNode; } } } // remove all other edges, backwards to prevent indexing fail for (int i = 0; i < NodeV.Len(); i++) { if (NodeV[i] != MaxNodeId) { G->DelEdge(Node.GetId(), NodeV[i]); } } //printf("Out degree: %d out of %d\n", Node.GetOutDeg(), NodeDegree.Val); } } } fprintf(stderr, "finished deleting edges\n"); }
void TGraphEnumUtils::GetIndGraph(const PNGraph &G, const TIntV &sg, PNGraph &indG) { //Add nodes for(int i=0; i<sg.Len(); i++) indG->AddNode(sg[i]); //Add edges for(int i=0; i<sg.Len(); i++) { int nId = sg[i]; TNGraph::TNodeI nIt = G->GetNI(nId); // int deg = nIt.GetOutDeg(); for(int j=0; j<deg; j++) { int dstId = nIt.GetNbrNId(j); if(nId == dstId) continue; // if(indG->IsNode(dstId)) indG->AddEdge(nId, dstId); } } }
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[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("Inverse PageRank. Build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try const TStr Iput = Env.GetIfArgPrefixStr("-i:", "Input.txt", "Input File" ); const TStr Oput = Env.GetIfArgPrefixStr("-o:", "Output.txt", "Output File"); FILE* fpI = fopen(Iput.CStr(), "r"); FILE* fpO = fopen(Oput.CStr(), "w"); const double C = 0.85; const int MaxIter = 50; const double Eps = 1e-9; PNGraph Graph = TSnap::LoadEdgeList< PNGraph > (Iput); fprintf(fpO, "\nNodes: %d, Edges: %d\n\n", Graph->GetNodes(), Graph->GetEdges()); const int NNodes = Graph->GetNodes(); const double OneOver = (double) 1.0 / (double) NNodes; TIntFltH PRankH; PRankH.Gen(NNodes); for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) PRankH.AddDat(NI.GetId(), OneOver); TFltV TmpV(NNodes); for (int iter = 0; iter < MaxIter; iter++) { int j = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { TmpV[j] = 0; for (int e = 0; e < NI.GetOutDeg(); e++) { const int OutNId = NI.GetOutNId(e); const int InDeg = Graph->GetNI(OutNId).GetInDeg(); if (InDeg > 0) TmpV[j] += PRankH.GetDat(OutNId) / InDeg; } TmpV[j] = C * TmpV[j]; } for (int i = 0; i < PRankH.Len(); i++) PRankH[i] = TmpV[i]; /* double diff = 0, sum = 0, NewVal; for (int i = 0; i < TmpV.Len(); i++) sum += TmpV[i]; const double Leaked = (double) (1.0 - sum) / (double) NNodes; for (int i = 0; i < PRankH.Len(); i++) { NewVal = TmpV[i] + Leaked; diff += fabs(NewVal - PRankH[i]); PRankH[i] = NewVal; } if (diff < Eps) break; */ } fprintf(fpO, "Node ID\t\tInverse PageRank\n"); for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++){ int Id = NI.GetId(); double ipr = PRankH.GetDat(Id); fprintf(fpO, "%d\t\t\t%.5lf\n", Id, ipr); } Catch printf("\nRun Time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
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; }
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; }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("Trust Rank. Build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try const TStr Gnod = Env.GetIfArgPrefixStr("-g:", "Gnode.txt", "Good Nodes"); const TStr Bnod = Env.GetIfArgPrefixStr("-b:", "Bnode.txt", "Bad Nodes" ); const TStr Iput = Env.GetIfArgPrefixStr("-i:", "Input.txt", "Input File"); const TStr Oput = Env.GetIfArgPrefixStr("-o:", "Output.txt", "Output File"); const double C = 0.85; const int MaxIter = 50; const double Eps = 1e-9; FILE* fpO = fopen(Oput.CStr(), "w"); PNGraph Graph = TSnap::LoadEdgeList< PNGraph > (Iput); fprintf(fpO, "\nNodes: %d, Edges: %d\n\n", Graph->GetNodes(), Graph->GetEdges()); const int NNodes = Graph->GetNodes(); TIntFltH TRankH; TRankH.Gen(NNodes); int maxNId = 0, NId = 0, ret = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) maxNId = max(maxNId, NI.GetId()); TFltV initialTrustScore(maxNId + 1); for (int i = 0; i < initialTrustScore.Len(); i++) initialTrustScore[i] = 0.5; FILE* fpI = fopen(Gnod.CStr(), "r"); while (true) { ret = fscanf(fpI, "%d", &NId); if (ret == EOF) break; if (Graph->IsNode(NId)) initialTrustScore[NId] = 1.0; } fclose(fpI); fpI = fopen(Bnod.CStr(), "r"); while (true) { ret = fscanf(fpI, "%d", &NId); if (ret == EOF) break; if (Graph->IsNode(NId)) initialTrustScore[NId] = 0.0; } fclose(fpI); double Tot = 0.0; for(int i = 0; i < initialTrustScore.Len(); i++) Tot += initialTrustScore[i]; for(int i = 0; i < initialTrustScore.Len(); i++) initialTrustScore[i] /= Tot; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) TRankH.AddDat( NI.GetId(), initialTrustScore[NI.GetId()] ); TFltV TmpV(NNodes); for (int iter = 0; iter < MaxIter; iter++) { int j = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { TmpV[j] = 0; for (int e = 0; e < NI.GetOutDeg(); e++) { const int OutNId = NI.GetOutNId(e); const int InDeg = Graph->GetNI(InNId).GetInDeg(); if (InDeg > 0) TmpV[j] += (double) TRankH.GetDat(OutNId) / (double) InDeg; } TmpV[j] = C * TmpV[j] + (1.0 - C) * initialTrustScore[NI.GetId()]; } for (int i = 0; i < TRankH.Len(); i++) TRankH[i] = TmpV[i]; } fprintf(fpO, "Node ID\t\tTrustRank\n"); for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++){ int Id = NI.GetId(); double tr = TRankH.GetDat(Id); fprintf(fpO, "%d\t\t\t%.5lf\n", Id, tr); } fclose(fpO); Catch printf("\nRun Time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
result_t EPFLSolver::solve(const GraphHypothesis& realization, vector<pair<double, int>>& clusterSortedScores) { // Get infection times for all the observers and keep ascending. vector<pair<double, int>> observers; for (int observer : m_observerNodes) { // If chosen observers are not infected, we just skip them. if (realization.getInfectionTime(observer) == INFECTED_FALSE) continue; observers.push_back( pair<double, int>(realization.getInfectionTime(observer), observer)); } if (observers.size() == 0) { result_t empty; empty.first = 0; empty.second.push_back(0); // mass empty.second.push_back(100); // diff empty.second.push_back(0); // correct mass for (int s = 0; s < m_config.nodes; ++s) clusterSortedScores.push_back(pair<double, int>(0.0, s)); return empty; } // Everything is related to the reference observer (first infected). sort(observers.begin(), observers.end()); int referenceObserver = observers[0].second; // Compute gaussian moments. gaussian_t moments; if (m_config.infType == BETA) { double beta = m_config.cluster.beta; moments = make_pair(1.00/beta, sqrt((1.00 - beta)/(beta*beta))); } else { moments = make_pair(m_config.cluster.miu, m_config.cluster.beta); } TIntH idToShortestPathsFromReference; TSnap::GetShortPath(m_network, referenceObserver, idToShortestPathsFromReference); // BFS tree from reference observer. Compute LCA w.r.t. to ref. observer. PNGraph bfsTree = TSnap::GetBfsTree<PUNGraph>( m_network, referenceObserver, true, true); // The method below smartly identifies the lowest common ancestor // between two nodes, but wastes quite some memory. Note that because // of using unsigned short ints, one shouldn't have nodes with id > 65535 // TODO(vcarbune): use half of the memory. unsigned short int lca[observers.size()][observers.size()]; for (size_t k = 1; k < observers.size(); ++k) { for (size_t i = k + 1; i < observers.size(); ++i) { int Ni = observers[i].second; int Nk = observers[k].second; int heightNi = idToShortestPathsFromReference.GetDat(Ni); int heightNk = idToShortestPathsFromReference.GetDat(Nk); while (heightNi > heightNk && Ni != referenceObserver) { Ni = bfsTree->GetNI(Ni).GetInNId(0); heightNi = idToShortestPathsFromReference.GetDat(Ni); } while (heightNk > heightNi && Nk != referenceObserver) { Nk = bfsTree->GetNI(Nk).GetInNId(0); heightNk = idToShortestPathsFromReference.GetDat(Nk); } while (Ni != Nk) { Nk = bfsTree->GetNI(Nk).GetInNId(0); Ni = bfsTree->GetNI(Ni).GetInNId(0); } if (heightNk != heightNi || Ni != Nk) cout << "Something awfully wrong here" << endl; lca[k][i] = lca[i][k] = Ni; } } // Delay Covariance Eigen::MatrixXf lambda(observers.size() - 1, observers.size() - 1); for (size_t k = 0; k < observers.size() - 1; ++k) { for (size_t i = 0; i < observers.size() - 1; ++i) { float value = moments.second * moments.second; if (k == i) value *= idToShortestPathsFromReference.GetDat(observers[k+1].second); else value *= idToShortestPathsFromReference.GetDat(lca[k+1][i+1]); lambda(k, i) = value; } } Eigen::MatrixXf invLambda(observers.size() - 1, observers.size() - 1); invLambda = lambda.inverse(); // Observed Delay Eigen::VectorXf d(observers.size() - 1); for (size_t o = 0; o < observers.size() - 1; ++o) d[o] = observers[o+1].first - observers[0].first; TIntV nid; m_network->GetNIdV(nid); for (int s = 0; s < m_network->GetNodes(); ++s) { TIntH idToShortestPathsFromSource; TSnap::GetShortPath(m_network, nid[s], idToShortestPathsFromSource); // Deterministic Delay Eigen::VectorXf miu_s(observers.size() - 1); for (size_t o = 0; o < observers.size() - 1; ++o) { miu_s[o] = moments.first * (idToShortestPathsFromSource.GetDat(observers[o+1].second) - idToShortestPathsFromSource.GetDat(referenceObserver)); } // Estimator value. double estimator = miu_s.transpose() * invLambda * (d - 0.5 * miu_s); clusterSortedScores.push_back(pair<double, int>(estimator, nid[s])); } sort(clusterSortedScores.begin(), clusterSortedScores.end(), std::greater<pair<double, int>>()); int realSourceIdx = 0; for (size_t i = 0; i < clusterSortedScores.size(); ++i) { if (clusterSortedScores[i].second == realization.getSource()) realSourceIdx = i; } result_t result; result.first = clusterSortedScores[0].second; // solution score? result.second.push_back(clusterSortedScores[realSourceIdx].first); result.second.push_back(clusterSortedScores[0].first - clusterSortedScores[realSourceIdx].first); result.second.push_back(realSourceIdx); // rank return result; }