示例#1
0
def run_inf_prob_vs_perc_sus(name: str, diseases: Sequence[Disease],
                             new_network: Callable[[], Network],
                             flicker_config: RandomFlickerConfig,
                             num_trials: int, rng):
    """
    Save the plot and csv of infection probability vs percent susceptible.
    """
    results: Dict[float, List[float]] = defaultdict(lambda: [])
    print(f'Running {name}')
    pbar = tqdm(total=num_trials * len(diseases))
    for disease, _ in it.product(diseases, range(num_trials)):
        net = new_network()
        flicker = flicker_config.make_behavior(net.M, net.intercommunity_edges)
        sir0 = make_starting_sir(net.N, 1, rng)
        perc_sus = np.sum(
            simulate(net.M, sir0, disease, flicker, 100, None, rng)[-1][0] > 0
        ) / net.N
        results[disease.trans_prob].append(perc_sus)
        pbar.update()

    x_coords = tuple(results.keys())
    collected_data = np.array([list(values) for values in results.values()])
    quartiles = np.quantile(collected_data, (.25, .75),
                            axis=1,
                            interpolation='midpoint')
    y_coords = np.mean(collected_data, axis=1)
    plt.figure()
    plt.title(name)
    plt.xlim(0, 1)
    plt.ylim(0, 1)
    plt.xlabel('Infection Probability')
    plt.ylabel('Survival Percentage')
    plt.plot(x_coords, y_coords)
    plt.fill_between(x_coords, quartiles[0], quartiles[1], alpha=.4)
    plt.savefig(f'results/{name}.png', format='png', dpi=200)
示例#2
0
def run_agent_generated_trial(args: Tuple[Disease, AgentBehavior, int, Any])\
        -> Optional[Tuple[float, float, float]]:
    """
    args: (disease to use in the simulation,
           the behavior agents have when generating the network,
           the number of agents in the network,
           an instance of np.random.default_rng)
    """
    disease, agent_behavior, N, rand = args
    sim_len = 200
    sims_per_trial = 150
    net = make_agent_generated_network(N, agent_behavior)
    if net is None:
        return None

    to_flicker = partitioning.fluidc_partition(net.G, 50)
    proportion_flickering = len(to_flicker) / net.E
    social_good = rate_social_good(net)

    network_behavior = StaticFlickerBehavior(net.M, to_flicker, (True, False),
                                             "Probs don't change this")
    avg_sus = np.mean([
        np.sum(
            simulate(net.M, make_starting_sir(net.N, 1), disease,
                     network_behavior, sim_len, None, rand)[-1][0] > 0)
        for _ in range(sims_per_trial)
    ]) / net.N

    return proportion_flickering, avg_sus, social_good
def run_social_circles_trial(
    args: Tuple[Dict[networkgen.Agent, int], Tuple[int, int], Disease, Any]
) -> Optional[Tuple[float, float, float]]:
    agent_to_quantity, grid_dims, disease, rand = args
    sim_len = 200
    sims_per_trial = 150
    target_communities = 25

    sc_results = networkgen.make_social_circles_network(agent_to_quantity,
                                                        grid_dims,
                                                        rand=rand)
    if sc_results is None:
        return None
    net, _, = sc_results
    if nx.number_connected_components(net.G) > target_communities:
        return None

    to_flicker = partitioning.fluidc_partition(net.G, target_communities)
    proportion_flickering = len(to_flicker) / net.E
    social_good_score = rate_social_good(net)

    network_behavior = StaticFlickerBehavior(net.M, to_flicker, (True, False),
                                             "Probs don't change this")
    avg_sus = np.mean([
        np.sum(
            simulate(net.M, make_starting_sir(net.N, 1), disease,
                     network_behavior, sim_len, None, rand)[-1][0] > 0)
        for _ in range(sims_per_trial)
    ]) / net.N

    return proportion_flickering, avg_sus, social_good_score
def run_connected_community_trial(args: Tuple[ConnectedCommunityConfiguration, Disease, Any])\
        -> Optional[Tuple[float, float, float]]:
    """
    args: (ConnectedCommunityConfiguration to use,
           disease to use,
           default_rng instance)
    return: (proportion of edges that flicker, the average number of remaining susceptible agents)
            or None on failure.
    """
    sim_len = 200
    sims_per_trial = 150
    configuration, disease, rand = args

    inner_degrees = configuration.make_inner_degrees()
    outer_degrees = configuration.make_outer_degrees()
    net = networkgen.make_connected_community_network(inner_degrees, outer_degrees, rand)
    # If a network couldn't be successfully generated, return None to signal the failure
    if net is None:
        return None
    to_flicker = {(u, v) for u, v in net.edges if net.communities[u] != net.communities[v]}
    proportion_flickering = len(to_flicker) / net.E
    social_good = rate_social_good(net)

    behavior = StaticFlickerBehavior(net.M, to_flicker, (True, False), "Probs don't change this")
    avg_sus = np.mean([np.sum(simulate(net.M, make_starting_sir(net.N, 1),
                                       disease, behavior, sim_len, None, rand)[-1][0] > 0)
                       for _ in range(sims_per_trial)]) / net.N

    return proportion_flickering, avg_sus, social_good
示例#5
0
 def __call__(self, encoding: np.ndarray) -> float:
     net = self._enc_to_G(encoding)
     M = net.M
     to_flicker = fluidc_partition(net.G, net.N//20)
     flicker_behavior = StaticFlickerBehavior(M, to_flicker, (True, False), '')
     avg_sus = np.mean([np.sum(simulate(M, make_starting_sir(len(M), 1),
                                        self._disease, flicker_behavior, self._sim_len,
                                        None, self._rand)[-1][0] > 0)
                        for _ in range(self._n_sims)]) / len(M)
     cost = 2-avg_sus-rate_social_good(net, self._decay_func)
     return cost
示例#6
0
 def experiment(make_network, seed):
     """
     return: list of (high_reach_survival_rate, high_reach_sim_time,
                      low_reach_survival_rate, low_reach_sim_time)
     """
     rng = np.random.default_rng(seed)
     hr_net = make_network(high_reach)
     lr_net = make_network(low_reach)
     sir0 = make_starting_sir(hr_net.N, 1, rng)
     hr_sirs = simulate(hr_net.M, sir0, disease,
                        make_behavior(high_reach, make_network, rng),
                        sim_len_cap, rng, None)
     lr_sirs = simulate(lr_net.M, sir0, disease,
                        make_behavior(low_reach, make_network, rng),
                        sim_len_cap, rng, None)
     return (calc_survival_rate(hr_sirs), len(hr_sirs),
             calc_survival_rate(lr_sirs), len(lr_sirs))
示例#7
0
def cc_pressure_vs_none_entry_point():
    rng = np.random.default_rng(0xbeefee)
    num_trials = 1000
    disease = Disease(4, .4)
    inner_bounds = 1, 15
    outer_bounds = 1, 5
    community_size = 20
    n_communities = 25
    make_ccn = MakeConnectedCommunity(community_size, inner_bounds,
                                      n_communities, outer_bounds, rng)
    pressure_configurations = [
        SimplePressureConfig(radius, prob, rng)
        for radius, prob in it.product((1, 2, 3), (.25, .5, .75))
    ]
    # pressure_experiment(make_ccn, pressure_configurations, disease, num_trials, rng)
    net = make_ccn()
    simulate(net.M, make_starting_sir(net.N, 1, rng), disease,
             pressure_configurations[1].make_behavior(net), 100,
             nx.spring_layout(net.G))
def elitist_experiment():
    rng = np.random.default_rng()
    path = 'networks/elitist-500.txt'
    name = fio.get_network_name(path)
    net = fio.read_network(path)
    r, fp = 2, .75
    update_connections, uc_name = (sd.SimplePressureBehavior(net, rng, r, fp),
                                   f'Pressure(r={r}, fp={fp})')
    # update_connections, uc_name = sd.no_update, 'Static'
    disease = sd.Disease(4, .2)
    sir0 = sd.make_starting_sir(net.N, (0, ), rng)
    survival_rates = np.array([
        simulate_return_survival_rate(net, disease, update_connections, rng,
                                      sir0) for _ in range(500)
    ])
    title = f'{disease} {uc_name}\n{name} Survival Rates'
    plt.title(title)
    plt.boxplot(survival_rates)
    plt.savefig(title + '.png', format='png')
示例#9
0
def main():
    n_trials = 100
    max_steps = 100
    rng = np.random.default_rng(0)
    disease = Disease(4, .2)
    names = ('elitist-500', 'cavemen-50-10', 'spatial-network', 'cgg-500',
             'watts-strogatz-500-4-.1')
    paths = fio.network_names_to_paths(names)
    behavior_configs = (RandomFlickerConfig(.5, 'Random .5', rng),
                        StaticFlickerConfig((True, False), 'Static .5'))

    for net_name, path in zip(names, paths):
        net = fio.read_network(path)
        to_flicker = tuple((u, v) for u, v in net.edges
                           if net.communities[u] != net.communities[v])
        proportion_flickering = len(to_flicker) / net.E
        social_good = rate_social_good(net)
        trial_to_pf = tuple(proportion_flickering for _ in range(n_trials))
        trial_to_sg = tuple(social_good for _ in range(n_trials))
        print(f'Running simulations for {net_name}.')
        for config in behavior_configs:
            behavior = config.make_behavior(net.M, to_flicker)
            sim_results = [
                get_final_stats(
                    simulate(net.M,
                             make_starting_sir(net.N, 1, rng),
                             disease,
                             behavior,
                             max_steps,
                             None,
                             rng=rng)) for _ in tqdm(range(n_trials))
            ]
            results = BasicExperimentResult(f'{net_name} {config.name}',
                                            sim_results, trial_to_pf,
                                            trial_to_sg)
            results.save_csv(RESULTS_DIR)
            results.save_box_plots(RESULTS_DIR)
            results.save_perc_sus_vs_social_good(RESULTS_DIR)
示例#10
0
def run_experiments(args: Tuple[str, int, int, Disease, Sequence[FlickerConfig], str])\
        -> Optional[FlickerComparisonResult]:
    """
    Run a batch of experiments and return a tuple containing the network's name,
    number of flickering edges, and a mapping of behavior name to the final
    amount of susceptible nodes. Return None on failure.

    args: (path to the network,
           number of sims to run for each behavior,
           simulation length,
           disease,
           a sequence of configs for the flickers to use,
           the name of the baseline flicker to compare the other results to)
    """
    network_path, num_sims, sim_len, disease, flicker_configs, baseline_flicker_name = args
    net = fio.read_network(network_path)
    intercommunity_edges = {(u, v)
                            for u, v in net.edges
                            if net.communities[u] != net.communities[v]}

    behavior_to_results: Dict[str, Sequence[float]] = {}
    for config in flicker_configs:
        behavior = config.make_behavior(net.M, intercommunity_edges)
        # The tuple comprehension is pretty arcane, so here is an explanation.
        # Each entry is the sum of the number of entries in the final SIR where
        # the days in S are greater than 0. That is to say, the number of
        # susceptible agents at the end of the simulation.
        perc_sus = tuple(
            np.sum(
                simulate(net.M, make_starting_sir(net.N, 1), disease, behavior,
                         sim_len, None)[-1][0] > 0) / net.N
            for _ in range(num_sims))
        behavior_to_results[behavior.name] = perc_sus

    return FlickerComparisonResult(fio.get_network_name(network_path),
                                   num_sims, sim_len,
                                   len(intercommunity_edges) / net.E,
                                   behavior_to_results, baseline_flicker_name)
示例#11
0
def pressure_test_entry_point():
    rng = np.random.default_rng()
    net = fio.read_network('networks/cavemen-50-10.txt')
    simulate(net.M, make_starting_sir(net.N, (0, ), rng), Disease(4, 0.3),
             SimplePressureBehavior(net, 1), 200, None, rng)
 def choose_by_centrality(net, centrality_measure, max_or_min):
     degrees = dict(centrality_measure(net.G))  # type: ignore
     patient0 = max_or_min(degrees.keys(), key=lambda k: degrees[k])
     return sd.make_starting_sir(net.N, (patient0, ), rng)
def choose_infected_node():
    """This experiment is for choosing nodes with specific attributes to be patient 0"""
    rng = np.random.default_rng()
    r, fp = 2, .25
    disease = sd.Disease(4, .3)
    n_trials = 500
    seed = 0

    def choose_by_centrality(net, centrality_measure, max_or_min):
        degrees = dict(centrality_measure(net.G))  # type: ignore
        patient0 = max_or_min(degrees.keys(), key=lambda k: degrees[k])
        return sd.make_starting_sir(net.N, (patient0, ), rng)

    sir_strats = (
        ('Highest Degree',
         lambda net: choose_by_centrality(net, nx.degree_centrality, max)),
        ('Random', lambda net: sd.make_starting_sir(net.N, 1, rng)),
        ('Lowest Degree',
         lambda net: choose_by_centrality(net, nx.degree_centrality, min)),
        ('Highest Eigenvector Centrality', lambda net: choose_by_centrality(
            net, nx.eigenvector_centrality_numpy, max)),
        ('Lowest Eigenvector Centrality', lambda net: choose_by_centrality(
            net, nx.eigenvector_centrality_numpy, min)))
    networks: Tuple[MakeNetwork, ...] = (
        MakeConnectedCommunity(20, (15, 20), 25, (3, 6), rng),
        MakeConnectedCommunity(10, (5, 10), 50, (3, 6),
                               rng), MakeWattsStrogatz(500, 4, .01, seed),
        MakeWattsStrogatz(500, 4,
                          .02, seed), MakeWattsStrogatz(500, 5, .01, seed),
        MakeBarabasiAlbert(500,
                           2, seed), MakeBarabasiAlbert(500, 3,
                                                        seed),
        MakeBarabasiAlbert(500,
                           4, seed), MakeErdosRenyi(500, .01,
                                                    seed),
        MakeErdosRenyi(500, .02, seed), MakeErdosRenyi(500, .03, seed),
        MakeGrid(25, 20), MakeGrid(50, 10), MakeGrid(100,
                                                     5),
        LoadNetwork('evolved-low-communicability-100'))[-1:]

    print(f'Running {len(networks)*len(sir_strats)} experiments')
    experiment_to_survival_rates = {}
    for make_net, (strat_name, sir_strat) in it.product(networks, sir_strats):
        survival_rates = []
        for _ in tqdm(range(n_trials),
                      desc=f'{make_net.class_name} & {strat_name}'):
            net = make_net()
            update_connections = sd.SimplePressureBehavior(net, rng, r, fp)
            sir0 = sir_strat(net)
            survival_rate = simulate_return_survival_rate(
                net, disease, update_connections, rng, sir0)
            survival_rates.append(survival_rate)

        title = f'{strat_name} Patient 0\n{make_net.class_name} Survival Rates'
        plt.figure()
        plt.title(title)
        plt.xlim(0, 1.0)
        plt.ylim(0, n_trials)
        plt.hist(survival_rates, bins=None)
        plt.savefig(os.path.join('results', title + '.png'), format='png')
        experiment_to_survival_rates[title] = survival_rates

    # save the raw data
    with open(os.path.join('results', 'patient-0-sensitivity.csv'),
              'w',
              newline='') as csv_file:
        writer = csv.writer(csv_file)
        for experiment_name, survival_rates in experiment_to_survival_rates.items(
        ):
            writer.writerow([experiment_name])
            writer.writerow(survival_rates)