//??????? TPt<TNodeEDatNet<TFlt, TFlt>> GenerateDAG2(const TPt<TNodeEDatNet<TFlt, TFlt>>& pGraph, const std::vector<int> &vSeedIDs, double dThreshold) { // Vector of MIOA graphs per seed node std::vector<TPt<TNodeEDatNet<TFlt, TFlt>>> vMIOAGraphs; // Compute the union of MIOA for each node of vSeedIDs for(auto it=vSeedIDs.begin(); it!=vSeedIDs.end(); ++it) vMIOAGraphs.push_back(MIOA(pGraph, *it, dThreshold)); auto pOut = GraphUnion(vMIOAGraphs); // Set node data for (auto NI = pOut->BegNI(); NI < pOut->EndNI(); NI++) pOut->SetNDat(NI.GetId(), FLT_MAX); // Copy the edge weights from pGraph for (auto EI = pOut->BegEI(); EI < pOut->EndEI(); EI++) pOut->SetEDat(EI.GetSrcNId(), EI.GetDstNId(), pGraph->GetEDat(EI.GetSrcNId(), EI.GetDstNId())); // Create a super root in order to update in one pass all the shortest paths from vSeedIDs nodes int superRootID = pGraph->GetMxNId()+1; pOut->AddNode(superRootID); for(auto it=vSeedIDs.begin(); it!=vSeedIDs.end(); ++it) { pOut->AddEdge(superRootID, *it); pOut->SetEDat(superRootID, *it, 1.0); } Dijkstra(pOut, superRootID, dThreshold, pOut); // Remove the artificial super root node pOut->DelNode(superRootID); // Traverse the edges and prune the graph for (auto EI = pOut->BegEI(); EI < pOut->EndEI(); EI++) { if(EI.GetDstNDat().Val < EI.GetSrcNDat().Val) pOut->DelEdge(EI.GetSrcNId(), EI.GetDstNId()); } //Reset Node data from the original graph for (auto NI = pGraph->BegNI(); NI < pGraph->EndNI(); NI++) pOut->SetNDat(NI.GetId(),NI.GetDat().Val); return pOut; }
std::vector<int> MaxIncrementalInfluence(TPt<TNodeEDatNet<TFlt, TFlt>>& pGraph, int numRounds){ std::vector<int> vSeedSet; tbb::concurrent_unordered_map<int,double> mSpreadIncrement; auto pGraph_temp = TNodeEDatNet<TFlt, TFlt>::New(); double influence = 0.0; int i,chunk = 50; static tbb::spin_mutex sMutex; //Failure of using PeerSeeds due to insufficient memory //std::map<int,std::vector<int> > mPeerSeeds; //std::map<int,TPt<TNodeEDatNet<TFlt, TFlt>> > mMIOAs; /* Initialization*/ int numNodes = pGraph->GetMxNId(); #pragma omp parallel shared(pGraph,chunk,mSpreadIncrement) private(pGraph_temp,i) { #pragma omp for schedule(dynamic,chunk) nowait for (i =0;i<numNodes;++i) { if(pGraph->IsNode(i)) { pGraph_temp = MIOA(pGraph, i, 0); InitializationBeforePropagation(pGraph_temp); ParallelBPFromNode_1DPartitioning(pGraph_temp, i); mSpreadIncrement[i]=InfluenceSpreadFromSeedNodes(pGraph_temp); //mMIOAs.insert(std::make_pair(i,pGraph_v)); } } } /* //build PeerSeeds //Failure due to the insufficient memory for (int v =0; v<pGraph->GetNodes();++v) if(pGraph->IsNode(v)) mPeerSeeds[v]=GetPeerSeeds(mMIOAs,v); */ cout<<"--------------------------Finished Initialization---------------------"<<endl; for (int i=0;i<numRounds;++i) { /* select the i'th seed by finding u = argmax(mSpreadIncrement)*/ auto it = std::max_element(mSpreadIncrement.begin(),mSpreadIncrement.end(), [&](std::pair<int,double> const& a, std::pair<int,double> const& b) { return a.second < b.second; } ); int SeedID = it->first; cout << SeedID <<endl; /* calculate the current influence spread */ vSeedSet.push_back(SeedID); pGraph = GenerateDAG1(pGraph, vSeedSet, 0.0); ParallelBPFromNode_1DPartitioning(pGraph, vSeedSet); influence = InfluenceSpreadFromSeedNodes(pGraph); /*remove the newly selected node*/ mSpreadIncrement.unsafe_erase(SeedID); /* update incremental influence spread for each round */ double Delta_MAX = 0.0; std::vector<int> vSeedSet_temp = vSeedSet; #pragma omp parallel shared(pGraph,chunk,vSeedSet,mSpreadIncrement,Delta_MAX) private(pGraph_temp,vSeedSet_temp,i) { #pragma omp for schedule(dynamic,chunk) nowait for (i =0;i<numNodes;++i) { /* exclude the nodes in seed set */ auto result = std::find(vSeedSet.begin(),vSeedSet.end(), i); if (result != vSeedSet.end()) continue; if(pGraph->IsNode(i) && mSpreadIncrement[i] > Delta_MAX) { /*different processors use different copied vSeedSet*/ vSeedSet_temp.push_back(i); pGraph_temp = GenerateDAG1(pGraph, vSeedSet_temp, 0); ParallelBPFromNode_1DPartitioning(pGraph_temp, vSeedSet_temp); mSpreadIncrement[i]=InfluenceSpreadFromSeedNodes(pGraph_temp)-influence; if (mSpreadIncrement[i]> Delta_MAX) { tbb::spin_mutex::scoped_lock lock(sMutex); Delta_MAX = mSpreadIncrement[i]; } vSeedSet_temp.pop_back(); } } } } return vSeedSet; }