path2 / app.py
Isha184's picture
Update app.py
8a63926 verified
import json
import gradio as gr
import pandas as pd
from solver import (
generate_random_instance,
solve_vrp,
plot_solution,
parse_uploaded_csv,
make_template_dataframe,
)
TITLE = "Ride-Sharing Optimizer (Capacitated VRP) β€” Gradio Demo"
DESC = """
This demo assigns **stops (riders)** to **drivers (vehicles)** with a simple, fast heuristic:
**Sweep clustering** β†’ **Greedy routing** β†’ **2-opt improvement**.
You can **generate a sample** dataset or **upload a CSV** with columns:
`id,x,y,demand,tw_start,tw_end,service`.
- **Capacity** = max riders per vehicle (sum of `demand` per route).
- **Time windows** are *soft* (violations are reported in metrics).
- Distances are Euclidean on the X-Y plane for clarity.
πŸ’‘ Tip: Start with the generator, then switch to your CSV.
"""
FOOTER = "Made with ❀️ using Gradio. No native dependencies; runs quickly on Spaces."
# -----------------------------
# Functions
# -----------------------------
def run_generator(n_clients, n_vehicles, capacity, spread, demand_min, demand_max, seed):
df = generate_random_instance(
n_clients=n_clients,
n_vehicles=n_vehicles,
capacity=capacity,
spread=spread,
demand_min=demand_min,
demand_max=demand_max,
seed=seed,
)
depot = (0.0, 0.0)
sol = solve_vrp(df, depot=depot, n_vehicles=n_vehicles, capacity=capacity, speed=1.0)
# βœ… plot_solution now returns a PIL image
img = plot_solution(df, sol, depot=depot)
route_table = sol["assignments_table"]
metrics = json.dumps(sol["metrics"], indent=2)
return img, route_table, metrics, df
def run_csv(file, n_vehicles, capacity):
if file is None:
raise gr.Error("Please upload a CSV first.")
try:
df = parse_uploaded_csv(file)
except Exception as e:
raise gr.Error(f"CSV parsing error: {e}")
depot = (0.0, 0.0)
sol = solve_vrp(df, depot=depot, n_vehicles=n_vehicles, capacity=capacity, speed=1.0)
img = plot_solution(df, sol, depot=depot)
route_table = sol["assignments_table"]
metrics = json.dumps(sol["metrics"], indent=2)
return img, route_table, metrics
def download_template():
return make_template_dataframe()
# -----------------------------
# UI Layout
# -----------------------------
with gr.Blocks(title=TITLE) as demo:
gr.Markdown(f"# {TITLE}")
gr.Markdown(DESC)
with gr.Tab("πŸ”€ Generate sample"):
with gr.Row():
with gr.Column():
n_clients = gr.Slider(5, 200, value=30, step=1, label="Number of riders (clients)")
n_vehicles = gr.Slider(1, 20, value=4, step=1, label="Number of drivers (vehicles)")
capacity = gr.Slider(1, 50, value=10, step=1, label="Vehicle capacity (sum of demand)")
spread = gr.Slider(10, 200, value=50, step=1, label="Spatial spread (larger = wider map)")
demand_min = gr.Slider(1, 5, value=1, step=1, label="Min demand per stop")
demand_max = gr.Slider(1, 10, value=3, step=1, label="Max demand per stop")
seed = gr.Slider(0, 9999, value=42, step=1, label="Random seed")
run_btn = gr.Button("πŸš— Generate & Optimize", variant="primary")
with gr.Column():
img = gr.Image(type="pil", label="Route Visualization", interactive=False)
with gr.Row():
route_df = gr.Dataframe(label="Route assignments (per stop)", wrap=True)
metrics = gr.Code(label="Metrics (JSON)")
with gr.Accordion("Show generated dataset", open=False):
data_out = gr.Dataframe(label="Generated input data")
run_btn.click(
fn=run_generator,
inputs=[n_clients, n_vehicles, capacity, spread, demand_min, demand_max, seed],
outputs=[img, route_df, metrics, data_out],
)
with gr.Tab("πŸ“„ Upload CSV"):
with gr.Row():
with gr.Column():
file = gr.File(label="Upload CSV (id,x,y,demand,tw_start,tw_end,service)")
dl_tmp = gr.Button("Get CSV Template")
n_vehicles2 = gr.Slider(1, 50, value=5, step=1, label="Number of drivers (vehicles)")
capacity2 = gr.Slider(1, 200, value=15, step=1, label="Vehicle capacity (sum of demand)")
run_btn2 = gr.Button("πŸ“ˆ Optimize uploaded data", variant="primary")
with gr.Column():
img2 = gr.Image(type="pil", label="Route Visualization", interactive=False)
with gr.Row():
route_df2 = gr.Dataframe(label="Route assignments (per stop)")
metrics2 = gr.Code(label="Metrics (JSON)")
run_btn2.click(
fn=run_csv,
inputs=[file, n_vehicles2, capacity2],
outputs=[img2, route_df2, metrics2],
)
def _tmpl():
return gr.File.update(value=None), download_template()
dl_tmp.click(fn=_tmpl, outputs=[file, route_df2], inputs=None)
gr.Markdown(f"---\n{FOOTER}")
if __name__ == "__main__":
demo.launch()