Ejemplo n.º 1
0
 def __init__(self, capacity, restaurant_type, is_outdoor, covid_model,
              strid_prefix, strid_suffix, **kwargs):
     super().__init__(covid_model, strid_prefix, strid_suffix)
     outdoor = True
     indoor = False
     # https://docs.google.com/document/d/1imCNXOyoyecfD_sVNmKpmbWVB6xqP-FWlHELAyOg1Vs/edit
     base_fast_food = beta_range(0.014, 0.1)  # normal_ci(0.014, 0.1, 10)
     base_fancy = beta_range(0.07, 0.2)  # normal_ci(0.07, 0.2, 10)
     base_bar = beta_range(0.174, 0.796)  # normal_ci(0.174, 0.796, 10)
     cp = {
         RestaurantType.FAST_FOOD: {
             indoor: base_fast_food,
             outdoor: base_fast_food / 2
         },
         RestaurantType.FANCY: {
             indoor: base_fancy,
             outdoor: base_fancy / 2
         },
         RestaurantType.BAR: {
             indoor: base_bar,
             outdoor: base_bar / 2
         }
     }
     self.capacity = capacity
     self.available = capacity
     self.restaurant_type = restaurant_type
     self.is_outdoor = is_outdoor
     self.set_custom_parameters(
         [('contagion_probability', cp[restaurant_type][is_outdoor])],
         kwargs)
Ejemplo n.º 2
0
 def step(self):
     super().step()
     capacity = self.get_parameter('allowed_restaurant_capacity')
     ci = {1.0: (0.19, 1.23), 0.5: (0.11, 0.74), 0.25: (0.08, 0.50)}
     # https://docs.google.com/document/d/1imCNXOyoyecfD_sVNmKpmbWVB6xqP-FWlHELAyOg1Vs/edit
     lb, ub = ci[capacity]
     self.spreading_rate = beta_range(lb, ub)  # normal_ci(lb, ub, 20)
     if self.covid_model.current_state == SimulationState.POST_WORK_ACTIVITY:
         self.spread_infection()
Ejemplo n.º 3
0
def setup_grid_layout(model, population_size, home_grid_height,
                      home_grid_width, work_height, work_width, school_height,
                      school_width):
    #Makes a grid of homogeneous home districts, overlaid by school and work districts.
    #home_grid_height is the number of home districts high the grid is, and
    #home_grid_width is the nmber of home districts wide the grid is
    #school height and work height are how many home districts high a school
    #district and work are respectively, and the same for their length.
    #each begins in grid 0,0 and cover the orignal home district grid.
    #Persons assigned to the home districts are also assigned to the school
    #and work districts that cover them. The parameters determine the amount
    #of leakage across groups of people.  With parameters (10,10,1,1,1,1) you get 100
    #completely separated districts with no leakage.  With parameters (6,6,2,2,3,3) you
    #get a grid where every one is connected to everyone else, but there is a
    #degree of separation.  For example, a person in home district (0,0) can be infected
    #by a person in (5,5) but it would be bridged by three infections, slowing the
    #virus down.  Larger sizes for work and school districts enable faster spread. Fastest
    #spread occurs with parameters (1,1,1,1,1,1) or equivalently (10,10, 10,10,10,10)
    #or any of the same number
    #Since this is just a way to allocate human interactions, no label is needed and
    #the grid need not be saved, for interactions to occur, although this inforamtion
    #may be useful for visualizations.
    work_building_capacity = 20
    office_capacity = 10
    work_building_occupacy_rate = 0.5
    appartment_building_capacity = 20
    appartment_capacity = 5
    appartment_building_occupacy_rate = 0.5
    school_capacity = 50
    classroom_capacity = 20
    school_occupacy_rate = 0.5

    # Build empty districts
    # https://docs.google.com/document/d/1imCNXOyoyecfD_sVNmKpmbWVB6xqP-FWlHELAyOg1Vs/edit

    home_districts = []
    work_districts = []
    school_districts = []
    school_map = {}
    work_map = {}
    school_grid_height = math.ceil(home_grid_height / school_height)
    school_grid_width = math.ceil(home_grid_width / school_width)
    work_grid_height = math.ceil(home_grid_height / work_height)
    work_grid_width = math.ceil(home_grid_width / work_width)

    for hw in range(home_grid_width):
        for hh in range(home_grid_height):

            home_district = build_district(
                f"Home ({hh},{hw})", model, population_size,
                appartment_building_capacity,
                appartment_capacity, appartment_building_occupacy_rate,
                beta_range(0.021, 0.12))  # normal_ci(0.021, 0.12, 10)

            home_district.debug = model.debug

            home_districts.append(home_district)
            home_number = hw * home_grid_height + hh
            assert home_number == len(home_districts) - 1

            sh = hh // school_height
            sw = hw // school_width
            school_number = sw * school_grid_height + sh
            school_map[home_number] = school_number

            wh = hh // work_height
            ww = hw // work_width
            work_number = ww * work_grid_height + wh
            work_map[home_number] = work_number

    for ww in range(work_grid_width):
        for wh in range(work_grid_height):

            work_district = build_district(
                f"Work ({wh},{ww})", model, population_size,
                work_building_capacity,
                office_capacity, work_building_occupacy_rate,
                beta_range(0.007, 0.06))  # normal_ci(0.007, 0.06, 10)
            # Add Restaurants to work_district

            for i in range(get_parameters().
                           params['restaurant_count_per_work_district']):
                if flip_coin(0.5):
                    restaurant_type = RestaurantType.FAST_FOOD
                    rtype = "FASTFOOD"
                else:
                    restaurant_type = RestaurantType.FANCY
                    rtype = "FANCY"
                restaurant = Restaurant(
                    normal_cap(
                        get_parameters().params['restaurant_capacity_mean'],
                        get_parameters().params['restaurant_capacity_stdev'],
                        16, 200), restaurant_type, flip_coin(0.5), model, '',
                    rtype + '-' + str(i) + f"({wh},{ww})")
                work_district.locations.append(restaurant)
            for i in range(2):
                bar = Restaurant(normal_cap(100, 20, 50,
                                            200), RestaurantType.BAR,
                                 flip_coin(0.5), model, '',
                                 'BAR-' + str(i) + f"({wh},{ww})")
                work_district.locations.append(bar)
            work_district.debug = model.debug
            work_districts.append(work_district)

    for sw in range(school_grid_width):
        for sh in range(school_grid_height):

            school_district = build_district(
                f"School ({sh},{sw})", model, population_size, school_capacity,
                classroom_capacity, school_occupacy_rate,
                beta_range(0.014, 0.08))  # normal_ci(0.014, 0.08, 10)

            school_district.debug = model.debug
            school_districts.append(school_district)

    #print ("work_map")
    #print (work_map)
    #print ("school_map")
    #print (school_map)

    # Build families

    family_factory = FamilyFactory(model)
    family_factory.factory(population_size)
    model.global_count.total_population = family_factory.human_count

    # print(family_factory)

    age_group_sets = {
        Infant: [],
        Toddler: [],
        K12Student: [],
        Adult: [],
        Elder: []
    }

    # Allocate buildings to people
    #print ("home_districts")
    #print (home_districts)
    #print ("work_districts")
    #print (work_districts)
    #print ("school_districts")
    #print (school_districts)

    all_adults = []
    all_students = []
    for family in family_factory.families:
        adults = [human for human in family if isinstance(human, Adult)]
        students = [human for human in family if isinstance(human, K12Student)]
        home_district_num = np.random.randint(0, len(home_districts))
        #print("home_district_num")
        #print(home_district_num)
        home_district = home_districts[home_district_num]
        work_district = work_districts[work_map[home_district_num]]
        school_district = school_districts[school_map[home_district_num]]

        home_district.allocate(family, True, True, True)
        work_district.allocate(adults)
        school_district.allocate(students, True)
        for human in family:
            age_group_sets[type(human)].append(human)
            human.home_district = home_district
            home_district.get_buildings(human)[0].get_unit(
                human).humans.append(human)
        for adult in adults:
            adult.work_district = work_district
            all_adults.append(adult)
        for student in students:
            student.school_district = school_district
            all_students.append(student)

    # Set tribes

    adult_rf = HomophilyRelationshipFactory(model, all_adults)
    student_rf = HomophilyRelationshipFactory(model, all_students)
    # exit()

    count = 0
    for family in family_factory.families:
        for human in family:
            work_district = human.work_district
            school_district = human.school_district
            count += 1
            human.tribe[TribeSelector.AGE_GROUP] = age_group_sets[type(human)]
            human.tribe[TribeSelector.FAMILY] = family
            if isinstance(human, Adult):
                human.unique_id = "Adult" + str(count)
                #print(work_district.get_buildings(human))
                #print(work_district.get_buildings(human))
                #print(workd_district.get_buildings(human)[0].get_unit(human))
                #print(workd_district.get_buildings(human)[0].get_unit(human))
                human.tribe[
                    TribeSelector.COWORKER] = work_district.get_buildings(
                        human)[0].get_unit(human).allocation
                t1 = adult_rf.build_tribe(human,
                                          human.tribe[TribeSelector.COWORKER],
                                          1, office_capacity)
                t2 = adult_rf.build_tribe(human,
                                          human.tribe[TribeSelector.AGE_GROUP],
                                          1, 20)
                human.tribe[TribeSelector.FRIEND] = t1
                for h in t2:
                    if h not in human.tribe[TribeSelector.FRIEND]:
                        human.tribe[TribeSelector.FRIEND].append(h)
            elif isinstance(human, K12Student):
                human.unique_id = "K12Student" + str(count)
                human.tribe[
                    TribeSelector.CLASSMATE] = school_district.get_buildings(
                        human)[0].get_unit(human).allocation
                t1 = student_rf.build_tribe(
                    human, human.tribe[TribeSelector.CLASSMATE], 1,
                    classroom_capacity)
                t2 = student_rf.build_tribe(
                    human, human.tribe[TribeSelector.AGE_GROUP], 1, 20)
                human.tribe[TribeSelector.FRIEND] = t1
                for h in t2:
                    if h not in human.tribe[TribeSelector.FRIEND]:
                        human.tribe[TribeSelector.FRIEND].append(h)
            elif isinstance(human, Elder):
                human.unique_id = "Elder" + str(count)
            elif isinstance(human, Infant):
                human.unique_id = "Infant" + str(count)
            elif isinstance(human, Toddler):
                human.unique_id = "Toddler" + str(count)
Ejemplo n.º 4
0
def setup_city_layout(model, population_size):
    work_building_capacity = 20
    office_capacity = 10
    work_building_occupacy_rate = 0.5
    appartment_building_capacity = 20
    appartment_capacity = 5
    appartment_building_occupacy_rate = 0.5
    school_capacity = 50
    classroom_capacity = 20
    school_occupacy_rate = 0.5

    # Build empty districts
    # https://docs.google.com/document/d/1imCNXOyoyecfD_sVNmKpmbWVB6xqP-FWlHELAyOg1Vs/edit
    home_district = build_district(
        "Home", model, population_size, appartment_building_capacity,
        appartment_capacity, appartment_building_occupacy_rate,
        beta_range(0.021, 0.12))  # normal_ci(0.021, 0.12, 10)
    work_district = build_district(
        "Work", model, population_size,
        work_building_capacity, office_capacity, work_building_occupacy_rate,
        beta_range(0.007, 0.06))  # normal_ci(0.007, 0.06, 10)
    school_district = build_district(
        "School", model, population_size,
        school_capacity, classroom_capacity, school_occupacy_rate,
        beta_range(0.014, 0.08))  # normal_ci(0.014, 0.08, 10)

    home_district.debug = model.debug
    work_district.debug = model.debug
    school_district.debug = model.debug

    # Add Restaurants to work_district

    for i in range(
            get_parameters().params['restaurant_count_per_work_district']):
        if flip_coin(0.5):
            restaurant_type = RestaurantType.FAST_FOOD
            rtype = "FASTFOOD"
        else:
            restaurant_type = RestaurantType.FANCY
            rtype = "FANCY"
        restaurant = Restaurant(
            normal_cap(get_parameters().params['restaurant_capacity_mean'],
                       get_parameters().params['restaurant_capacity_stdev'],
                       16, 200), restaurant_type, flip_coin(0.5), model, '',
            rtype + '-' + str(i))
        work_district.locations.append(restaurant)
    for i in range(2):
        bar = Restaurant(normal_cap(100, 20, 50, 200), RestaurantType.BAR,
                         flip_coin(0.5), model, '', 'BAR-' + str(i))
        work_district.locations.append(bar)

    # print(home_district)
    # print(work_district)
    # print(school_district)

    # Build families

    family_factory = FamilyFactory(model)
    family_factory.factory(population_size)
    model.global_count.total_population = family_factory.human_count

    # print(family_factory)

    age_group_sets = {
        Infant: [],
        Toddler: [],
        K12Student: [],
        Adult: [],
        Elder: []
    }

    # Allocate buildings to people

    all_adults = []
    all_students = []
    for family in family_factory.families:
        adults = [human for human in family if isinstance(human, Adult)]
        students = [human for human in family if isinstance(human, K12Student)]
        home_district.allocate(family, True, True, True)
        work_district.allocate(adults)
        school_district.allocate(students, True)
        for human in family:
            age_group_sets[type(human)].append(human)
            human.home_district = home_district
            home_district.get_buildings(human)[0].get_unit(
                human).humans.append(human)
        for adult in adults:
            adult.work_district = work_district
            all_adults.append(adult)
        for student in students:
            student.school_district = school_district
            all_students.append(student)

    # Set tribes

    adult_rf = HomophilyRelationshipFactory(model, all_adults)
    student_rf = HomophilyRelationshipFactory(model, all_students)
    # exit()

    count = 0
    for family in family_factory.families:
        for human in family:
            count += 1
            human.tribe[TribeSelector.AGE_GROUP] = age_group_sets[type(human)]
            human.tribe[TribeSelector.FAMILY] = family
            if isinstance(human, Adult):
                human.unique_id = "Adult" + str(count)
                human.tribe[
                    TribeSelector.COWORKER] = work_district.get_buildings(
                        human)[0].get_unit(human).allocation
                t1 = adult_rf.build_tribe(human,
                                          human.tribe[TribeSelector.COWORKER],
                                          1, office_capacity)
                t2 = adult_rf.build_tribe(human,
                                          human.tribe[TribeSelector.AGE_GROUP],
                                          1, 20)
                human.tribe[TribeSelector.FRIEND] = t1
                for h in t2:
                    if h not in human.tribe[TribeSelector.FRIEND]:
                        human.tribe[TribeSelector.FRIEND].append(h)
            elif isinstance(human, K12Student):
                human.unique_id = "K12Student" + str(count)
                human.tribe[
                    TribeSelector.CLASSMATE] = school_district.get_buildings(
                        human)[0].get_unit(human).allocation
                t1 = student_rf.build_tribe(
                    human, human.tribe[TribeSelector.CLASSMATE], 1,
                    classroom_capacity)
                t2 = student_rf.build_tribe(
                    human, human.tribe[TribeSelector.AGE_GROUP], 1, 20)
                human.tribe[TribeSelector.FRIEND] = t1
                for h in t2:
                    if h not in human.tribe[TribeSelector.FRIEND]:
                        human.tribe[TribeSelector.FRIEND].append(h)
            elif isinstance(human, Elder):
                human.unique_id = "Elder" + str(count)
            elif isinstance(human, Infant):
                human.unique_id = "Infant" + str(count)
            elif isinstance(human, Toddler):
                human.unique_id = "Toddler" + str(count)
Ejemplo n.º 5
0
    latency_period_shape=2,
    latency_period_scale=1,
    incubation_period_shape=4,
    incubation_period_scale=1,
    mild_period_duration_shape=14,
    mild_period_duration_scale=1,
    hospitalization_period_duration_shape=12,
    hospitalization_period_duration_scale=1,
    symptomatic_isolation_rate=0.0,
    asymptomatic_contagion_probability=0.1,
    risk_tolerance_mean=0.7,
    risk_tolerance_stdev=0.2,
    herding_behavior_mean=0.7,
    herding_behavior_stdev=0.2,
    allowed_restaurant_capacity=1.0,  # valid values: {1.0, 0.50, 0.25}
    spreading_rate=beta_range(2.41, 3.90)  # normal_ci(2.41, 3.90, 20)
)

# Simulation

population_size = 1000
simulation_cycles = 90  # days

################################################################################
# Scenarios

scenario = {}

# ------------------------------------------------------------------------------

sc = 1  # Do nothing
Ejemplo n.º 6
0
    def __init__(self, city, population_size, model):

        self.work_zones = [
            'GM', 'IC', 'GR', 'CS', 'HC', 'O-1', 'O-2', 'LI', 'HM', 'GI', 'LB',
            'WC-1', 'WC-2', 'WC-3', 'RI', 'CC', 'COM-1', 'COM-2', 'CNTY-A-1',
            'CNTY-M-1', 'CNTY-C-2'
        ]
        self.home_zones = [
            'R-SF', 'R-LD', 'R-TH', 'R-MD', 'CNTY-R-1', 'R-MHC', 'R-HD'
        ]
        self.unused_zones = ['PD', 'CNTY-PAD', None]

        home_low_density_capacity = 20
        home_medium_density_capacity = 150
        home_high_density_capacity = 450

        family_capacity_per_building = {
            'R-SF': 1,
            'R-LD': home_low_density_capacity,
            'R-TH': home_low_density_capacity,
            'R-MD': home_medium_density_capacity,
            'CNTY-R-1': home_medium_density_capacity,
            'R-MHC': home_medium_density_capacity,
            'R-HD': home_high_density_capacity
        }
        family_capacity = {}

        self.model = model
        self.population_size = population_size
        self.zone_centroid = {}
        self.work_building_ids = []
        self.home_building_ids = []
        self.school_building_ids = []
        self.restaurant_building_ids = []
        self.home_building = {}
        self.work_building = {}
        self.school_building = {}
        self.restaurant_building = {}
        self.restaurant_distances = {}
        self.school_distances = {}
        self.work_zone_distances = {}
        self.restaurant_roulette = {}
        self.school_roulette = {}
        self.work_zone_roulette = {}
        self.sigma = get_parameters(
        ).params['real_sites_roulette_rescale_sigma']
        self.kappa = get_parameters(
        ).params['real_sites_roulette_rescale_kappa']

        home_district = District('HomeDistrict', model, '', '')
        work_district = District('WorkDistrict', model, '', '')
        school_district = District('SchoolDistrict', model, '', '')
        restaurant_district = District('RestaurantDistrict', model, '', '')
        with open(f'mesa-geo/examples/GeoSIR/{city}/neighborhoods.geojson'
                  ) as json_file:
            self.neighborhoods = json.load(json_file)
            self.neighborhoods_count = len(self.neighborhoods['features'])
            print(
                f"Total number of neighboorhoods: {self.neighborhoods_count}")
        with open(f'mesa-geo/examples/GeoSIR/{city}/schools.geojson'
                  ) as json_file:
            self.schools = json.load(json_file)
            self.schools_count = len(self.schools['features'])
            for school in self.schools['features']:
                bid = str(school['properties']['OBJECTID'])
                self.school_building_ids.append(bid)
                self.school_building[bid] = HomogeneousBuilding(
                    1000000, model, 'School', bid)
                school_district.locations.append(self.school_building[bid])
            print(f"Total number of schools: {self.schools_count}")
        with open(f'mesa-geo/examples/GeoSIR/{city}/zoning.geojson'
                  ) as json_file:
            self.buildings = json.load(json_file)
            print(
                f"Total number of buildings: {len(self.buildings['features'])}"
            )
            self.all_zones_coordinates = []
            for building in self.buildings['features']:
                bid = str(building['properties']['OBJECTID'])
                self.zone_centroid[bid] = self.compute_centroid(building)
                zone = building['properties']['PLANZONE']
                if building['geometry']['type'] == 'Polygon':
                    self.all_zones_coordinates.append(
                        building['geometry']['coordinates'][0])
                elif building['geometry']['type'] == 'MultiPolygon':
                    for v in building['geometry']['coordinates']:
                        self.all_zones_coordinates.append(v[0])
                else:
                    assert False
                if zone in self.work_zones:
                    self.work_building_ids.append(bid)
                    self.work_building[bid] = HomogeneousBuilding(
                        1000000, model, 'Work', bid)
                    work_district.locations.append(self.work_building[bid])
                elif zone in self.home_zones:
                    family_capacity[bid] = family_capacity_per_building[zone]
                    self.home_building_ids.append(bid)
                    self.home_building[bid] = HomogeneousBuilding(
                        family_capacity[bid], model, 'Home', bid)
                    home_district.locations.append(self.home_building[bid])
                elif zone not in self.unused_zones:
                    print(f"Unknown zone type: {zone}")
                    exit()
        self.restaurants = self.create_geo_restaurants(self.buildings)
        self.restaurants_count = len(self.restaurants['features'])
        for restaurant in self.restaurants['features']:
            bid_int = restaurant['properties']['OBJECTID']
            bid = str(bid_int)
            self.restaurant_building_ids.append(bid)
            self.restaurant_building[bid] = self.create_restaurant_location(
                bid_int, flip_coin(0.1))
            restaurant_district.locations.append(self.restaurant_building[bid])
        print(f"Total number of restaurants: {self.restaurants_count}")
        with open('restaurants.geojson', 'w') as fp:
            json.dump(self.restaurants, fp)

        distance_cache_file = f'mesa-geo/examples/GeoSIR/{city}/distances_{self.sigma}_{self.kappa}.json'
        if os.path.isfile(distance_cache_file):
            with open(distance_cache_file) as json_file:
                table = json.load(json_file)
            self.restaurant_distances = table['restaurant_distances']
            self.school_distances = table['school_distances']
            self.work_zone_distances = table['work_zone_distances']
            self.restaurant_roulette = table['restaurant_roulette']
            self.school_roulette = table['school_roulette']
            self.work_zone_roulette = table['work_zone_roulette']
        else:
            self.compute_restaurant_distances()
            self.compute_school_distances()
            self.compute_work_zone_distances()
            table = {}
            table['restaurant_distances'] = self.restaurant_distances
            table['school_distances'] = self.school_distances
            table['work_zone_distances'] = self.work_zone_distances
            table['restaurant_roulette'] = self.restaurant_roulette
            table['school_roulette'] = self.school_roulette
            table['work_zone_roulette'] = self.work_zone_roulette
            with open(distance_cache_file, 'w') as json_file:
                json.dump(table, json_file)

        family_factory = FamilyFactory(model)
        family_factory.factory(population_size)
        model.global_count.total_population = family_factory.human_count
        print(f"Total number of families: {len(family_factory.families)}")
        #count_family = 0
        for family in family_factory.families:
            #if count_family % 1000 == 0: print(f"{count_family} {datetime.datetime.now()}")
            #count_family += 1
            assert len(self.home_building_ids) > 0
            home_bid = random_selection(self.home_building_ids)
            selected_home_build = self.home_building[home_bid]
            home_unit = BuildingUnit(10,
                                     model,
                                     home_bid,
                                     '',
                                     contagion_probability=beta_range(
                                         0.021, 0.12))
            family_capacity[home_bid] -= 1
            if family_capacity[home_bid] == 0:
                self.home_building_ids.remove(home_bid)
            selected_home_build.locations.append(home_unit)
            for human in family:
                # Home
                human.home_district = home_district
                home_district.allocation[human] = [selected_home_build]
                home_unit.allocation.append(human)
                selected_home_build.allocation[human] = home_unit
                assert home_district.get_buildings(human)[0].get_unit(
                    human) == home_unit
                home_unit.humans.append(human)
                # Work
                if isinstance(human, Adult):
                    human.work_district = work_district
                    #work_bid = random_selection(self.work_building_ids)
                    work_bid = roulette_selection(
                        self.work_zone_distances[home_bid]['work_zone_bid'],
                        self.work_zone_distances[home_bid]['distance'],
                        roulette=self.work_zone_roulette[home_bid])
                    selected_work_building = self.work_building[work_bid]
                    work_unit = selected_work_building.locations[-1] if selected_work_building.locations and\
                        len(work_unit.allocation) < work_unit.capacity else None
                    if work_unit is None:
                        work_unit = BuildingUnit(
                            10,
                            model,
                            work_bid,
                            '',
                            contagion_probability=beta_range(0.007, 0.06))
                        selected_work_building.locations.append(work_unit)
                    work_district.allocation[human] = [selected_work_building]
                    work_unit.allocation.append(human)
                    selected_work_building.allocation[human] = work_unit
                    assert work_district.get_buildings(human)[0].get_unit(
                        human) == work_unit
                # School
                if isinstance(human, K12Student):
                    human.school_district = school_district
                    #work_bid = random_selection(self.school_building_ids)
                    school_bid = roulette_selection(
                        self.school_distances[home_bid]['school_bid'],
                        self.school_distances[home_bid]['distance'],
                        roulette=self.school_roulette[home_bid])
                    selected_school_building = self.school_building[school_bid]
                    school_unit = selected_school_building.locations[-1] if selected_school_building.locations and\
                        len(school_unit.allocation) < school_unit.capacity else None
                    if school_unit is None:
                        school_unit = BuildingUnit(
                            20,
                            model,
                            school_bid,
                            '',
                            contagion_probability=beta_range(0.014, 0.08))
                        selected_school_building.locations.append(school_unit)
                    school_district.allocation[human] = [
                        selected_school_building
                    ]
                    school_unit.allocation.append(human)
                    selected_school_building.allocation[human] = school_unit
                    assert school_district.get_buildings(human)[0].get_unit(
                        human) == school_unit
                # Restaurants
                if isinstance(human, Adult):
                    #bids = [random_selection(self.restaurant_building_ids) for i in range(10)]
                    bids = roulette_selection(
                        self.restaurant_distances[work_bid]['restaurant_bid'],
                        self.restaurant_distances[work_bid]['distance'],
                        10,
                        roulette=self.restaurant_roulette[work_bid])
                    human.preferred_restaurants = [
                        self.restaurant_building[bid] for bid in bids
                    ]