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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
    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
        
        
Beispiel #5
0
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