File size: 5,005 Bytes
fa7b8b5 94ba0ac fa7b8b5 94ba0ac fa7b8b5 94ba0ac fa7b8b5 94ba0ac fa7b8b5 94ba0ac 3c2a2dc 94ba0ac fa7b8b5 94ba0ac fa7b8b5 94ba0ac fa7b8b5 b6f5dd4 94ba0ac b6f5dd4 94ba0ac e46c84a 94ba0ac 08aba45 94ba0ac 714bb14 94ba0ac fa7b8b5 714bb14 94ba0ac 714bb14 94ba0ac 714bb14 94ba0ac fa7b8b5 b1ead6c fa7b8b5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
import gradio as gr
import pandas as pd
import numpy as np
import json
from io import StringIO
def adjust_population_by_distance(df_distances, df_population, distance_threshold, decay_factor):
"""
Adjusts the population of each origin based on the distance to any destination, applying a decay effect for distances beyond the threshold.
Parameters:
- df_distances (pd.DataFrame): DataFrame with distances from origins to destinations.
- df_population (pd.Series): Series with population for each origin.
- distance_threshold (float): Distance beyond which the decay effect is applied.
- decay_factor (float): Factor controlling the rate of decay in willingness to travel beyond the threshold.
Returns:
- pd.Series: Adjusted population for each origin.
"""
# Calculate the minimum distance from each origin to any destination
min_distance = df_distances.min(axis=1)
# Adjust the population based on the minimum distance and the decay factor
def adjustment_factor(distance):
if distance > distance_threshold:
return np.exp(-(distance - distance_threshold) * decay_factor)
else:
return 1
adjustment_factors = min_distance.apply(adjustment_factor)
return df_population * adjustment_factors
def huff_model_probability(df_distances, df_attractiveness, alpha, beta, df_population=None, distance_threshold=None, decay_factor=0.1):
"""
Calculates the probability of choosing among destinations based on an enhanced Huff model that considers a willingness to travel threshold and applies a decay effect for distances beyond this threshold.
Parameters:
- df_distances (pd.DataFrame): DataFrame where rows are origins, columns are destinations, and values are distances.
- df_attractiveness (pd.Series): Series with attractiveness weights for each destination.
- alpha (float): Attractiveness parameter of the Huff model.
- beta (float): Distance decay parameter of the Huff model.
- df_population (pd.Series, optional): Series with population for each origin. Defaults to 1 if not provided.
- distance_threshold (float, optional): Distance beyond which the decay effect on willingness to travel is applied.
- decay_factor (float, optional): Factor controlling the rate of decay in willingness to travel beyond the threshold.
Returns:
- pd.DataFrame: DataFrame with probabilities of choosing each destination from each origin.
"""
if df_population is None:
df_population = pd.Series(np.ones(df_distances.shape[0]), index=df_distances.index)
if distance_threshold is not None:
df_population = adjust_population_by_distance(df_distances, df_population, distance_threshold, decay_factor)
attractiveness_term = df_attractiveness ** alpha
distance_term = df_distances ** -beta
numerator = (attractiveness_term * distance_term).multiply(df_population, axis=0)
denominator = numerator.sum(axis=1)
probabilities = numerator.div(denominator, axis=0)
return probabilities
def app_function(input_json):
print("Received input")
# Parse the input JSON string
try:
inputs = json.loads(input_json)
except json.JSONDecodeError:
inputs = json.loads(input_json.replace("'", '"'))
print("Parsed input keys:", inputs.keys())
# Assuming the input structure is correctly formatted to include the necessary parameters
inputs = inputs["input"]
# Convert 'df_distances' from a list of lists into a DataFrame
df_distances = pd.DataFrame(inputs["df_distances"])
print("df_distances shape:", df_distances.shape)
# Convert 'df_attractiveness' into a Series
df_attractiveness = pd.Series(inputs["df_attractiveness"])
print("df_attractiveness shape:", df_attractiveness.shape)
# Extract alpha and beta parameters
alpha = inputs["alpha"]
beta = inputs["beta"]
# Check if 'df_population' is provided and convert to Series, else default to None
df_population = pd.Series(inputs["df_population"]) if "df_population" in inputs else None
# Additional parameters for the updated Huff model
distance_threshold = inputs.get("distance_threshold", None)
decay_factor = inputs.get("decay_factor", 0.1) # Default decay factor if not provided
# Call the updated Huff model function
probabilities = huff_model_probability(
df_distances=df_distances,
df_attractiveness=df_attractiveness,
alpha=alpha,
beta=beta,
df_population=df_population,
distance_threshold=distance_threshold,
decay_factor=decay_factor
)
return probabilities.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() |