Isha184 commited on
Commit
5ac2f2d
Β·
verified Β·
1 Parent(s): d3d0c97

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +141 -42
app.py CHANGED
@@ -1,42 +1,141 @@
1
- import streamlit as st
2
- import numpy as np
3
- import matplotlib.pyplot as plt
4
- from solver import clarke_wright
5
-
6
- st.set_page_config(page_title="Ride Sharing Optimizer", layout="wide")
7
-
8
- st.title("🚐 Ride Sharing Optimizer (VRP)")
9
-
10
- st.markdown("""
11
- Upload your customer data and optimize vehicle routes with capacity constraints.
12
- """)
13
-
14
- # Input params
15
- num_customers = st.slider("Number of Customers", 5, 30, 10)
16
- vehicle_capacity = st.slider("Vehicle Capacity", 5, 50, 15)
17
-
18
- # Random data generation
19
- np.random.seed(42)
20
- coords = [(50, 50)] + [(np.random.randint(0, 100), np.random.randint(0, 100)) for _ in range(num_customers)]
21
- demands = [0] + [np.random.randint(1, 5) for _ in range(num_customers)]
22
-
23
- if st.button("Optimize Routes"):
24
- routes, dist = clarke_wright(coords, demands, vehicle_capacity)
25
-
26
- fig, ax = plt.subplots(figsize=(6,6))
27
-
28
- colors = plt.cm.tab10.colors
29
- for idx, route in enumerate(routes):
30
- xs, ys = zip(*[coords[i] for i in route])
31
- ax.plot(xs, ys, marker="o", color=colors[idx % len(colors)], label=f"Vehicle {idx+1}")
32
- for i, (x,y) in enumerate(coords):
33
- ax.text(x, y, str(i), fontsize=8, ha="right")
34
-
35
- ax.scatter(coords[0][0], coords[0][1], c="red", s=100, marker="s", label="Depot")
36
- ax.set_title("Optimized Vehicle Routes")
37
- ax.legend()
38
-
39
- st.pyplot(fig)
40
-
41
- total_distance = sum(sum(dist[route[i]][route[i+1]] for i in range(len(route)-1)) for route in routes)
42
- st.success(f"βœ… Total distance: {total_distance:.2f}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import json
3
+ import gradio as gr
4
+ import pandas as pd
5
+ from solver import (
6
+ generate_random_instance,
7
+ solve_vrp,
8
+ plot_solution,
9
+ parse_uploaded_csv,
10
+ make_template_dataframe,
11
+ )
12
+
13
+ TITLE = "Ride-Sharing Optimizer (Capacitated VRP) β€” Gradio Demo"
14
+ DESC = """
15
+ This demo assigns **stops (riders)** to **drivers (vehicles)** with a simple, fast heuristic:
16
+ **Sweep clustering** β†’ **Greedy routing** β†’ **2-opt improvement**.
17
+ You can **generate a sample** dataset or **upload a CSV** with columns:
18
+ `id,x,y,demand,tw_start,tw_end,service`.
19
+
20
+ - **Capacity** = max riders per vehicle (sum of `demand` per route).
21
+ - **Time windows** are *soft* (violations are reported in metrics).
22
+ - Distances are Euclidean on the X-Y plane for clarity.
23
+
24
+ Tip: Start with the generator, then switch to your CSV.
25
+ """
26
+
27
+ FOOTER = "Made with ❀️ using Gradio. No native dependencies; runs quickly on Spaces."
28
+
29
+ def run_generator(
30
+ n_clients, n_vehicles, capacity, spread, demand_min, demand_max, seed
31
+ ):
32
+ df = generate_random_instance(
33
+ n_clients=n_clients,
34
+ n_vehicles=n_vehicles,
35
+ capacity=capacity,
36
+ spread=spread,
37
+ demand_min=demand_min,
38
+ demand_max=demand_max,
39
+ seed=seed,
40
+ )
41
+ depot = (0.0, 0.0)
42
+ sol = solve_vrp(
43
+ df, depot=depot, n_vehicles=n_vehicles, capacity=capacity, speed=1.0
44
+ )
45
+ fig = plot_solution(df, sol, depot=depot)
46
+ buf = io.BytesIO()
47
+ fig.savefig(buf, format="png", bbox_inches="tight", dpi=160)
48
+ buf.seek(0)
49
+
50
+ # Route table
51
+ route_table = sol["assignments_table"]
52
+ metrics = json.dumps(sol["metrics"], indent=2)
53
+
54
+ return buf, route_table, metrics, df
55
+
56
+ def run_csv(
57
+ file, n_vehicles, capacity
58
+ ):
59
+ if file is None:
60
+ raise gr.Error("Please upload a CSV first.")
61
+ try:
62
+ df = parse_uploaded_csv(file)
63
+ except Exception as e:
64
+ raise gr.Error(f"CSV parsing error: {e}")
65
+
66
+ depot = (0.0, 0.0)
67
+ sol = solve_vrp(
68
+ df, depot=depot, n_vehicles=n_vehicles, capacity=capacity, speed=1.0
69
+ )
70
+ fig = plot_solution(df, sol, depot=depot)
71
+ buf = io.BytesIO()
72
+ fig.savefig(buf, format="png", bbox_inches="tight", dpi=160)
73
+ buf.seek(0)
74
+
75
+ route_table = sol["assignments_table"]
76
+ metrics = json.dumps(sol["metrics"], indent=2)
77
+ return buf, route_table, metrics
78
+
79
+ def download_template():
80
+ df = make_template_dataframe()
81
+ return df
82
+
83
+ with gr.Blocks(title=TITLE) as demo:
84
+ gr.Markdown(f"# {TITLE}")
85
+ gr.Markdown(DESC)
86
+
87
+ with gr.Tab("πŸ”€ Generate sample"):
88
+ with gr.Row():
89
+ with gr.Column():
90
+ n_clients = gr.Slider(5, 200, value=30, step=1, label="Number of riders (clients)")
91
+ n_vehicles = gr.Slider(1, 20, value=4, step=1, label="Number of drivers (vehicles)")
92
+ capacity = gr.Slider(1, 50, value=10, step=1, label="Vehicle capacity (sum of demand)")
93
+ spread = gr.Slider(10, 200, value=50, step=1, label="Spatial spread (larger = wider map)")
94
+ demand_min = gr.Slider(1, 5, value=1, step=1, label="Min demand per stop")
95
+ demand_max = gr.Slider(1, 10, value=3, step=1, label="Max demand per stop")
96
+ seed = gr.Slider(0, 9999, value=42, step=1, label="Random seed")
97
+ run_btn = gr.Button("πŸš— Generate & Optimize", variant="primary")
98
+ with gr.Column():
99
+ img = gr.Image(label="Route Visualization", interactive=False)
100
+ with gr.Row():
101
+ route_df = gr.Dataframe(label="Route assignments (per stop)", wrap=True)
102
+ metrics = gr.Code(label="Metrics (JSON)")
103
+ with gr.Accordion("Show generated dataset", open=False):
104
+ data_out = gr.Dataframe(label="Generated input data")
105
+
106
+ run_btn.click(
107
+ fn=run_generator,
108
+ inputs=[n_clients, n_vehicles, capacity, spread, demand_min, demand_max, seed],
109
+ outputs=[img, route_df, metrics, data_out],
110
+ )
111
+
112
+ with gr.Tab("πŸ“„ Upload CSV"):
113
+ with gr.Row():
114
+ with gr.Column():
115
+ file = gr.File(label="Upload CSV (id,x,y,demand,tw_start,tw_end,service)")
116
+ dl_tmp = gr.Button("Get CSV Template")
117
+ n_vehicles2 = gr.Slider(1, 50, value=5, step=1, label="Number of drivers (vehicles)")
118
+ capacity2 = gr.Slider(1, 200, value=15, step=1, label="Vehicle capacity (sum of demand)")
119
+ run_btn2 = gr.Button("πŸ“ˆ Optimize uploaded data", variant="primary")
120
+ with gr.Column():
121
+ img2 = gr.Image(label="Route Visualization", interactive=False)
122
+
123
+ with gr.Row():
124
+ route_df2 = gr.Dataframe(label="Route assignments (per stop)")
125
+ metrics2 = gr.Code(label="Metrics (JSON)")
126
+
127
+ run_btn2.click(
128
+ fn=run_csv,
129
+ inputs=[file, n_vehicles2, capacity2],
130
+ outputs=[img2, route_df2, metrics2],
131
+ )
132
+
133
+ def _tmpl():
134
+ return gr.File.update(value=None), download_template()
135
+
136
+ dl_tmp.click(fn=_tmpl, outputs=[file, route_df2], inputs=None)
137
+
138
+ gr.Markdown(f"---\n{FOOTER}")
139
+
140
+ if __name__ == "__main__":
141
+ demo.launch()