Exemple #1
0
    def drive(self,
              max_iterations=500,
              random_seed=0,
              initial_pop=50):
        """
        Args:
            max_iterations: Integer. The maximum number of iterations the
                simulation should run.
            random_seed: Integer. Seed for the random number generator.
            initial_pop: Integer. The initial population for the population.

        Returns:
            None.
        """

        # Dictionary to keep track of results
        self.results = defaultdict(list)

        # Seed the random number generator.
        random.seed(random_seed)

        # Create a dictionary that will hold the number of newborns that will
        # be added to the simulation.
        people_born = { k: 0 for k in range(9) }

        # Set the maximum number of iterations that the simulation will run.
        max_sim_time = max_iterations

        # Initialize a population.
        population = Population()

        # Initialize an air instance for modeling oxygen consumption.
        air = Air(population)

        # Initialize a power instance for modeling power consumption.
        power = Power(population)

        # Initial Iteration
        cur_sim_time = 0
        start = time.time()

        # Add initial population
        initial_ages = [10, 18, 20, 25, 28, 30, 32, 35, 40, 45, 50, 55]
        for add_count in range (initial_pop):
            init_age = cur_sim_time - initial_ages[add_count % len(initial_ages)]*12.0
            population.add_person(Person(init_age, population.get_rand_death_time(cur_sim_time), random.random()))
        print 'added', people_born.get(cur_sim_time % 9, 0), 'people in', time.time()-start

        start = time.time()
        total_kcal = population.kcal_requirements(cur_sim_time)
        print 'completed total kcal in:', time.time() - start

        # Create a facility for population
        # Crop area of 25000 feeds about 30 people
        facility = Facility(30000.0/30.0*(initial_pop+30), initial_pop+30)

        # Food initialization
        food = Food(facility, total_kcal)

        # Create a disaster object for the population - this models uncertainty
        # events that may adversely affect the population & food
        disaster = Disaster(population, food)

        # Write initial loop results
        self._write_results(population=population.num_people(),
                            food=food.produced_food,
                            kcals=total_kcal,
                            facility_crop=facility.crop_area,
                            facility_personnel=facility.personnel_capacity,
                            air=air.oxygen_consumed(),
                            power=power.power_consumed())

        # Main iteration loop
        for cur_sim_time in range(1, max_sim_time):
            print 'current sim time:', cur_sim_time
            start = time.time()

            # Diasters
            if random.random() <= 0.01:
                #ratio = random.random()/10.0
                #disaster.create_disaster(ratio)
                #print 'DISASTER killed', ratio, 'in:', time.time() - start
                death_from_disaster = random.randint(1,20)
                disaster.create_disaster(death_from_disaster)
                print 'DISASTER killed', death_from_disaster, 'people and', (death_from_disaster+10)*2500.0, 'food in:', time.time() - start
                start = time.time()

            # If enough food, expand facility. Assume 3 month build time
            if food.remaining_food > 2500*10 and (facility.personnel_capacity - population.num_people()) <= 10:
                facility.start_pod_construction(cur_sim_time, 3)
                facility.add_pod(cur_sim_time)

            # Adding newborns
            born_count = 0
            for add_count in range (people_born.get(cur_sim_time % 9, 0)):
                if population.num_people() < facility.personnel_capacity:
                    population.add_person(Person(cur_sim_time, population.get_rand_death_time(cur_sim_time), random.random()))
                    born_count += 1
            print 'added', born_count, 'people in', time.time()-start

            # Removing the dead
            start = time.time()
            people_to_kill = len(population.death_dict.get(cur_sim_time, []))
            population.remove_dead(cur_sim_time)
            print 'removed', people_to_kill, 'people in:', time.time() - start

            # Calculating total kcal
            start = time.time()
            total_kcal = population.kcal_requirements(cur_sim_time)
            print 'completed total kcal in:', time.time() - start

            # Food consumption
            food_delta = food.update_food(total_kcal)
            print 'produced food = ', food.produced_food, '; remaining food = ', food.remaining_food
            # if not enough food
            if food_delta < 0:
                # people who are unfed will die, starting with oldest people
                while (food_delta < 0):
                    food_delta = food_delta + population.people[0].kcal_requirements(cur_sim_time)
                    population.remove_person(0)
                population.generate_death_dict()

            # Calculating how many newborns to be created in 9 months time
            num_people = population.num_people()
            num_adults = population.num_adults(cur_sim_time)
            # newborns based on number of adults. Average US birthrate in 2014: 0.01342 (indexmundi.com)
            people_born[cur_sim_time % 9] = random.randint(np.rint(num_adults*0.01),np.rint(num_adults*0.020))
            print 'total people:', num_people, 'and total adults:', num_adults, 'and total kcal:', total_kcal
            print 'total capacity:', facility.personnel_capacity

            print('-'*100)

            # Record results of the iteration.
            self._write_results(population=num_people,
                                food=food.produced_food,
                                kcals=total_kcal,
                                facility_crop=facility.crop_area,
                                facility_personnel=facility.personnel_capacity,
                                air=air.oxygen_consumed(),
                                power=power.power_consumed())

            # If the visualization option has been selected, plot the results
            # every 10 timesteps.
            if self.vis and cur_sim_time % 10 == 0:

                # Add data for the chart.
                self.vis.add_data(cur_sim_time, {
                    'Population Count': num_people,
                    'Adult Count': num_adults,
                    'Caloric Requirements (Mcal)': total_kcal / 1000.0,
                    'Produced Food (Mcal)': food.produced_food / 1000.0,
                    'Air (kg O2)': air.oxygen_consumed(),
                    'Power Consumption (kWh)': power.power_consumed()
                })

                # Update the chart, re-rendering.
                self.vis.update()

        # If visualization has been selected,
        if self.vis:
            # Save the last rendered chart as a png image.
            self.vis.savefig()

        # Return the results dict.
        return self.results