vincentiusyoshuac commited on
Commit
3787471
Β·
verified Β·
1 Parent(s): 0e240e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -17
app.py CHANGED
@@ -1,15 +1,63 @@
1
  import streamlit as st
2
  import folium
3
  from geopy.geocoders import Nominatim
4
- from itertools import combinations
5
  import numpy as np
6
  import requests
7
  import polyline
8
  import time
9
  from functools import lru_cache
10
- import json
11
  from concurrent.futures import ThreadPoolExecutor
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  @st.cache_data
14
  def get_route_osrm(start_coords: tuple, end_coords: tuple) -> tuple:
15
  """
@@ -152,20 +200,20 @@ def plot_route_with_roads(map_obj: folium.Map, coordinates: list, route: list,
152
  return map_obj
153
 
154
  def main():
155
- st.set_page_config(page_title="TSP Solver with OSRM", layout="wide")
156
 
157
  st.title("🌍 TSP Route Optimizer")
158
  st.markdown("""
159
- Find the optimal driving route between multiple cities using OSRM.
160
- Enter city names below and click 'Optimize Route' to see the results.
161
  """)
162
 
163
  col1, col2 = st.columns([1, 2])
164
 
165
  with col1:
166
- st.subheader("πŸ“ Enter Cities")
167
- city_count = st.number_input("Number of cities", min_value=2, max_value=10, value=3, step=1,
168
- help="Maximum 10 cities recommended due to API limits")
169
 
170
  if 'city_inputs' not in st.session_state:
171
  st.session_state.city_inputs = [''] * city_count
@@ -178,7 +226,7 @@ def main():
178
 
179
  for i in range(city_count):
180
  city_name = st.text_input(
181
- f"City {i+1}",
182
  value=st.session_state.city_inputs[i],
183
  key=f"city_{i}"
184
  )
@@ -190,7 +238,7 @@ def main():
190
  city_names.append(city_name)
191
  city_coords.append(coords)
192
  else:
193
- st.warning(f"⚠️ Could not find coordinates for '{city_name}'")
194
 
195
  with col2:
196
  if not city_coords:
@@ -204,27 +252,26 @@ def main():
204
 
205
  if st.button("πŸ”„ Optimize Route", key="optimize"):
206
  if len(city_coords) < 2:
207
- st.error("❌ Please enter at least 2 valid cities")
208
  else:
209
- with st.spinner("Calculating optimal route..."):
210
  start_time = time.time()
211
 
212
  # Get distance matrix and routes
213
  dist_matrix, valid_coordinates, routes_dict = create_distance_matrix_with_routes(city_coords)
214
 
215
  # Calculate optimal route
216
- from held_karp_tsp import held_karp_tsp # Menggunakan fungsi yang sudah ada
217
  min_cost, optimal_route = held_karp_tsp(dist_matrix)
218
 
219
  end_time = time.time()
220
 
221
  if min_cost == float('inf'):
222
- st.error("❌ Could not find a valid route")
223
  else:
224
  # Display results
225
- st.success(f"βœ… Route calculated in {end_time - start_time:.2f} seconds")
226
- st.write(f"πŸ›£οΈ Total driving distance: {min_cost:.2f} km")
227
- st.write("πŸ“ Optimal route:")
228
  route_text = " β†’ ".join([city_names[i] for i in optimal_route])
229
  st.code(route_text)
230
 
 
1
  import streamlit as st
2
  import folium
3
  from geopy.geocoders import Nominatim
 
4
  import numpy as np
5
  import requests
6
  import polyline
7
  import time
8
  from functools import lru_cache
 
9
  from concurrent.futures import ThreadPoolExecutor
10
 
11
+ def held_karp_tsp(dist_matrix: np.ndarray) -> tuple:
12
+ """
13
+ Held-Karp algorithm for solving TSP
14
+ Returns: (minimum cost, optimal route)
15
+ """
16
+ if len(dist_matrix) < 2:
17
+ return 0, []
18
+
19
+ n = len(dist_matrix)
20
+ inf = float('inf')
21
+
22
+ # Use numpy arrays for better performance
23
+ dp = np.full((1 << n, n), inf)
24
+ parent = np.full((1 << n, n), -1, dtype=int)
25
+
26
+ # Base cases
27
+ for i in range(1, n):
28
+ dp[1 << i][i] = dist_matrix[0][i]
29
+
30
+ # Main DP loop
31
+ for mask in range(1, 1 << n):
32
+ if bin(mask).count('1') <= 1:
33
+ continue
34
+ for curr in range(n):
35
+ if not (mask & (1 << curr)):
36
+ continue
37
+ prev_mask = mask ^ (1 << curr)
38
+ for prev in range(n):
39
+ if not (prev_mask & (1 << prev)):
40
+ continue
41
+ candidate = dp[prev_mask][prev] + dist_matrix[prev][curr]
42
+ if candidate < dp[mask][curr]:
43
+ dp[mask][curr] = candidate
44
+ parent[mask][curr] = prev
45
+
46
+ # Reconstruct path
47
+ mask = (1 << n) - 1
48
+ curr = min(range(n), key=lambda x: dp[mask][x] + dist_matrix[x][0])
49
+ path = []
50
+ while curr != -1:
51
+ path.append(curr)
52
+ new_mask = mask ^ (1 << curr)
53
+ curr = parent[mask][curr]
54
+ mask = new_mask
55
+
56
+ path.append(0)
57
+ path.reverse()
58
+
59
+ return dp[(1 << n) - 1][path[-2]] + dist_matrix[path[-2]][0], path
60
+
61
  @st.cache_data
62
  def get_route_osrm(start_coords: tuple, end_coords: tuple) -> tuple:
63
  """
 
200
  return map_obj
201
 
202
  def main():
203
+ st.set_page_config(page_title="TSP Route Optimizer", layout="wide")
204
 
205
  st.title("🌍 TSP Route Optimizer")
206
  st.markdown("""
207
+ Temukan rute optimal berkendara antar multiple kota menggunakan algoritma TSP.
208
+ Masukkan nama kota dibawah dan klik 'Optimize Route' untuk melihat hasilnya.
209
  """)
210
 
211
  col1, col2 = st.columns([1, 2])
212
 
213
  with col1:
214
+ st.subheader("πŸ“ Masukkan Kota")
215
+ city_count = st.number_input("Jumlah kota", min_value=2, max_value=10, value=3, step=1,
216
+ help="Maksimum 10 kota direkomendasikan karena batasan API")
217
 
218
  if 'city_inputs' not in st.session_state:
219
  st.session_state.city_inputs = [''] * city_count
 
226
 
227
  for i in range(city_count):
228
  city_name = st.text_input(
229
+ f"Kota {i+1}",
230
  value=st.session_state.city_inputs[i],
231
  key=f"city_{i}"
232
  )
 
238
  city_names.append(city_name)
239
  city_coords.append(coords)
240
  else:
241
+ st.warning(f"⚠️ Tidak dapat menemukan koordinat untuk '{city_name}'")
242
 
243
  with col2:
244
  if not city_coords:
 
252
 
253
  if st.button("πŸ”„ Optimize Route", key="optimize"):
254
  if len(city_coords) < 2:
255
+ st.error("❌ Masukkan minimal 2 kota yang valid")
256
  else:
257
+ with st.spinner("Menghitung rute optimal..."):
258
  start_time = time.time()
259
 
260
  # Get distance matrix and routes
261
  dist_matrix, valid_coordinates, routes_dict = create_distance_matrix_with_routes(city_coords)
262
 
263
  # Calculate optimal route
 
264
  min_cost, optimal_route = held_karp_tsp(dist_matrix)
265
 
266
  end_time = time.time()
267
 
268
  if min_cost == float('inf'):
269
+ st.error("❌ Tidak dapat menemukan rute yang valid")
270
  else:
271
  # Display results
272
+ st.success(f"βœ… Rute dihitung dalam {end_time - start_time:.2f} detik")
273
+ st.write(f"πŸ›£οΈ Total jarak berkendara: {min_cost:.2f} km")
274
+ st.write("πŸ“ Rute optimal:")
275
  route_text = " β†’ ".join([city_names[i] for i in optimal_route])
276
  st.code(route_text)
277