|
import gradio as gr |
|
import pandas as pd |
|
import numpy as np |
|
import json |
|
from io import StringIO |
|
|
|
|
|
def dynamic_huff_model(df_distances, df_attractiveness, alpha, beta, df_capacity, df_population=None, iterations=5, crowding_threshold=1.0): |
|
""" |
|
Iteratively calculates the distribution of people/visitors to destinations considering capacity and crowding based on an extended Huff model with linear decay function. |
|
|
|
Parameters: |
|
- df_distances, df_attractiveness, alpha, beta, df_capacity, df_population are the same as before. |
|
- iterations (int): The number of iterations to distribute the population. |
|
- crowding_threshold (float): The ratio of current visitors to capacity at which the decay of attractiveness starts. |
|
|
|
Returns: |
|
- pd.DataFrame: A DataFrame with the final distribution of visitors to each destination. |
|
""" |
|
if df_population is None: |
|
df_population = pd.Series(np.ones(df_distances.shape[0]), index=df_distances.index) |
|
|
|
|
|
df_visitors = pd.DataFrame(0, index=df_distances.index, columns=df_distances.columns) |
|
|
|
|
|
df_population_per_iteration = df_population / iterations |
|
|
|
|
|
for i in range(int(iterations)): |
|
print("iteration " + str(i) + "/"+str(int(iterations))) |
|
attractiveness = df_attractiveness.copy() |
|
current_visitors = df_visitors.sum(axis=0) |
|
|
|
|
|
print(" Calculate the decay based on the relative share of free capacity") |
|
relative_crowding = current_visitors / df_capacity |
|
decay_factor = np.where(relative_crowding < crowding_threshold, 1, 1 - (relative_crowding - crowding_threshold) / (1 - crowding_threshold)) |
|
attractiveness *= decay_factor |
|
|
|
|
|
print("Calculate Huff model probabilities") |
|
distance_term = df_distances ** -beta |
|
|
|
numerator = df_distances.multiply(df_attractiveness, axis=0) |
|
|
|
denominator = numerator.sum(axis='columns') |
|
probabilities = numerator.div(denominator, axis='index').fillna(0) |
|
|
|
print("Distribute visitors based on probabilities and population") |
|
|
|
visitors_this_iteration = probabilities.multiply(df_population_per_iteration, axis='index') |
|
|
|
|
|
potential_new_visitors = df_visitors + visitors_this_iteration |
|
excess_visitors = potential_new_visitors.sum(axis=0) - df_capacity |
|
excess_visitors[excess_visitors < 0] = 0 |
|
visitors_this_iteration -= visitors_this_iteration.multiply(excess_visitors, axis='columns') / visitors_this_iteration.sum(axis=0) |
|
|
|
df_visitors += visitors_this_iteration |
|
|
|
|
|
return df_visitors |
|
|
|
def app_function(input_json): |
|
print("something happend") |
|
|
|
print(input_json) |
|
|
|
try: |
|
inputs = json.loads(input_json) |
|
except: |
|
inputs = json.loads(input_json.replace("'", '"')) |
|
print(inputs.keys()) |
|
|
|
inputs = inputs["input"] |
|
|
|
print(inputs.keys()) |
|
|
|
df_distances = pd.DataFrame(inputs["df_distances"]) |
|
|
|
|
|
df_attractiveness = pd.Series(inputs["df_attractiveness"]) |
|
alpha = inputs["alpha"] |
|
beta = inputs["beta"] |
|
df_capacity = pd.Series(inputs["df_capacity"]) |
|
|
|
|
|
df_population = pd.Series(inputs["df_population"]) if "df_population" in inputs else None |
|
|
|
iterations = int(inputs.get("iterations", 5)) |
|
crowding_threshold = inputs.get("crowding_threshold", 1.0) |
|
|
|
|
|
result = dynamic_huff_model(df_distances, df_attractiveness, alpha, beta, df_capacity, df_population, iterations, crowding_threshold) |
|
print(result) |
|
|
|
return result.to_json(orient='split') |
|
|
|
|
|
iface = gr.Interface( |
|
fn=app_function, |
|
inputs=gr.Textbox(label="Input JSON", lines=20, placeholder="Enter JSON with all parameters here..."), |
|
outputs=gr.JSON(label="Output JSON"), |
|
title="Dynamic Huff Model" |
|
) |
|
|
|
iface.launch() |