def compute_graph_likelihood(source, who_infected, adjacency, vs_path, max_infection): # compute the likelihood of the infected subgraph starting from node source # Inputs # source: assumed source of the rumor # who_infected: adjacency relations for the infected subgraph # adjacency: adjacency relations for the underlying network # vs_path: path that the virtual source takes in the graph # max_infection: maximum number of people who can be infected by a single node # # Outputs # likelihood likelihood of the graph given source if len(vs_path) == 1: print('The vs path is 1 hop!', source, vs_path) utilities.print_adjacency(who_infected, adjacency) return float('-inf') # vs_path.pop() nodes = range(len(who_infected)) new_infection_pattern = [0 for i in nodes] new_infection_pattern[source] = 1 new_who_infected = [[] for i in nodes] # first element is just the source itself current_vs = vs_path.pop(0) # log likelihood of the 1st node likelihood = math.log(1.0 / len(adjacency[source])) # get the new vs current_vs = vs_path.pop(0) new_infection_pattern, new_who_infected, tmp = infectionUtils.infect_nodes( source, [current_vs], new_infection_pattern, new_who_infected) # infect the neighbors of the new vs infected = [i for i in who_infected[current_vs]] infected.remove(source) new_infection_pattern, new_who_infected, tmp = infectionUtils.infect_nodes( current_vs, infected, new_infection_pattern, new_who_infected) likelihood += infect_set_likelihood(infected, adjacency[current_vs], new_infection_pattern, max_infection) while vs_path: new_infection_pattern, new_who_infected, likelihood = pass_branch_message_likelihood( current_vs, vs_path[0], new_infection_pattern, adjacency, max_infection, new_who_infected, who_infected, likelihood) current_vs = vs_path.pop(0) return likelihood
def pass_branch_message_likelihood(source, recipient, new_infection_pattern, adjacency, max_infection, new_who_infected, who_infected, likelihood): # pass an instruction to branch from the source to the leaves using the who_infected pattern, and compute the likelihood # Inputs # source: source of the infection # recipient: array of child ids # new_infection_pattern: binary array describing whether each node is already infected or not in the graph being built up # adjacency: adjacency relations for the underlying network # max_infection: maximum number of people who can be infected by a single node # new_who_infected: adjacency relations for the infected subgraph being built up # who_infected: adjacency relations for the original infected subgraph # likelihood: the likelihood for this graph # # Outputs # new_infection_pattern (updated) # new_who_infected (updated) # likelihood (updated) leaf = True # pass to the neighbors who are your neighbors in the true infection graph neighbors = [k for k in new_who_infected[recipient] if (not k == source)] neighbors.sort() for neighbor in neighbors: leaf = False new_infection_pattern, new_who_infected, likelihood = pass_branch_message_likelihood(recipient, neighbor, new_infection_pattern, adjacency, max_infection, new_who_infected, who_infected, likelihood) if leaf: neighbors = [k for k in who_infected[recipient] if not k==source] likelihood += infect_set_likelihood(neighbors, adjacency[recipient], new_infection_pattern, max_infection) new_infection_pattern, new_who_infected, tmp = infectionUtils.infect_nodes(recipient, neighbors, new_infection_pattern, new_who_infected) return new_infection_pattern, new_who_infected, likelihood
def compute_graph_likelihood(self, path): if len(path) == 1: print('ERROR: The source is a spy!', self.source, path) return [self.source] # print('THe path is ',path) # print('THe source is ',self.source) path.pop() nodes = self.contact_graph.nodes() num_nodes = self.contact_graph.number_of_nodes() # print('There are ',num_nodes,'nodes here') # print('And the other graph has ',self.graph.number_of_nodes(),'nodes') new_infection_pattern = [0 for i in nodes] new_infection_pattern[self.source] = 1 new_who_infected = [[] for i in nodes] # first element is just the source itself current_vs = path.pop(0) path_source = current_vs # log likelihood of the 1st passage to the VS likelihood = math.log(1.0/self.contact_graph.degree(self.source)) if not path: path.append(path_source) # print('path',path) return likelihood # get the new vs current_vs = path.pop(0) new_infection_pattern, new_who_infected, tmp = infectionUtils.infect_nodes(self.source, [current_vs], new_infection_pattern, new_who_infected) # infect the neighbors of the new vs infected = [i for i in self.adjacency[current_vs]] infected.remove(path_source) new_infection_pattern, new_who_infected, tmp = infectionUtils.infect_nodes(current_vs, infected, new_infection_pattern, new_who_infected) likelihood += estimation.infect_set_likelihood(infected, self.contact_adjacency[current_vs], new_infection_pattern, self.max_infection) while path: new_infection_pattern, new_who_infected, likelihood = estimation.pass_branch_message_likelihood(current_vs, path[0], new_infection_pattern, self.contact_adjacency, self.max_infection, new_who_infected, self.adjacency, likelihood) current_vs = path.pop(0) path.append(path_source) # print('path',path) return likelihood
def compute_graph_likelihood(source, who_infected, adjacency, vs_path, max_infection): # compute the likelihood of the infected subgraph starting from node source # Inputs # source: assumed source of the rumor # who_infected: adjacency relations for the infected subgraph # adjacency: adjacency relations for the underlying network # vs_path: path that the virtual source takes in the graph # max_infection: maximum number of people who can be infected by a single node # # Outputs # likelihood likelihood of the graph given source if len(vs_path) == 1: print('The vs path is 1 hop!', source, vs_path) utilities.print_adjacency(who_infected, adjacency) return float('-inf') # vs_path.pop() nodes = range(len(who_infected)) new_infection_pattern = [0 for i in nodes] new_infection_pattern[source] = 1 new_who_infected = [[] for i in nodes] # first element is just the source itself current_vs = vs_path.pop(0) # log likelihood of the 1st node likelihood = math.log(1.0/len(adjacency[source])) # get the new vs current_vs = vs_path.pop(0) new_infection_pattern, new_who_infected, tmp = infectionUtils.infect_nodes(source, [current_vs], new_infection_pattern, new_who_infected) # infect the neighbors of the new vs infected = [i for i in who_infected[current_vs]] infected.remove(source) new_infection_pattern, new_who_infected, tmp = infectionUtils.infect_nodes(current_vs, infected, new_infection_pattern, new_who_infected) likelihood += infect_set_likelihood(infected, adjacency[current_vs], new_infection_pattern, max_infection) while vs_path: new_infection_pattern, new_who_infected, likelihood = pass_branch_message_likelihood(current_vs, vs_path[0], new_infection_pattern, adjacency, max_infection, new_who_infected, who_infected, likelihood) current_vs = vs_path.pop(0) return likelihood
def infect_nodes_adaptive_diff(source, adjacency, max_time, max_infection): num_nodes = len(adjacency) timesteps = 0 # initially the virtual source and the true source are the same virtual_source = source virtual_source_candidate = virtual_source infection_pattern = [0] * num_nodes infection_pattern[source] = 1 dist_from_source = [-1] * num_nodes dist_from_source[source] = 0 who_infected = [[] for i in range(num_nodes)] jordan_correct = [0 for i in range(max_time)] rumor_correct = [0 for i in range(max_time)] ml_correct = [0 for i in range(max_time)] ml_distances = [[] for i in range(max_time)] num_infected = [] blocked = False while timesteps < max_time: # print('time', timesteps) # in odd timesteps, choose a direction to expand in if timesteps == 0: current_neighbors = [k for k in adjacency[source]] virtual_source_candidate, current_neighbors, source_likelihood = pick_random_elements( current_neighbors, 1) previous_vs = virtual_source # infect twice in one direction, always infection_pattern, who_infected, dist_from_source = infectionUtils.infect_nodes( source, virtual_source_candidate, infection_pattern, who_infected, dist_from_source) virtual_source_candidate = virtual_source_candidate[0] infection_pattern, who_infected, dist_from_source = pass_branch_message( source, virtual_source_candidate, infection_pattern, adjacency, max_infection, who_infected, dist_from_source) virtual_source = virtual_source_candidate m = 1 # the virtual source is always going to be 1 hop away from the true source at T=1 else: current_neighbors = [k for k in who_infected[virtual_source]] # if (len(current_neighbors) < 2) or (random.random() < utilities.compute_alpha(m,timesteps,max_infection)): # with probability alpha, spread symmetrically (keep the virtual source where it is) if (len(current_neighbors) < 2): # if there is nowhere for the virtual source to move, keep it where it is if len(current_neighbors) < 1: blocked = True print('Blocked. Exiting.') break # branch once in every direction for neighbor in current_neighbors: infection_pattern, who_infected, dist_from_source = pass_branch_message( virtual_source, neighbor, infection_pattern, adjacency, max_infection, who_infected, dist_from_source) # take care of getting stuck if len(current_neighbors) == 1: infection_pattern, who_infected, dist_from_source = pass_branch_message( virtual_source, current_neighbors[0], infection_pattern, adjacency, max_infection, who_infected, dist_from_source) previous_vs = virtual_source virtual_source = current_neighbors[0] else: # spread asymmetrically # find a direction to move virtual_source_candidate = [previous_vs] while virtual_source_candidate[0] == previous_vs: virtual_source_candidate, current_neighbors, new_vs_likelihood = pick_random_elements( current_neighbors, 1) virtual_source_candidate = virtual_source_candidate[0] previous_vs = virtual_source # the virtual source moves one more hop away from the true source m += 1 # branch twice in one direction infection_pattern, who_infected, dist_from_source = pass_branch_message( virtual_source, virtual_source_candidate, infection_pattern, adjacency, max_infection, who_infected, dist_from_source) infection_pattern, who_infected, dist_from_source = pass_branch_message( virtual_source, virtual_source_candidate, infection_pattern, adjacency, max_infection, who_infected, dist_from_source) virtual_source = virtual_source_candidate # print('Adjacency at time ', timesteps) # utilities.print_adjacency(who_infected, adjacency) # print('\n') num_infected = num_infected + [sum(infection_pattern)] # Jordan-centrality estimate # jordan_estimate = estimation.jordan_centrality(who_infected) # jordan_correct[timesteps] = (jordan_estimate == source) jordan_correct[timesteps] = 0 # Rumor centrality estimate # rumor_estimate = estimation.rumor_centrality(who_infected) # rumor_correct[timesteps] = (rumor_estimate == source) rumor_correct[timesteps] = 0 # ML estimate ml_leaf, likelihoods, ml_distance = estimation.max_likelihood( who_infected, virtual_source, adjacency, max_infection, dist_from_source, source) ml_correct[timesteps] = (ml_leaf == source) ml_distances[timesteps] = ml_distance results = (jordan_correct, rumor_correct, ml_correct, ml_distances) timesteps += 1 return num_infected, infection_pattern, who_infected, results