huffModel / app.py
serJD's picture
Update app.py
d53f142 verified
raw
history blame
4.81 kB
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)
# Initialize the visitors DataFrame
df_visitors = pd.DataFrame(0, index=df_distances.index, columns=df_distances.columns)
# Distribute the population over the iterations
df_population_per_iteration = df_population / iterations
# Run the iterative distribution process
for i in range(int(iterations)):
print("iteration " + str(i) + "/"+str(int(iterations)))
attractiveness = df_attractiveness.copy()
current_visitors = df_visitors.sum(axis=0)
# Calculate the decay based on the relative share of free capacity
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
# Calculate Huff model probabilities
print("Calculate Huff model probabilities")
distance_term = df_distances ** -beta
# If df_distances is a DataFrame and df_attractiveness is a Series, you might need an operation like:
numerator = df_distances.multiply(df_attractiveness, axis=0) # Adjust based on actual intent
denominator = numerator.sum(axis='columns')
probabilities = numerator.div(denominator, axis='index').fillna(0)
print("Distribute visitors based on probabilities and population")
# Distribute visitors based on probabilities and population
visitors_this_iteration = probabilities.multiply(df_population_per_iteration, axis='index')
# Adjust for excess visitors beyond capacity
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 the final distribution of visitors
return df_visitors
def app_function(input_json):
print("something happend")
# Parse the input JSON string
print(input_json)
try:
inputs = json.loads(input_json)
except:
inputs = json.loads(input_json.replace("'", '"'))
print(inputs.keys())
# navigate to payload
inputs = inputs["input"]
print(inputs.keys())
# Convert 'df_distances' from a list of lists into a DataFrame directly
df_distances = pd.DataFrame(inputs["df_distances"])
# 'inputs["df_attractiveness"]' and others are directly usable as lists
df_attractiveness = pd.Series(inputs["df_attractiveness"])
alpha = inputs["alpha"]
beta = inputs["beta"]
df_capacity = pd.Series(inputs["df_capacity"])
# Check if 'df_population' is provided and convert to Series
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)
# Assuming dynamic_huff_model function is correctly defined to accept these parameters
result = dynamic_huff_model(df_distances, df_attractiveness, alpha, beta, df_capacity, df_population, iterations, crowding_threshold)
print(result)
# Convert the result DataFrame to a JSON string for output
return result.to_json(orient='split')
# Define the Gradio interface with a single JSON input
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()