Initial parameters
[ ]:
from blocksnet.optimization.services import (
TPEOptimizer,
WeightedObjective,
WeightedConstraints,
Facade,
BlockSolution,
GradientChooser,
AreaSolution,
)
from blocksnet.enums import LandUse
import numpy as np
import pandas as pd
import geopandas as gpd
import ast
import csv
Services
[ ]:
BASIC_SERVICES = {
"kindergarten": 0.2,
"school": 0.2,
"pharmacy": 0.2,
"polyclinics": 0.3,
"convenience": 0.2,
"cafe": 0.15,
"playground": 0.2,
"post": 0.1,
"hairdresser": 0.1
}
ADVANCED_SERVICES = {
"hospital": 0.5,
"supermarket": 0.4,
"restaurant": 0.3,
"park": 0.8,
"bank": 0.3,
"fuel": 0.25,
"police": 0.2,
"cinema": 0.2,
"market": 0.2,
"religion": 0.5,
"multifunctional_center": 0.1
}
COMFORT_SERVICES = {
"mall": 0.3,
"swimming_pool": 0.4,
"theatre": 0.2,
"museum": 0.2,
"university": 0.2,
"sanatorium": 0.2,
}
Block id for profiling
[ ]:
PROFILING_ID = 1536
City Initialization
[ ]:
blocks = gpd.read_parquet('./../../data/blocks.parquet')
columns = [c for c in blocks.columns if 'capacity_' in c]
blocks = blocks[['geometry', 'population', 'site_area', *columns]].copy()
blocks.head(3)
[ ]:
accessibility_matrix = pd.read_pickle('./../../data/accessibility_matrix.pickle')
accessibility_matrix.head()
Service weights
[ ]:
def get_service_weight(service_name):
if service_name in BASIC_SERVICES:
return 0.5714 * BASIC_SERVICES[service_name] / sum(BASIC_SERVICES.values())
elif service_name in ADVANCED_SERVICES:
return 0.2857 * ADVANCED_SERVICES[service_name] / sum(ADVANCED_SERVICES.values())
elif service_name in COMFORT_SERVICES:
return 0.1429 * COMFORT_SERVICES[service_name] / sum(COMFORT_SERVICES.values())
return 0
chosen_service_types = set(BASIC_SERVICES) | set(ADVANCED_SERVICES) | set(COMFORT_SERVICES)
service_weights = {service_type: get_service_weight(service_type) for service_type in chosen_service_types if f'capacity_{service_type}' in blocks.columns}
Save service to csv
[ ]:
def save_max_capacities(land_use: LandUse, facade: Facade):
with open(f'{land_use.name}_max_capacities.csv', 'w', newline='') as csvfile:
capacities = facade.get_max_capacities(PROFILING_ID)
writer = csv.writer(csvfile)
writer.writerow(["Service type", "Capacity required"]) # Write header row
for service, capacity in capacities.items():
writer.writerow([service, capacity])
[ ]:
import os
import shutil
from pathlib import Path
def move_csv_to_results():
results_dir = Path("./results")
results_dir.mkdir(exist_ok=True)
csv_files = [f for f in os.listdir() if f.endswith('.csv')]
for csv_file in csv_files:
src = Path(csv_file)
dest = results_dir / csv_file
shutil.move(str(src), str(dest))
Land use provision with selected services
[ ]:
from tqdm import tqdm
provision_data = {land_use: dict() for land_use in LandUse}
for land_use in LandUse:
blocks_lu = dict()
blocks_lu[PROFILING_ID] = land_use
var_adapter = AreaSolution(blocks_lu)
facade = Facade(
blocks_lu=blocks_lu,
blocks_df=blocks,
accessibility_matrix=accessibility_matrix,
var_adapter=var_adapter,
)
for service_type, weight in tqdm(service_weights.items()):
facade.add_service_type(service_type, weight, blocks.rename(columns={f'capacity_{service_type}': 'capacity'})[['capacity']])
start_prov = facade.start_provisions
objective = WeightedObjective(num_params=facade.num_params, facade=facade, weights=service_weights, max_evals=50)
constraints = WeightedConstraints(num_params=facade.num_params, facade=facade)
tpe_optimizer = TPEOptimizer(
objective=objective, constraints=constraints, vars_chooser=SimpleChooser(facade, facade.num_params, 5)
)
best_x, best_val, perc, func_evals = tpe_optimizer.run(max_runs=1000, timeout=60000, initial_runs_num=1)
solution_df = facade.solution_to_services_df(best_x)
solution_df.to_csv(f'{land_use.name}_services.csv')
save_max_capacities(land_use, facade)
df = pd.read_csv('tpe_provisions.csv')
best_provisions = None
max_val = 0
for index, row in df.iterrows():
if max_val < row['best_val']:
max_val = row['best_val']
best_provisions = row['provisions']
best_provisions = ast.literal_eval(best_provisions)
for service in facade._chosen_service_types:
if service in best_provisions.keys():
opt = best_provisions[service]
else:
opt = start_prov[service]
start = start_prov[service]
provision_data[land_use][service] = (start, opt)
move_csv_to_results()
break
[ ]:
with open('./results/provisions_data.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["Land use", "Service type", "Start provisions", "Opt. provisions", "Delta provisions"]) # Write header row
for land_use, services in provision_data.items():
for service_type, (start_prov, opt_prov) in services.items():
writer.writerow([land_use, service_type, start_prov, opt_prov, opt_prov - start_prov])