vincentiusyoshuac commited on
Commit
fb17aa5
·
verified ·
1 Parent(s): b1621cd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -22
app.py CHANGED
@@ -1,14 +1,11 @@
1
  import streamlit as st
2
  import folium
3
  import numpy as np
4
- from scipy.optimize import linear_sum_assignment
5
- from folium import plugins
6
- import requests
7
- from datetime import datetime
8
- from geopy.geocoders import Nominatim
9
- import polyline
10
  from typing import List, Tuple, Dict, Optional
11
  import time
 
 
 
12
 
13
  # Utility Functions
14
  def create_numbered_marker(number: int) -> folium.features.DivIcon:
@@ -76,8 +73,8 @@ def get_route_from_osrm(coord1: Tuple[float, float], coord2: Tuple[float, float]
76
  st.warning(f"Error getting route: {str(e)}")
77
  return None
78
 
79
- def calculate_real_distances(places: List[Tuple[str, Tuple[float, float]]]) -> Tuple[np.ndarray, Dict]:
80
- """Calculate real driving distances using OSRM"""
81
  n = len(places)
82
  distances = np.zeros((n, n))
83
  routing_info = {}
@@ -108,17 +105,37 @@ def calculate_real_distances(places: List[Tuple[str, Tuple[float, float]]]) -> T
108
 
109
  return distances, routing_info
110
 
111
- def optimize_route(distances: np.ndarray) -> List[int]:
112
- """Optimize route using modified Hungarian algorithm for TSP"""
113
  n = len(distances)
114
- row_ind, col_ind = linear_sum_assignment(distances)
 
 
115
 
116
- # Convert assignment to tour
117
- tour = []
118
- for i in range(n):
119
- tour.append(col_ind[i])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- return tour
122
 
123
  def add_markers_and_route(m: folium.Map, places: List[Tuple[str, Tuple[float, float]]], optimal_order: List[int], routing_info: Dict):
124
  """Add markers and route lines to the map"""
@@ -237,16 +254,16 @@ def main():
237
  col1, col2 = st.columns([2, 1])
238
  with col1:
239
  with st.spinner("🚗 Calculating optimal route..."):
240
- # Calculate real distances
241
- distances, routing_info = calculate_real_distances(places)
242
 
243
- # Get optimized route order
244
- optimal_order = optimize_route(distances)
245
 
246
  # Update the route if the user changes the input
247
  if st.button("Recalculate Route"):
248
- distances, routing_info = calculate_real_distances(places)
249
- optimal_order = optimize_route(distances)
250
 
251
  # Create map and display
252
  m = folium.Map()
 
1
  import streamlit as st
2
  import folium
3
  import numpy as np
 
 
 
 
 
 
4
  from typing import List, Tuple, Dict, Optional
5
  import time
6
+ from collections import deque
7
+ import requests
8
+ import polyline
9
 
10
  # Utility Functions
11
  def create_numbered_marker(number: int) -> folium.features.DivIcon:
 
73
  st.warning(f"Error getting route: {str(e)}")
74
  return None
75
 
76
+ def calculate_distance_matrix(places: List[Tuple[str, Tuple[float, float]]]) -> Tuple[np.ndarray, Dict]:
77
+ """Calculate distance matrix and routing information using OSRM"""
78
  n = len(places)
79
  distances = np.zeros((n, n))
80
  routing_info = {}
 
105
 
106
  return distances, routing_info
107
 
108
+ def dijkstra(distances: np.ndarray, start_idx: int) -> Tuple[List[int], Dict[int, float]]:
109
+ """Implement Dijkstra's algorithm to find the optimal route"""
110
  n = len(distances)
111
+ visited = [False] * n
112
+ distances_to = [float('inf')] * n
113
+ prev_node = [-1] * n
114
 
115
+ distances_to[start_idx] = 0
116
+ queue = deque([start_idx])
117
+
118
+ while queue:
119
+ current_node = queue.popleft()
120
+ visited[current_node] = True
121
+
122
+ for neighbor in range(n):
123
+ if not visited[neighbor] and distances[current_node, neighbor] > 0:
124
+ new_distance = distances_to[current_node] + distances[current_node, neighbor]
125
+ if new_distance < distances_to[neighbor]:
126
+ distances_to[neighbor] = new_distance
127
+ prev_node[neighbor] = current_node
128
+ queue.append(neighbor)
129
+
130
+ # Reconstruct the optimal route
131
+ optimal_order = []
132
+ node = n - 1
133
+ while prev_node[node] != -1:
134
+ optimal_order.insert(0, node)
135
+ node = prev_node[node]
136
+ optimal_order.insert(0, start_idx)
137
 
138
+ return optimal_order, distances_to
139
 
140
  def add_markers_and_route(m: folium.Map, places: List[Tuple[str, Tuple[float, float]]], optimal_order: List[int], routing_info: Dict):
141
  """Add markers and route lines to the map"""
 
254
  col1, col2 = st.columns([2, 1])
255
  with col1:
256
  with st.spinner("🚗 Calculating optimal route..."):
257
+ # Calculate distance matrix
258
+ distances, routing_info = calculate_distance_matrix(places)
259
 
260
+ # Get optimized route order using Dijkstra's algorithm
261
+ optimal_order, _ = dijkstra(distances, 0)
262
 
263
  # Update the route if the user changes the input
264
  if st.button("Recalculate Route"):
265
+ distances, routing_info = calculate_distance_matrix(places)
266
+ optimal_order, _ = dijkstra(distances, 0)
267
 
268
  # Create map and display
269
  m = folium.Map()