def __init__( self, supervisable_makers: Iterable[Union[str, Supervisable, Callable]], population_data: PopulationData, matrix_data: MatrixData, inital_agent_constraints: InitialAgentsConstraints, run_args, consts: Consts = Consts(), ): # setting logger self.logger = logging.getLogger("simulation") logging.basicConfig() self.logger.setLevel(logging.INFO) self.logger.info("Creating a new simulation.") # unpacking data from generation self.initial_agent_constraints = inital_agent_constraints self.agents = population_data.agents self.geographic_circles = population_data.geographic_circles self.social_circles_by_connection_type = population_data.social_circles_by_connection_type self.geographic_circle_by_agent_index = population_data.geographic_circle_by_agent_index self.social_circles_by_agent_index = population_data.social_circles_by_agent_index self.matrix_type = matrix_data.matrix_type self.matrix = matrix_data.matrix self.depth = matrix_data.depth self.run_args = run_args # setting up medical things self.consts = consts self.medical_machine = consts.medical_state_machine() initial_state = self.medical_machine.initial self.pending_transfers = PendingTransfers() # the manager holds the vector, but the agents update it self.contagiousness_vector = np.zeros(len( self.agents), dtype=float) # how likely to infect others self.susceptible_vector = np.zeros(len(self.agents), dtype=bool) # can get infected # healthcare related data self.living_agents_vector = np.ones(len(self.agents), dtype=bool) self.test_willingness_vector = np.zeros(len(self.agents), dtype=float) self.tested_vector = np.zeros(len(self.agents), dtype=bool) self.tested_positive_vector = np.zeros(len(self.agents), dtype=bool) self.ever_tested_positive_vector = np.zeros(len(self.agents), dtype=bool) self.date_of_last_test = np.zeros(len(self.agents), dtype=int) self.pending_test_results = PendingTestResults() # initializing agents to current simulation for agent in self.agents: agent.add_to_simulation(self, initial_state) initial_state.add_many(self.agents) # initializing simulation modules self.simulation_progression = SimulationProgression( [Supervisable.coerce(a, self) for a in supervisable_makers], self) self.update_matrix_manager = update_matrix.UpdateMatrixManager(self) self.infection_manager = infection.InfectionManager(self) self.healthcare_manager = healthcare.HealthcareManager(self) self.medical_state_manager = MedicalStateManager(self) self.policy_manager = PolicyManager(self) self.current_step = 0 # initializing data for supervising # dict(day:int -> message:string) saving policies messages self.policies_messages = defaultdict(str) self.sick_agents = SickAgents() self.new_sick_counter = 0 self.new_detected_daily = 0 self.logger.info("Created new simulation.") self.simulation_progression.snapshot(self)
def monte_carlo_state_machine_analysis(configuration: Dict) -> Dict: """ :param configuration: Dictionary with configuration for the mc run configuration must contain: * population_size for the mc configuration might contain: * consts_file - For loading Consts() * circle_consts file - for loading CircleConsts :return: Dictionary with statistics of the run: * population_size * days_passed - time it took to all the agents to recover/die * time_in_each_state - for each state, total number of days all agents were in it * visitors_in_each_state - Number of agents that visited each state * average_duration_in_state - Empirical mean time to stay at state conditioned that we enter it * state_duration_expected_time - Empirical mean to stay in state, not conditioned * average_time_to_terminal -Empirical mean time until death/recovery """ if 'consts_file' in configuration: consts = Consts.from_file(configuration['consts_file']) else: consts = Consts() if "circle_consts_file" in configuration: circle_const = CirclesConsts.from_file( configuration['circle_consts_file']) else: circle_const = CirclesConsts() population_size = configuration["monte_carlo_size"] medical_state_machine = consts.medical_state_machine() medical_machine_manager = MedicalStateManager( medical_state_machine=medical_state_machine) agents_list = _generate_agents_randomly(population_size=population_size, circle_consts=circle_const) _infect_all_agents(agents_list, medical_machine_manager, medical_state_machine) medical_states = medical_state_machine.states terminal_states = list(filter(_is_terminal_state, medical_states)) state_counter = Counter({m.name: m.agent_count for m in medical_states}) sum_days_to_terminal = 0 days_passed = 1 number_terminals_agents = 0 while number_terminals_agents != population_size: # No manager so we don't update it previous_terminal_agents = sum( [m.agent_count for m in terminal_states]) medical_machine_manager.step(list()) number_terminals_agents = sum([m.agent_count for m in terminal_states]) new_terminals = number_terminals_agents - previous_terminal_agents for m in medical_states: state_counter[m.name] += m.agent_count days_passed += 1 sum_days_to_terminal += days_passed * new_terminals average_state_time_duration, state_duration_expected_time = _get_empirical_state_times( medical_state_machine, population_size, state_counter) return dict(population_size=population_size, days_passed=days_passed, time_in_each_state=dict(state_counter), visitors_in_each_state={ m.name: len(m.ever_visited) for m in medical_state_machine.states }, average_duration_in_state=average_state_time_duration, state_duration_expected_time=state_duration_expected_time, average_time_to_terminal=sum_days_to_terminal / population_size)