void TGreedyAlg::addCascade(const TStr& cascadeStr) { TStrV NIdV; cascadeStr.SplitOnAllCh(';', NIdV); TCascade C; for (int i = 0; i < NIdV.Len(); i++) { TStr NId, Tm; NIdV[i].SplitOnCh(NId, ',', Tm); IAssert( IsNodeNm(NId.GetInt()) ); GetNodeInfo(NId.GetInt()).Vol = GetNodeInfo(NId.GetInt()).Vol + 1; C.Add(NId.GetInt(), Tm.GetFlt()); } C.Sort(); cascadeV.Add(C); }
void TGreedyAlg::runGreedyAlgorithm() { outputGraph = TKColourNet::New(); for (THash<TInt, TNodeInfo>::TIter NI = nodeNmH.BegI(); NI < nodeNmH.EndI(); NI++) { outputGraph->AddNode(NI.GetKey(), TKColourNode()); printf("Added node %d to output graph\n", (int) NI.GetKey()); } // for each node i for (THash<TInt, TNodeInfo>::TIter NI = nodeNmH.BegI(); NI < nodeNmH.EndI(); NI++) { int nodeI = NI.GetKey(); printf("***** Considering node i: %d *****\n", nodeI); // initialise unaccounted cascades U TVec<TCascade> cascades = cascadeV; // initialise parental neighbourhood TIntV parentalNeighbourhood; bool uselessUnaccountedCasacdesLeft = false; while ((cascades.Len() != 0) && (!uselessUnaccountedCasacdesLeft)) { // printf("%d Casacdes left...\n", cascades.Len()); // find node j that could possible have infected node i that has been observed for largest number of cascades int argmax = -1; int maxNoCascades = 0; bool areUnaccountedCascadesUseless = true; for (THash<TInt, TNodeInfo>::TIter LNI = nodeNmH.BegI(); LNI < nodeNmH.EndI(); LNI++) { int nodeJ = LNI.GetKey(); // printf("nodeJ: %d\n", nodeJ); int countPotentialNoCascades = 0; if (nodeI != nodeJ) { for (int c = 0; c < cascades.Len(); c++) { TCascade cascade = cascades[c]; if (cascade.IsNode(nodeJ) && cascade.IsNode(nodeI)) { // if (cascade.GetTm(nodeI) > cascade.GetTm(nodeJ)) { if (cascade.GetTm(nodeJ) == (cascade.GetTm(nodeI) - 1)) { countPotentialNoCascades++; } } } if (countPotentialNoCascades > maxNoCascades) { maxNoCascades = countPotentialNoCascades; argmax = nodeJ; areUnaccountedCascadesUseless = false; } else { areUnaccountedCascadesUseless = areUnaccountedCascadesUseless && true; } } } if (areUnaccountedCascadesUseless) { uselessUnaccountedCasacdesLeft = true; } if (argmax != -1) { // printf("argmax (k) = %d, noCasacdesAppearedIn = %d\n", argmax, maxNoCascades); // add arg max (k) to the set of parental neighbours parentalNeighbourhood.Add(argmax); } // remove the cascades which k belongs to TIntV cascadesToRemove; for (int c = 0; c < cascades.Len(); c++) { TCascade cascade = cascades[c]; if (cascade.IsNode(argmax) && cascade.IsNode(nodeI)) { if (cascade.GetTm(nodeI) > cascade.GetTm(argmax)) { cascadesToRemove.Add(c); } } } cascadesToRemove.Sort(); // printf("cascadesToRemove: "); for (int i = 0; i < cascadesToRemove.Len(); i++) { // printf("%d, ", (int) cascadesToRemove[i]); cascades.Del(cascadesToRemove[i]-i); } // printf("\n"); } // add edges from node i to each of parent for (int i = 0; i < parentalNeighbourhood.Len(); i++) { int srcNodeId = parentalNeighbourhood[i]; int dstNodeId = nodeI; outputGraph->AddEdge(srcNodeId, dstNodeId); // printf("##### Added Edge: %d -> %d #####\n", srcNodeId, dstNodeId); } } }
void TNetInfBs::GenNoisyCascade(TCascade& C, const int& TModel, const double &window, TIntPrIntH& EdgesUsed, const double& std_waiting_time, const double& std_beta, const double& PercRndNodes, const double& PercRndRemoval) { TIntPrIntH EdgesUsedC; // list of used edges for a single cascade GenCascade(C, TModel, window, EdgesUsedC, delta, std_waiting_time, std_beta); // store keys TIntV KeyV; C.NIdHitH.GetKeyV(KeyV); // store first and last time double tbeg = TFlt::Mx, tend = TFlt::Mn; for (int i=0; i < KeyV.Len(); i++) { if (tbeg > C.NIdHitH.GetDat(KeyV[i]).Tm) tbeg = C.NIdHitH.GetDat(KeyV[i]).Tm; if (tend < C.NIdHitH.GetDat(KeyV[i]).Tm) tend = C.NIdHitH.GetDat(KeyV[i]).Tm; } // remove PercRndRemoval% of the nodes of the cascades if (PercRndRemoval > 0) { for (int i=KeyV.Len()-1; i >= 0; i--) { if (TFlt::Rnd.GetUniDev() < PercRndRemoval) { // remove from the EdgesUsedC the ones affected by the removal TIntPrV EdgesToRemove; for (TIntPrIntH::TIter EI = EdgesUsedC.BegI(); EI < EdgesUsedC.EndI(); EI++) { if ( (KeyV[i]==EI.GetKey().Val1 && C.IsNode(EI.GetKey().Val2) && C.GetTm(KeyV[i]) < C.GetTm(EI.GetKey().Val2)) || (KeyV[i]==EI.GetKey().Val2 && C.IsNode(EI.GetKey().Val1) && C.GetTm(KeyV[i]) > C.GetTm(EI.GetKey().Val1)) ) { EI.GetDat() = EI.GetDat()-1; if (EI.GetDat()==0) EdgesToRemove.Add(EI.GetKey()); } } for (int er=0; er<EdgesToRemove.Len(); er++) EdgesUsedC.DelKey(EdgesToRemove[er]); C.Del(KeyV[i]); } } // defrag the hash table, otherwise other functions can crash C.NIdHitH.Defrag(); } // Substitute PercRndNodes% of the nodes for a random node at a random time if (PercRndNodes > 0) { for (int i=KeyV.Len()-1; i >= 0; i--) { if (TFlt::Rnd.GetUniDev() < PercRndNodes) { // remove from the EdgesUsedC the ones affected by the change TIntPrV EdgesToRemove; for (TIntPrIntH::TIter EI = EdgesUsedC.BegI(); EI < EdgesUsedC.EndI(); EI++) { if ( (KeyV[i]==EI.GetKey().Val1 && C.IsNode(EI.GetKey().Val2) && C.GetTm(KeyV[i]) < C.GetTm(EI.GetKey().Val2)) || (KeyV[i]==EI.GetKey().Val2 && C.IsNode(EI.GetKey().Val1) && C.GetTm(KeyV[i]) > C.GetTm(EI.GetKey().Val1)) ) { EI.GetDat() = EI.GetDat()-1; if (EI.GetDat()==0) EdgesToRemove.Add(EI.GetKey()); } } for (int er=0; er<EdgesToRemove.Len(); er++) EdgesUsedC.DelKey(EdgesToRemove[er]); printf("Old node n:%d t:%f --", KeyV[i].Val, C.GetTm(KeyV[i])); C.Del(KeyV[i]); // not repeating a label double tnew = 0; int keynew = -1; do { tnew = tbeg + TFlt::Rnd.GetUniDev()*(tend-tbeg); keynew = Graph->GetRndNId(); } while (KeyV.IsIn(keynew)); printf("New node n:%d t:%f\n", keynew, tnew); C.Add(keynew, tnew); KeyV.Add(keynew); } } } // add to the aggregate list (EdgesUsed) EdgesUsedC.Defrag(); for (int i=0; i<EdgesUsedC.Len(); i++) { if (!EdgesUsed.IsKey(EdgesUsedC.GetKey(i))) EdgesUsed.AddDat(EdgesUsedC.GetKey(i)) = 0; EdgesUsed.GetDat(EdgesUsedC.GetKey(i)) += 1; } }
void TGreedyAlg::generateCascades(const int& noCasacdes, const double& pInit, const double& p, const double& q) { int noNodes = groundTruthGraph->GetNodes(); // printf("Generating cascade for graph with noNodes = %d:\n\n", noNodes); if (noNodes == 0) { return; } // set random seed TInt::Rnd.Randomize(); for (int casacdeI = 0; casacdeI < noCasacdes; casacdeI++) { TCascade cascade; double globalTime = 0; int noActiveNodes = 0; int noSusceptibleNodes = 0; int noInactiveNodes = 0; TIntIntH nodeStates; // flip biased coin for each node to collect seeds for (TKColourNet::TNodeI NI = groundTruthGraph->BegNI(); NI < groundTruthGraph->EndNI(); NI++) { const int nodeId = NI.GetId(); double flipResult = TInt::Rnd.GetUniDev(); // printf("nodeId = %d, flipResult = %f\n", nodeId, (float) flipResult); if (flipResult <= pInit) { nodeStates.AddDat(nodeId) = activeState; // printf("##### ADD TO CASCADE: nodeId = %d, globalTime = %f #####\n", nodeId, globalTime); cascade.Add(nodeId, globalTime); noActiveNodes++; } else { nodeStates.AddDat(nodeId) = susceptibleState; noSusceptibleNodes++; } } globalTime++; while (noActiveNodes > 0) { // printf("\n***** noActiveNodes = %d, noSusceptibleNodes = %d, noInactiveNodes = %d, globalTime = %f *****\n\n", noActiveNodes, noSusceptibleNodes, noInactiveNodes, (float) globalTime); const TIntIntH beginningNodeStates = nodeStates; // for each node in the graph for (TKColourNet::TNodeI NI = groundTruthGraph->BegNI(); NI < groundTruthGraph->EndNI(); NI++) { const int nodeId = NI.GetId(); const int nodeColourId = NI.GetDat().getColourId(); const int nodeState = beginningNodeStates.GetDat(nodeId); // printf("nodeId = %d, nodeColourId = %d, nodeState = %d\n", nodeId, nodeColourId, nodeState); // if node is active, infect susceptible child nodes with probability pij if (nodeState == activeState) { const TKColourNet::TNodeI LNI = groundTruthGraph->GetNI(nodeId); for (int e = 0; e < LNI.GetOutDeg(); e++) { const int childNodeId = LNI.GetOutNId(e); const int childNodeColourId = LNI.GetOutNDat(e).getColourId(); const int childNodeState = nodeStates.GetDat(childNodeId); // printf("childNodeId = %d, childNodeColourId = %d, childNodeState = %d\n", childNodeId, childNodeColourId, childNodeState); if (childNodeState == susceptibleState) { double probablityInfection = (nodeColourId == childNodeColourId) ? p : q; double flipResult = TInt::Rnd.GetUniDev(); // printf("childNodeId = %d, probabilityInfection = %f, flipResult = %f\n", childNodeId, (float) probablityInfection, (float) flipResult); // infection occurred: childNode goes from susceptible -> active if (flipResult <= probablityInfection) { nodeStates[childNodeId] = activeState; // printf("##### ADD TO CASCADE: nodeId = %d, globalTime = %f #####\n", childNodeId, globalTime); cascade.Add(childNodeId, globalTime); noActiveNodes++; noSusceptibleNodes--; } } } // main node goes from active -> inactive nodeStates[nodeId] = inactiveState; noActiveNodes--; noInactiveNodes++; } } globalTime++; } addCascade(cascade); } }
void TNetInfBs::GenCascade(TCascade& C, const int& TModel, const double &window, TIntPrIntH& EdgesUsed, const double& delta, const double& std_waiting_time, const double& std_beta) { TIntFltH InfectedNIdH; TIntH InfectedBy; double GlobalTime; int StartNId; double alpha, beta; if (GroundTruth->GetNodes() == 0) return; while (C.Len() < 2) { C.Clr(); InfectedNIdH.Clr(); InfectedBy.Clr(); GlobalTime = 0; StartNId = GroundTruth->GetRndNId(); InfectedNIdH.AddDat(StartNId) = GlobalTime; while (true) { // sort by time & get the oldest node that did not run infection InfectedNIdH.SortByDat(true); const int& NId = InfectedNIdH.BegI().GetKey(); GlobalTime = InfectedNIdH.BegI().GetDat(); // all the nodes has run infection if (GlobalTime >= window) break; // add current oldest node to the network and set its time C.Add(NId, GlobalTime); // run infection from the current oldest node const TNGraph::TNodeI NI = GroundTruth->GetNI(NId); for (int e = 0; e < NI.GetOutDeg(); e++) { const int DstNId = NI.GetOutNId(e); beta = Betas.GetDat(TIntPr(NId, DstNId)); // flip biased coin (set by beta) if (TInt::Rnd.GetUniDev() > beta+std_beta*TFlt::Rnd.GetNrmDev()) continue; alpha = Alphas.GetDat(TIntPr(NId, DstNId)); // not infecting the parent if (InfectedBy.IsKey(NId) && InfectedBy.GetDat(NId).Val == DstNId) continue; double sigmaT; switch (TModel) { case 0: // exponential with alpha parameter sigmaT = TInt::Rnd.GetExpDev(alpha); break; case 1: // power-law with alpha parameter sigmaT = TInt::Rnd.GetPowerDev(alpha); while (sigmaT < delta) { sigmaT = TInt::Rnd.GetPowerDev(alpha); } break; case 2: // rayleigh with alpha parameter sigmaT = TInt::Rnd.GetRayleigh(1/sqrt(alpha)); break; default: sigmaT = 1; break; } // avoid negative time diffs in case of noise if (std_waiting_time > 0) sigmaT = TFlt::GetMx(0.0, sigmaT + std_waiting_time*TFlt::Rnd.GetNrmDev()); double t1 = GlobalTime + sigmaT; if (InfectedNIdH.IsKey(DstNId)) { double t2 = InfectedNIdH.GetDat(DstNId); if (t2 > t1 && t2 != window) { InfectedNIdH.GetDat(DstNId) = t1; InfectedBy.GetDat(DstNId) = NId; } } else { InfectedNIdH.AddDat(DstNId) = t1; InfectedBy.AddDat(DstNId) = NId; } } // we cannot delete key (otherwise, we cannot sort), so we assign a big time (window cut-off) InfectedNIdH.GetDat(NId) = window; } } C.Sort(); for (TIntH::TIter EI = InfectedBy.BegI(); EI < InfectedBy.EndI(); EI++) { TIntPr Edge(EI.GetDat().Val, EI.GetKey().Val); if (!EdgesUsed.IsKey(Edge)) EdgesUsed.AddDat(Edge) = 0; EdgesUsed.GetDat(Edge) += 1; } }