def check_if_has_holes(sln: RegionMap): districts = sln.districts for dist in districts: neighboring_districts = sln.get_neighboring_districts_of(dist) if len(neighboring_districts) > 1: continue units_on_region_border = dist.get_district_units_on_region_border() if len(units_on_region_border) == 0: return True return False
def create_neighboring_sln(cur_sln: RegionMap): """Generates a neighboring solution using the Ising models approach""" # if unit borders several districts, choose one of these districts randomly # decide randomly if unit should "go" to another district all_units = Units.units() for cur_unit in all_units: cur_district = cur_sln.find_district_by_unit(cur_unit) # if cur_unit is the only unit in the district, do not change cur_unit "membership" # (in favor of another district) if len(cur_district) <= 1: continue neighboring_districts_collection = cur_sln.get_neighboring_districts_of(cur_district) # find those districts that cur_unit borders districts_that_cur_unit_borders = [] for neighboring_district in neighboring_districts_collection: bordering_units = cur_district.get_units_bordering_that_district(neighboring_district) if cur_unit in bordering_units: districts_that_cur_unit_borders.append(neighboring_district) if len(districts_that_cur_unit_borders) == 0: continue random_district = rd.choice(districts_that_cur_unit_borders) cur_district.remove_unit(cur_unit) random_district.add_unit(cur_unit) # revert the move if it breaks contiguity or if the move creates holes if not check_if_contiguous(cur_district) or check_if_has_holes(cur_sln): random_district.remove_unit(cur_unit) cur_district.add_unit(cur_unit) return cur_sln