Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -19,23 +19,20 @@ def held_karp_tsp_fixed_start(dist_matrix: np.ndarray, return_to_start: bool = T
|
|
19 |
n = len(dist_matrix)
|
20 |
inf = float('inf')
|
21 |
|
22 |
-
# Only consider paths that start from index 0
|
23 |
dp = np.full((1 << n, n), inf)
|
24 |
parent = np.full((1 << n, n), -1, dtype=int)
|
25 |
|
26 |
-
# Initialize paths from start (index 0) to other cities
|
27 |
for i in range(1, n):
|
28 |
dp[1 << i | 1][i] = dist_matrix[0][i]
|
29 |
|
30 |
-
# Process all possible subsets of cities
|
31 |
for mask in range(1, 1 << n):
|
32 |
-
if not (mask & 1):
|
33 |
continue
|
34 |
for curr in range(n):
|
35 |
if not (mask & (1 << curr)):
|
36 |
continue
|
37 |
prev_mask = mask ^ (1 << curr)
|
38 |
-
if not prev_mask:
|
39 |
continue
|
40 |
for prev in range(n):
|
41 |
if not (prev_mask & (1 << prev)):
|
@@ -45,18 +42,18 @@ def held_karp_tsp_fixed_start(dist_matrix: np.ndarray, return_to_start: bool = T
|
|
45 |
dp[mask][curr] = candidate
|
46 |
parent[mask][curr] = prev
|
47 |
|
48 |
-
# Find the optimal end point
|
49 |
mask = (1 << n) - 1
|
50 |
if return_to_start:
|
51 |
-
|
52 |
-
|
|
|
53 |
final_cost = dp[mask][curr] + dist_matrix[curr][0]
|
54 |
else:
|
55 |
-
|
56 |
-
|
|
|
57 |
final_cost = dp[mask][curr]
|
58 |
|
59 |
-
# Reconstruct the path
|
60 |
path = []
|
61 |
while curr != -1:
|
62 |
path.append(curr)
|
@@ -64,14 +61,14 @@ def held_karp_tsp_fixed_start(dist_matrix: np.ndarray, return_to_start: bool = T
|
|
64 |
curr = parent[mask][curr]
|
65 |
mask = new_mask
|
66 |
|
67 |
-
path.append(0)
|
68 |
-
if return_to_start:
|
69 |
-
path.append(0) # Add start city again for closed loop
|
70 |
path.reverse()
|
71 |
|
|
|
|
|
|
|
72 |
return final_cost, path
|
73 |
|
74 |
-
# Keep other helper functions unchanged
|
75 |
@st.cache_data
|
76 |
def get_route_osrm(start_coords: tuple, end_coords: tuple) -> tuple:
|
77 |
"""Get route using OSRM public API"""
|
@@ -165,30 +162,38 @@ def plot_route_with_roads(map_obj: folium.Map, coordinates: list, route: list,
|
|
165 |
|
166 |
if route_key in routes_dict:
|
167 |
decoded_path = polyline.decode(routes_dict[route_key])
|
|
|
|
|
|
|
168 |
folium.PolyLine(
|
169 |
decoded_path,
|
170 |
color="blue",
|
171 |
weight=3,
|
172 |
opacity=0.8,
|
173 |
-
tooltip=
|
174 |
).add_to(route_group)
|
175 |
|
176 |
for i, point_idx in enumerate(route):
|
177 |
-
if return_to_start:
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
|
|
|
|
181 |
|
182 |
popup_text = f"""
|
183 |
<div style='font-size: 12px'>
|
184 |
<b>City:</b> {city_names[point_idx]}<br>
|
185 |
-
<b>Stop:</b> {
|
186 |
</div>
|
187 |
"""
|
|
|
188 |
folium.Marker(
|
189 |
location=coordinates[point_idx],
|
190 |
popup=folium.Popup(popup_text, max_width=200),
|
191 |
-
tooltip=f'
|
192 |
icon=folium.Icon(color=icon_color, icon='info-sign')
|
193 |
).add_to(route_group)
|
194 |
|
@@ -206,8 +211,7 @@ def main():
|
|
206 |
|
207 |
st.title("π Route Optimizer")
|
208 |
st.markdown("""
|
209 |
-
Temukan rute optimal berkendara antar lokasi.
|
210 |
-
Masukkan nama lokasi dibawah dan klik 'Optimize Route' untuk melihat hasilnya.
|
211 |
Kota 1 akan menjadi titik awal perjalanan.
|
212 |
""")
|
213 |
|
@@ -280,7 +284,11 @@ def main():
|
|
280 |
st.success(f"β
Rute dihitung dalam {end_time - start_time:.2f} detik")
|
281 |
st.write(f"π£οΈ Total jarak berkendara: {min_cost:.2f} km")
|
282 |
st.write("π Rute optimal:")
|
283 |
-
|
|
|
|
|
|
|
|
|
284 |
st.code(route_text)
|
285 |
|
286 |
map_obj = plot_route_with_roads(map_obj, valid_coordinates, optimal_route,
|
|
|
19 |
n = len(dist_matrix)
|
20 |
inf = float('inf')
|
21 |
|
|
|
22 |
dp = np.full((1 << n, n), inf)
|
23 |
parent = np.full((1 << n, n), -1, dtype=int)
|
24 |
|
|
|
25 |
for i in range(1, n):
|
26 |
dp[1 << i | 1][i] = dist_matrix[0][i]
|
27 |
|
|
|
28 |
for mask in range(1, 1 << n):
|
29 |
+
if not (mask & 1):
|
30 |
continue
|
31 |
for curr in range(n):
|
32 |
if not (mask & (1 << curr)):
|
33 |
continue
|
34 |
prev_mask = mask ^ (1 << curr)
|
35 |
+
if not prev_mask:
|
36 |
continue
|
37 |
for prev in range(n):
|
38 |
if not (prev_mask & (1 << prev)):
|
|
|
42 |
dp[mask][curr] = candidate
|
43 |
parent[mask][curr] = prev
|
44 |
|
|
|
45 |
mask = (1 << n) - 1
|
46 |
if return_to_start:
|
47 |
+
curr = min(range(1, n), key=lambda x: dp[mask][x] + dist_matrix[x][0] if dp[mask][x] != inf else inf)
|
48 |
+
if dp[mask][curr] == inf:
|
49 |
+
return inf, []
|
50 |
final_cost = dp[mask][curr] + dist_matrix[curr][0]
|
51 |
else:
|
52 |
+
curr = min(range(1, n), key=lambda x: dp[mask][x] if dp[mask][x] != inf else inf)
|
53 |
+
if dp[mask][curr] == inf:
|
54 |
+
return inf, []
|
55 |
final_cost = dp[mask][curr]
|
56 |
|
|
|
57 |
path = []
|
58 |
while curr != -1:
|
59 |
path.append(curr)
|
|
|
61 |
curr = parent[mask][curr]
|
62 |
mask = new_mask
|
63 |
|
64 |
+
path.append(0)
|
|
|
|
|
65 |
path.reverse()
|
66 |
|
67 |
+
if return_to_start:
|
68 |
+
path.append(0)
|
69 |
+
|
70 |
return final_cost, path
|
71 |
|
|
|
72 |
@st.cache_data
|
73 |
def get_route_osrm(start_coords: tuple, end_coords: tuple) -> tuple:
|
74 |
"""Get route using OSRM public API"""
|
|
|
162 |
|
163 |
if route_key in routes_dict:
|
164 |
decoded_path = polyline.decode(routes_dict[route_key])
|
165 |
+
segment_label = (f"Return to {city_names[end_idx]}" if i == len(route)-2 and return_to_start
|
166 |
+
else f"Segment {i+1}: {city_names[start_idx]} β {city_names[end_idx]}")
|
167 |
+
|
168 |
folium.PolyLine(
|
169 |
decoded_path,
|
170 |
color="blue",
|
171 |
weight=3,
|
172 |
opacity=0.8,
|
173 |
+
tooltip=segment_label
|
174 |
).add_to(route_group)
|
175 |
|
176 |
for i, point_idx in enumerate(route):
|
177 |
+
if return_to_start and i == len(route) - 1:
|
178 |
+
continue
|
179 |
+
|
180 |
+
is_start = i == 0
|
181 |
+
is_end = (i == len(route) - 1) if not return_to_start else (i == len(route) - 2)
|
182 |
+
|
183 |
+
icon_color = "green" if is_start else "red" if is_end else "blue"
|
184 |
+
stop_number = "Start" if is_start else "End" if is_end else f"Stop {i}"
|
185 |
|
186 |
popup_text = f"""
|
187 |
<div style='font-size: 12px'>
|
188 |
<b>City:</b> {city_names[point_idx]}<br>
|
189 |
+
<b>Stop:</b> {stop_number}
|
190 |
</div>
|
191 |
"""
|
192 |
+
|
193 |
folium.Marker(
|
194 |
location=coordinates[point_idx],
|
195 |
popup=folium.Popup(popup_text, max_width=200),
|
196 |
+
tooltip=f'{stop_number}: {city_names[point_idx]}',
|
197 |
icon=folium.Icon(color=icon_color, icon='info-sign')
|
198 |
).add_to(route_group)
|
199 |
|
|
|
211 |
|
212 |
st.title("π Route Optimizer")
|
213 |
st.markdown("""
|
214 |
+
Temukan rute optimal berkendara antar lokasi. Masukkan nama lokasi dibawah dan klik 'Optimize Route' untuk melihat hasilnya.
|
|
|
215 |
Kota 1 akan menjadi titik awal perjalanan.
|
216 |
""")
|
217 |
|
|
|
284 |
st.success(f"β
Rute dihitung dalam {end_time - start_time:.2f} detik")
|
285 |
st.write(f"π£οΈ Total jarak berkendara: {min_cost:.2f} km")
|
286 |
st.write("π Rute optimal:")
|
287 |
+
|
288 |
+
route_cities = [city_names[i] for i in optimal_route]
|
289 |
+
if return_to_start:
|
290 |
+
route_cities = route_cities[:-1]
|
291 |
+
route_text = " β ".join(route_cities)
|
292 |
st.code(route_text)
|
293 |
|
294 |
map_obj = plot_route_with_roads(map_obj, valid_coordinates, optimal_route,
|