예제 #1
0
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
예제 #2
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)
예제 #3
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_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 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))
예제 #6
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))
예제 #7
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
예제 #8
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)
예제 #9
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)
예제 #10
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)