koesan commited on
Commit
b83bae4
·
1 Parent(s): 6d63489

Rebuild project without binary files

Browse files
Files changed (11) hide show
  1. A_Star.py +0 -39
  2. Bellman_Ford.py +0 -44
  3. Dijkstra.py +0 -49
  4. HUGGINGFACE_YUKLE.txt +28 -0
  5. README.md +23 -6
  6. app.py +70 -123
  7. docker-compose.yml +0 -11
  8. main.py +0 -87
  9. requirements.txt +1 -1
  10. run_local.sh +0 -30
  11. templates/index.html +253 -0
A_Star.py DELETED
@@ -1,39 +0,0 @@
1
- from heapq import *
2
-
3
- # A* algoritmasında kullanılacak olan heuristik fonksiyon
4
- def heuristic(a, b):
5
- return abs(a[0] - b[0]) + abs(a[1] - b[1]) # A ile B arasındaki Manhattan mesafesi
6
-
7
- # Yolu geri döndürmek için kullanılan fonksiyon
8
- def reconstruct_path(came_from, current):
9
- total_path = [current]
10
- while current in came_from and came_from[current] is not None:
11
- current = came_from[current]
12
- total_path.append(current) # Yolun parçalarını sırayla ekle
13
- return total_path[::-1] # Yolu ters çevir, böylece başlangıç -> hedef sırası olur
14
-
15
- def a_star(graph, start, goal):
16
- queue = []
17
- heappush(queue, (0, start)) # Başlangıç düğümünü maliyet 0 ile kuyruğa ekle
18
- g_score = {start: 0} # Başlangıç düğümünün maliyeti 0
19
- came_from = {start: None} # Her düğümün nereden geldiğini takip etmek için
20
-
21
- while queue:
22
- _, current = heappop(queue) # En düşük maliyetli düğümü al
23
-
24
- if current == goal:
25
- return reconstruct_path(came_from, goal) # Hedefe ulaşıldıysa yolu geri döndür
26
-
27
- # Mevcut düğümün komşularını dolaş
28
- for neighbor_cost, neighbor in graph[current]:
29
- tentative_g_score = g_score[current] + neighbor_cost # Komşuya ulaşmanın maliyetini hesapla
30
-
31
- # Daha düşük maliyet bulunursa güncelle
32
- if neighbor not in g_score or tentative_g_score < g_score[neighbor]:
33
- g_score[neighbor] = tentative_g_score # En iyi g_score güncelle
34
- f_score = tentative_g_score + heuristic(neighbor, goal) # Toplam maliyeti hesapla (g + h)
35
- heappush(queue, (f_score, neighbor)) # Komşuyu öncelik sırasına ekle
36
- came_from[neighbor] = current # Bu komşuya, mevcut düğümden gelindi
37
-
38
- return None # Eğer hedefe ulaşılamazsa None döndür
39
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Bellman_Ford.py DELETED
@@ -1,44 +0,0 @@
1
- # kaynak: https://www.youtube.com/watch?v=24HziTZ8_xo
2
-
3
- def bellman_ford(graph,başlangıç,hedef):
4
- # Mesafeleri sonsuz olarak başlat
5
- mesafeler = {node: float('infinity') for node in graph}
6
- önceki = {node: None for node in graph} # Her düğümün öncesini kaydet
7
-
8
- # Başlangıç düğümünün mesafesini sıfır olarak ayarla
9
- mesafeler[başlangıç] = 0
10
-
11
- # Döngü graftaki düğümlerin sayısının 1 eksiği kadar devam etmeli.
12
- for _ in range(len(graph) - 1): # Düğüm sayısı - 1 kadar tekrar et
13
- for i in graph: # Her düğüm üzerinde dolaş
14
- for j in graph[i]: # Düğümün komşularına bak
15
- hedef_dugum = j[1] # Hedef düğümü al
16
- maliyet = j[0] # Kenar maliyetini al
17
-
18
- # Eğer mevcut düğümün mesafesi sonsuz değilse ve komşuya olan mesafe daha düşükse güncelle
19
- if mesafeler[i] != float('infinity') and (mesafeler[i] + maliyet < mesafeler[hedef_dugum]):
20
- mesafeler[hedef_dugum] = mesafeler[i] + maliyet
21
- önceki[hedef_dugum] = i # Önceki düğümü güncelle
22
-
23
- # Negatif ağırlıklı döngü kontrolü
24
- for i in graph:
25
- for j in graph[i]:
26
- hedef_dugum = j[1]
27
- maliyet = j[0]
28
-
29
- # Eğer hala bir iyileştirme yapılabiliyorsa negatif döngü vardır
30
- if mesafeler[i] != float('infinity') and (mesafeler[i] + maliyet < mesafeler[hedef_dugum]):
31
- return None # Negatif döngü bulunduktan sonra işlevi sonlandırın.
32
-
33
-
34
- # En kısa yolu bulmak için hedeften başlangıca doğru git
35
- yol = []
36
- geçerli_dugum = hedef
37
-
38
- while geçerli_dugum is not None:
39
- yol.append(geçerli_dugum)
40
- geçerli_dugum = önceki[geçerli_dugum]
41
-
42
- # Yolu ters çevir ve döndür.
43
- yol.reverse()
44
- return yol
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Dijkstra.py DELETED
@@ -1,49 +0,0 @@
1
- def get_shortest_path(previous_nodes, start, target):
2
- path = []
3
- current_node = target
4
-
5
- while current_node is not None:
6
- path.insert(0, current_node) # Düğümü başa ekle
7
- current_node = previous_nodes[current_node] # Bir önceki düğüme git
8
-
9
- if path[0] == start:
10
- return path
11
- else:
12
- return [] # Eğer yol yoksa boş liste döner
13
-
14
- def dijkstra(graph, start,target):
15
- # 1. Mesafe tablosu: Başlangıç düğümünden diğer düğümlere olan mesafeleri tutar
16
- mesafeler = {node: float('infinity') for node in graph}
17
- mesafeler[start] = 0
18
-
19
- # 2. Ziyaret edilen düğümleri tutan liste
20
- ziyaret_edilen = []
21
-
22
- # 3. Önceki düğümleri tutan tablo: En kısa yolu oluşturmak için
23
- önceki_düğümler = {node: None for node in graph}
24
-
25
- while len(ziyaret_edilen) < len(graph):
26
- # 4. Ziyaret edilmemiş düğümler arasında en kısa mesafeye sahip olanı seç
27
- en_kısa_yol_düğümü = None
28
- for node in mesafeler:
29
- if node not in ziyaret_edilen:
30
- if en_kısa_yol_düğümü is None:
31
- en_kısa_yol_düğümü = node
32
- elif mesafeler[node] < mesafeler[en_kısa_yol_düğümü]:
33
- en_kısa_yol_düğümü = node
34
-
35
- if en_kısa_yol_düğümü is None:
36
- break # Tüm düğümler ziyaret edilmişse ya da ulaşılamayan düğümler kalmışsa döngüyü sonlandır
37
-
38
- # 5. Seçilen düğümün komşularının mesafelerini güncelle
39
- for ağırlık,komşu in graph[en_kısa_yol_düğümü]:
40
-
41
- yeni_mesafe = mesafeler[en_kısa_yol_düğümü] + ağırlık
42
- if yeni_mesafe < mesafeler[komşu]:
43
- mesafeler[komşu] = yeni_mesafe
44
- önceki_düğümler[komşu] = en_kısa_yol_düğümü
45
-
46
- # 6. Seçilen düğümü ziyaret edilmiş olarak işaretle
47
- ziyaret_edilen.append(en_kısa_yol_düğümü)
48
-
49
- return get_shortest_path(önceki_düğümler, start, target)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
HUGGINGFACE_YUKLE.txt ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 🚀 HUGGING FACE SPACES'E YÜKLEME
2
+
3
+ Bu klasördeki TÜM dosya ve klasörleri Hugging Face'e yükleyin.
4
+
5
+ 📁 YÜKLENECEK DOSYALAR:
6
+
7
+ ├── app.py
8
+ ├── Dockerfile
9
+ ├── README.md
10
+ ├── requirements.txt
11
+ ├── static/
12
+ │ └── images/
13
+ │ └── map.jpg
14
+ └── templates/
15
+ └── index.html
16
+
17
+ 🎯 ADIMLAR:
18
+
19
+ 1. https://huggingface.co/new-space
20
+ 2. SDK: DOCKER seçin
21
+ 3. Tüm dosyaları yükleyin
22
+ 4. Build bekleyin (5-10 dakika)
23
+ 5. Hazır!
24
+
25
+ ✅ KONTROL:
26
+ - Sayfa açılır açılmaz resim üzerinde path göreceksiniz
27
+ - Algoritma seçebileceksiniz
28
+ - Slider ile start/goal ayarlayabileceksiniz
README.md CHANGED
@@ -1,12 +1,29 @@
1
  ---
2
- title: Pathfinding Algorithms
3
- emoji:
4
- colorFrom: yellow
5
- colorTo: red
6
  sdk: docker
 
7
  pinned: false
8
  license: mit
9
- short_description: '``` Interactive pathfinding algorithm visualizer with A*, Di'
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Path Finding Algorithms
3
+ emoji: 🗺️
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: docker
7
+ app_port: 7860
8
  pinned: false
9
  license: mit
 
10
  ---
11
 
12
+ # 🗺️ Path Finding Algorithms Visualizer
13
+
14
+ Interactive pathfinding visualization with **A\***, **Dijkstra**, and **Bellman-Ford** algorithms on a custom map.
15
+
16
+ ## 🚀 How to Use
17
+
18
+ 1. **Select Algorithm**: A*, Dijkstra, or Bellman-Ford
19
+ 2. **Set Start Position**: X and Y sliders
20
+ 3. **Set Goal Position**: X and Y sliders
21
+ 4. **Find Path**: Click button to visualize
22
+
23
+ ## 📊 Algorithms
24
+
25
+ - **A\***: Fastest with heuristic
26
+ - **Dijkstra**: Classic shortest path
27
+ - **Bellman-Ford**: Handles negative weights
28
+
29
+ Built with Python, Flask, and Matplotlib
app.py CHANGED
@@ -1,17 +1,19 @@
1
- import gradio as gr
2
  import numpy as np
3
  import matplotlib
4
- matplotlib.use('Agg') # Non-interactive backend for server
5
  import matplotlib.pyplot as plt
6
  from matplotlib.patches import Rectangle
7
  from heapq import heappush, heappop
8
  import io
9
  from PIL import Image
10
  import os
 
11
 
12
- # Matplotlib config directory
13
  os.environ['MPLCONFIGDIR'] = '/tmp/matplotlib'
14
 
 
 
15
  # Grid tanımı
16
  GRID = [[4, 4, 4, 4, 4, 4, 4, 2, 3, 2, 4, 2],
17
  [4, 4, 4, 4, 9, 9, 3, 2, 2, 4, 4, 4],
@@ -24,7 +26,6 @@ GRID = [[4, 4, 4, 4, 4, 4, 4, 2, 3, 2, 4, 2],
24
 
25
  COLS, ROWS = 12, 8
26
 
27
- # Graph oluştur
28
  def create_graph(grid):
29
  graph = {}
30
  for y in range(len(grid)):
@@ -39,7 +40,6 @@ def create_graph(grid):
39
 
40
  GRAPH = create_graph(GRID)
41
 
42
- # A* Algoritması
43
  def heuristic(a, b):
44
  return abs(a[0] - b[0]) + abs(a[1] - b[1])
45
 
@@ -70,7 +70,6 @@ def a_star(graph, start, goal):
70
 
71
  return None
72
 
73
- # Dijkstra Algoritması
74
  def dijkstra(graph, start, goal):
75
  distances = {node: float('infinity') for node in graph}
76
  distances[start] = 0
@@ -103,7 +102,6 @@ def dijkstra(graph, start, goal):
103
 
104
  return path if path[0] == start else None
105
 
106
- # Bellman-Ford Algoritması
107
  def bellman_ford(graph, start, goal):
108
  distances = {node: float('infinity') for node in graph}
109
  previous = {node: None for node in graph}
@@ -125,97 +123,78 @@ def bellman_ford(graph, start, goal):
125
  path.reverse()
126
  return path if path and path[0] == start else None
127
 
128
- # Görselleştirme
129
  def visualize_path(start_x, start_y, goal_x, goal_y, algorithm):
130
- start = (start_x, start_y)
131
- goal = (goal_x, goal_y)
132
 
133
- # Algoritma seçimi
134
  if algorithm == "A*":
135
  path = a_star(GRAPH, start, goal)
136
- color = '#2196F3'
137
  title = "A* Algorithm"
138
  elif algorithm == "Dijkstra":
139
  path = dijkstra(GRAPH, start, goal)
140
- color = '#FF9800'
141
  title = "Dijkstra Algorithm"
142
- else: # Bellman-Ford
143
  path = bellman_ford(GRAPH, start, goal)
144
- color = '#F44336'
145
  title = "Bellman-Ford Algorithm"
146
 
147
- # Matplotlib ile görselleştirme
 
 
 
 
 
 
 
148
  fig, ax = plt.subplots(figsize=(14, 8))
149
 
150
- # Grid çiz
151
- for y in range(ROWS):
152
- for x in range(COLS):
153
- cost = GRID[y][x]
154
- # Maliyet değerine göre renk
155
- if cost == 1:
156
- cell_color = '#E8F5E9'
157
- elif cost <= 3:
158
- cell_color = '#FFF9C4'
159
- elif cost <= 6:
160
- cell_color = '#FFE0B2'
161
- else:
162
- cell_color = '#FFCDD2'
163
-
164
- rect = Rectangle((x, ROWS - y - 1), 1, 1,
165
- facecolor=cell_color,
166
- edgecolor='gray',
167
- linewidth=0.5)
168
- ax.add_patch(rect)
169
-
170
- # Maliyet değerini yaz
171
- ax.text(x + 0.5, ROWS - y - 0.5, str(cost),
172
- ha='center', va='center',
173
- fontsize=10, color='#424242', weight='bold')
174
 
175
- # Yolu çiz
176
  if path:
 
 
 
 
 
 
177
  for i, (x, y) in enumerate(path):
178
  if (x, y) == start:
179
- circle_color = '#4CAF50'
180
- label = 'Start'
 
 
 
 
 
181
  elif (x, y) == goal:
182
- circle_color = '#F44336'
183
- label = 'Goal'
184
- else:
185
- circle_color = color
186
- label = 'Path'
187
-
188
- circle = plt.Circle((x + 0.5, ROWS - y - 0.5), 0.3,
189
- color=circle_color, zorder=10)
190
- ax.add_patch(circle)
191
 
192
  path_length = sum(GRID[y][x] for x, y in path[1:])
193
- info_text = f"Path Length: {len(path)} nodes\nTotal Cost: {path_length}"
194
  else:
195
- info_text = "No path found!"
196
 
197
  ax.set_xlim(0, COLS)
198
  ax.set_ylim(0, ROWS)
199
  ax.set_aspect('equal')
200
  ax.axis('off')
201
- ax.set_title(f'{title}\n{info_text}', fontsize=16, weight='bold', pad=20)
202
-
203
- # Legend
204
- from matplotlib.patches import Patch
205
- legend_elements = [
206
- Patch(facecolor='#4CAF50', label='Start'),
207
- Patch(facecolor='#F44336', label='Goal'),
208
- Patch(facecolor=color, label='Path'),
209
- Patch(facecolor='#E8F5E9', label='Low Cost (1)'),
210
- Patch(facecolor='#FFF9C4', label='Medium Cost (2-3)'),
211
- Patch(facecolor='#FFE0B2', label='High Cost (4-6)'),
212
- Patch(facecolor='#FFCDD2', label='Very High Cost (7-9)')
213
- ]
214
- ax.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(1, 1))
215
 
216
  plt.tight_layout()
217
 
218
- # PIL Image'e çevir
219
  buf = io.BytesIO()
220
  plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')
221
  buf.seek(0)
@@ -224,60 +203,28 @@ def visualize_path(start_x, start_y, goal_x, goal_y, algorithm):
224
 
225
  return img
226
 
227
- # Gradio Arayüzü
228
- with gr.Blocks(title="Path Finding Algorithms", theme=gr.themes.Soft()) as demo:
229
- gr.Markdown("""
230
- # 🗺️ Path Finding Algorithms Visualizer
231
-
232
- Select start and goal positions, choose an algorithm, and visualize the shortest path!
233
-
234
- ### 📊 Algorithms:
235
- - **A\***: Heuristic-based, fastest with known goal
236
- - **Dijkstra**: Classic shortest path algorithm
237
- - **Bellman-Ford**: Handles negative weights, detects negative cycles
238
- """)
239
-
240
- with gr.Row():
241
- with gr.Column(scale=1):
242
- gr.Markdown("### ⚙️ Settings")
243
-
244
- algorithm = gr.Radio(
245
- choices=["A*", "Dijkstra", "Bellman-Ford"],
246
- value="A*",
247
- label="Algorithm"
248
- )
249
-
250
- with gr.Row():
251
- start_x = gr.Slider(0, 11, value=0, step=1, label="Start X")
252
- start_y = gr.Slider(0, 7, value=7, step=1, label="Start Y")
253
-
254
- with gr.Row():
255
- goal_x = gr.Slider(0, 11, value=11, step=1, label="Goal X")
256
- goal_y = gr.Slider(0, 7, value=0, step=1, label="Goal Y")
257
-
258
- find_btn = gr.Button("🔍 Find Path", variant="primary", size="lg")
259
-
260
- gr.Markdown("""
261
- ### 📝 Info:
262
- - **Grid Size**: 12x8
263
- - **Cost Range**: 1-9
264
- - **Green**: Start point
265
- - **Red**: Goal point
266
- - **Blue/Orange/Red**: Path (depends on algorithm)
267
- """)
268
-
269
- with gr.Column(scale=2):
270
- output_image = gr.Image(label="Visualization", type="pil")
271
 
272
- find_btn.click(
273
- fn=visualize_path,
274
- inputs=[start_x, start_y, goal_x, goal_y, algorithm],
275
- outputs=output_image
276
- )
277
 
278
  if __name__ == "__main__":
279
- demo.launch(
280
- server_name="0.0.0.0",
281
- server_port=7860,
282
- share=False
283
- )
 
1
+ from flask import Flask, render_template, request, jsonify, send_file
2
  import numpy as np
3
  import matplotlib
4
+ matplotlib.use('Agg')
5
  import matplotlib.pyplot as plt
6
  from matplotlib.patches import Rectangle
7
  from heapq import heappush, heappop
8
  import io
9
  from PIL import Image
10
  import os
11
+ import base64
12
 
 
13
  os.environ['MPLCONFIGDIR'] = '/tmp/matplotlib'
14
 
15
+ app = Flask(__name__)
16
+
17
  # Grid tanımı
18
  GRID = [[4, 4, 4, 4, 4, 4, 4, 2, 3, 2, 4, 2],
19
  [4, 4, 4, 4, 9, 9, 3, 2, 2, 4, 4, 4],
 
26
 
27
  COLS, ROWS = 12, 8
28
 
 
29
  def create_graph(grid):
30
  graph = {}
31
  for y in range(len(grid)):
 
40
 
41
  GRAPH = create_graph(GRID)
42
 
 
43
  def heuristic(a, b):
44
  return abs(a[0] - b[0]) + abs(a[1] - b[1])
45
 
 
70
 
71
  return None
72
 
 
73
  def dijkstra(graph, start, goal):
74
  distances = {node: float('infinity') for node in graph}
75
  distances[start] = 0
 
102
 
103
  return path if path[0] == start else None
104
 
 
105
  def bellman_ford(graph, start, goal):
106
  distances = {node: float('infinity') for node in graph}
107
  previous = {node: None for node in graph}
 
123
  path.reverse()
124
  return path if path and path[0] == start else None
125
 
 
126
  def visualize_path(start_x, start_y, goal_x, goal_y, algorithm):
127
+ start = (int(start_x), int(start_y))
128
+ goal = (int(goal_x), int(goal_y))
129
 
 
130
  if algorithm == "A*":
131
  path = a_star(GRAPH, start, goal)
132
+ color = '#00FF00'
133
  title = "A* Algorithm"
134
  elif algorithm == "Dijkstra":
135
  path = dijkstra(GRAPH, start, goal)
136
+ color = '#FFA500'
137
  title = "Dijkstra Algorithm"
138
+ else:
139
  path = bellman_ford(GRAPH, start, goal)
140
+ color = '#FF0000'
141
  title = "Bellman-Ford Algorithm"
142
 
143
+ # Arka plan resmini yükle
144
+ bg_img = Image.open('static/images/map.jpg')
145
+ bg_width, bg_height = bg_img.size
146
+
147
+ # Her hücrenin piksel boyutu
148
+ tile_width = bg_width / COLS
149
+ tile_height = bg_height / ROWS
150
+
151
  fig, ax = plt.subplots(figsize=(14, 8))
152
 
153
+ # Arka plan resmini göster
154
+ ax.imshow(bg_img, extent=[0, COLS, 0, ROWS], aspect='auto')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ # Path'i çiz
157
  if path:
158
+ # Path çizgisi
159
+ path_x = [x + 0.5 for x, y in path]
160
+ path_y = [ROWS - y - 0.5 for x, y in path]
161
+ ax.plot(path_x, path_y, color=color, linewidth=4, alpha=0.7, zorder=5)
162
+
163
+ # Start ve goal noktaları
164
  for i, (x, y) in enumerate(path):
165
  if (x, y) == start:
166
+ circle = plt.Circle((x + 0.5, ROWS - y - 0.5), 0.4,
167
+ color='#00FF00', edgecolor='white',
168
+ linewidth=3, zorder=10)
169
+ ax.add_patch(circle)
170
+ ax.text(x + 0.5, ROWS - y - 0.5, 'S',
171
+ ha='center', va='center',
172
+ fontsize=14, color='white', weight='bold', zorder=11)
173
  elif (x, y) == goal:
174
+ circle = plt.Circle((x + 0.5, ROWS - y - 0.5), 0.4,
175
+ color='#FF0000', edgecolor='white',
176
+ linewidth=3, zorder=10)
177
+ ax.add_patch(circle)
178
+ ax.text(x + 0.5, ROWS - y - 0.5, 'G',
179
+ ha='center', va='center',
180
+ fontsize=14, color='white', weight='bold', zorder=11)
 
 
181
 
182
  path_length = sum(GRID[y][x] for x, y in path[1:])
183
+ info_text = f"{title}\nPath: {len(path)} nodes | Cost: {path_length}"
184
  else:
185
+ info_text = f"{title}\nNo path found!"
186
 
187
  ax.set_xlim(0, COLS)
188
  ax.set_ylim(0, ROWS)
189
  ax.set_aspect('equal')
190
  ax.axis('off')
191
+ ax.text(COLS/2, ROWS + 0.5, info_text,
192
+ ha='center', va='bottom',
193
+ fontsize=14, weight='bold',
194
+ bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))
 
 
 
 
 
 
 
 
 
 
195
 
196
  plt.tight_layout()
197
 
 
198
  buf = io.BytesIO()
199
  plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')
200
  buf.seek(0)
 
203
 
204
  return img
205
 
206
+ @app.route('/')
207
+ def index():
208
+ return render_template('index.html')
209
+
210
+ @app.route('/find_path', methods=['POST'])
211
+ def find_path():
212
+ data = request.json
213
+ start_x = int(data['start_x'])
214
+ start_y = int(data['start_y'])
215
+ goal_x = int(data['goal_x'])
216
+ goal_y = int(data['goal_y'])
217
+ algorithm = data['algorithm']
218
+
219
+ img = visualize_path(start_x, start_y, goal_x, goal_y, algorithm)
220
+
221
+ # PIL Image'i base64'e çevir
222
+ buf = io.BytesIO()
223
+ img.save(buf, format='PNG')
224
+ buf.seek(0)
225
+ img_base64 = base64.b64encode(buf.getvalue()).decode('utf-8')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
+ return jsonify({'image': f'data:image/png;base64,{img_base64}'})
 
 
 
 
228
 
229
  if __name__ == "__main__":
230
+ app.run(host="0.0.0.0", port=7860, debug=False)
 
 
 
 
docker-compose.yml DELETED
@@ -1,11 +0,0 @@
1
- version: '3.8'
2
-
3
- services:
4
- pathfinding:
5
- build: .
6
- ports:
7
- - "7860:7860"
8
- environment:
9
- - GRADIO_SERVER_NAME=0.0.0.0
10
- - GRADIO_SERVER_PORT=7860
11
- restart: unless-stopped
 
 
 
 
 
 
 
 
 
 
 
 
main.py DELETED
@@ -1,87 +0,0 @@
1
- import pygame as pg
2
- from heapq import *
3
- from A_Star import a_star
4
- from Dijkstra import dijkstra
5
- from Bellman_Ford import bellman_ford
6
-
7
- # Konumun merkezine yerleştirilen çemberin pozisyonunu döndürüyor
8
- def get_circle(x, y):
9
- return (x * TILE + TILE // 2, y * TILE + TILE // 2), TILE // 7 # Çemberin merkezini ve yarıçapını döndür
10
-
11
- # Komşu hücreleri kontrol ediyor
12
- def neighbor_control(x, y):
13
- # Komşuların hangi yönlerde olduğunu belirleyen liste (sol, yukarı, sağ, aşağı)
14
- ways = [-1, 0], [0, -1], [1, 0], [0, 1]
15
- neighbor = []
16
-
17
- for dx, dy in ways:
18
- new_dx, new_dy = x + dx, y + dy
19
- # Komşu hücrelerin oyun alanı sınırları içinde olup olmadığını kontrol et
20
- if cols > new_dx >= 0 and rows > new_dy >= 0:
21
- neighbor.append((grid[new_dy][new_dx], (new_dx, new_dy))) # Geçerli komşuyu listeye ekle
22
- return neighbor
23
-
24
- # Fare ile tıklanan hücreyi seçiyor.
25
- def get_click_mouse_pos():
26
- x, y = pg.mouse.get_pos() # Fare imlecinin konumunu al
27
- grid_x, grid_y = x // TILE, y // TILE # Imlecin bulunduğu grid hücresini bul
28
- pg.draw.circle(sc, pg.Color('black'), * ((grid_x * TILE + TILE // 2, grid_y * TILE + TILE // 2), TILE // 7)) # Hücrede kırmızı çember çiz
29
- click = pg.mouse.get_pressed() # Fare tıklaması kontrolü
30
- return (grid_x, grid_y) if click[0] else False # Sol tıklama yapılmışsa pozisyonu döndür, aksi halde False döndür
31
-
32
- # Oyun alanının boyutları (kolonlar, satırlar ve hücre boyutu)
33
- cols, rows = 12, 8
34
- TILE = 70 # Her bir hücrenin piksel boyutu
35
-
36
- # Pygame başlatma ve ekran ayarlama
37
- pg.init()
38
- sc = pg.display.set_mode([cols * TILE, rows * TILE])
39
- clock = pg.time.Clock()
40
-
41
- # Oyun alanı için grid oluşturma (her hücrede maliyetler)
42
- grid = [[4, 4, 4, 4, 4, 4, 4, 2, 3, 2, 4, 2],
43
- [4, 4, 4, 4, 9, 9, 3, 2, 2, 4, 4, 4],
44
- [4, 4, 2, 4, 2, 2, 2, 1, 1, 9, 9, 4],
45
- [4, 2, 2, 4, 2, 2, 1, 1, 1, 4, 4, 2],
46
- [1, 1, 2, 1, 1, 1, 1, 9, 1, 1, 1, 1],
47
- [4, 1, 2, 1, 9, 2, 1, 1, 1, 9, 2, 2],
48
- [4, 1, 4, 1, 2, 4, 4, 1, 1, 4, 4, 2],
49
- [1, 1, 1, 1, 2, 4, 2, 2, 1, 2, 3, 2]]
50
-
51
- # Oyun alanı için graph oluşturma (komşuluk ilişkileri ile)
52
- graph = {}
53
- for y, row in enumerate(grid):
54
- for x, col in enumerate(row):
55
- graph[(x, y)] = graph.get((x, y), []) + neighbor_control(x, y)
56
-
57
- # Başlangıç ve hedef konum
58
- start = (0, 7)
59
- goal = start
60
- visited = []
61
-
62
- # Arka plan resmi yükleme ve ölçeklendirme
63
- bg = pg.image.load('./resim/map.jpg').convert()
64
- bg = pg.transform.scale(bg, (cols * TILE, rows * TILE))
65
-
66
- # Oyun döngüsü
67
- while True:
68
-
69
- sc.blit(bg, (0, 0))
70
- mouse_pos = get_click_mouse_pos()
71
- if mouse_pos:
72
- #visited = a_star(graph, start, mouse_pos) # A* algoritmasını çalıştır ve yolu bul
73
- #visited = dijkstra(graph, start, mouse_pos) # dijkstra algoritmasını çalıştır ve yolu bul
74
- visited = bellman_ford(graph, start, mouse_pos) # bellman_ford algoritmasını çalıştır ve yolu bul
75
-
76
-
77
- goal = mouse_pos # Hedefi fare ile tıklanan pozisyona ayarla
78
-
79
- if visited:
80
- for path_segment in visited:
81
- pg.draw.circle(sc, pg.Color('blue'), *get_circle(*path_segment)) # Bulunan yol üzerindeki hücreleri maviyle işaretle
82
- pg.draw.circle(sc, pg.Color('green'), *get_circle(*start)) # Başlangıç hücresini yeşille işaretle
83
- pg.draw.circle(sc, pg.Color('red'), *get_circle(*goal)) # Hedef hücresini kırmızı işaretle
84
-
85
- [exit() for event in pg.event.get() if event.type == pg.QUIT]
86
- pg.display.flip()
87
- clock.tick(30)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
- gradio==4.16.0
2
  numpy==1.24.3
3
  matplotlib==3.7.1
4
  Pillow==10.2.0
 
1
+ Flask==3.0.0
2
  numpy==1.24.3
3
  matplotlib==3.7.1
4
  Pillow==10.2.0
run_local.sh DELETED
@@ -1,30 +0,0 @@
1
- #!/bin/bash
2
-
3
- echo "🚀 Starting Path Finding Algorithms Visualizer..."
4
- echo ""
5
-
6
- # Check if Docker is installed
7
- if ! command -v docker &> /dev/null; then
8
- echo "❌ Docker is not installed. Please install Docker first."
9
- echo "Visit: https://docs.docker.com/get-docker/"
10
- exit 1
11
- fi
12
-
13
- # Build Docker image
14
- echo "📦 Building Docker image..."
15
- docker build -t pathfinding-app .
16
-
17
- if [ $? -ne 0 ]; then
18
- echo "❌ Docker build failed!"
19
- exit 1
20
- fi
21
-
22
- echo "✅ Docker image built successfully!"
23
- echo ""
24
-
25
- # Run container
26
- echo "🏃 Running container..."
27
- docker run -p 7860:7860 pathfinding-app
28
-
29
- # Or use docker-compose
30
- # docker-compose up
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
templates/index.html ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Path Finding Algorithms Visualizer</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
11
+ min-height: 100vh;
12
+ padding: 20px;
13
+ }
14
+ .container {
15
+ background: white;
16
+ border-radius: 15px;
17
+ padding: 30px;
18
+ box-shadow: 0 10px 40px rgba(0,0,0,0.2);
19
+ }
20
+ .header {
21
+ text-align: center;
22
+ margin-bottom: 30px;
23
+ }
24
+ .header h1 {
25
+ color: #667eea;
26
+ font-weight: bold;
27
+ }
28
+ .controls-panel {
29
+ background: #f8f9fa;
30
+ padding: 20px;
31
+ border-radius: 10px;
32
+ margin-bottom: 20px;
33
+ }
34
+ .slider-container {
35
+ margin: 15px 0;
36
+ }
37
+ .slider-label {
38
+ font-weight: 600;
39
+ color: #495057;
40
+ margin-bottom: 5px;
41
+ }
42
+ .slider-value {
43
+ display: inline-block;
44
+ min-width: 30px;
45
+ text-align: center;
46
+ font-weight: bold;
47
+ color: #667eea;
48
+ }
49
+ .btn-find {
50
+ width: 100%;
51
+ padding: 12px;
52
+ font-size: 18px;
53
+ font-weight: bold;
54
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
55
+ border: none;
56
+ margin-top: 20px;
57
+ }
58
+ .btn-find:hover {
59
+ transform: translateY(-2px);
60
+ box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
61
+ }
62
+ #resultImage {
63
+ max-width: 100%;
64
+ border-radius: 10px;
65
+ box-shadow: 0 5px 20px rgba(0,0,0,0.1);
66
+ }
67
+ .info-box {
68
+ background: #e7f3ff;
69
+ padding: 15px;
70
+ border-radius: 8px;
71
+ border-left: 4px solid #667eea;
72
+ margin-top: 20px;
73
+ }
74
+ .info-box h6 {
75
+ color: #667eea;
76
+ font-weight: bold;
77
+ }
78
+ .algorithm-btn {
79
+ margin: 5px;
80
+ }
81
+ .loading {
82
+ display: none;
83
+ text-align: center;
84
+ padding: 40px;
85
+ }
86
+ .spinner-border {
87
+ color: #667eea;
88
+ }
89
+ </style>
90
+ </head>
91
+ <body>
92
+ <div class="container">
93
+ <div class="header">
94
+ <h1>🗺️ Path Finding Algorithms Visualizer</h1>
95
+ <p class="text-muted">Select start and goal positions, choose an algorithm, and visualize the shortest path!</p>
96
+ </div>
97
+
98
+ <div class="row">
99
+ <div class="col-lg-4">
100
+ <div class="controls-panel">
101
+ <h5 class="mb-3">⚙️ Settings</h5>
102
+
103
+ <!-- Algorithm Selection -->
104
+ <div class="mb-4">
105
+ <label class="slider-label">🎯 Algorithm</label>
106
+ <div class="btn-group-vertical w-100" role="group">
107
+ <input type="radio" class="btn-check" name="algorithm" id="astar" value="A*" checked>
108
+ <label class="btn btn-outline-primary algorithm-btn" for="astar">
109
+ A* (Fastest)
110
+ </label>
111
+
112
+ <input type="radio" class="btn-check" name="algorithm" id="dijkstra" value="Dijkstra">
113
+ <label class="btn btn-outline-warning algorithm-btn" for="dijkstra">
114
+ Dijkstra (Classic)
115
+ </label>
116
+
117
+ <input type="radio" class="btn-check" name="algorithm" id="bellman" value="Bellman-Ford">
118
+ <label class="btn btn-outline-danger algorithm-btn" for="bellman">
119
+ Bellman-Ford (Robust)
120
+ </label>
121
+ </div>
122
+ </div>
123
+
124
+ <!-- Start Position -->
125
+ <h6 class="mt-4">📍 Start Position</h6>
126
+ <div class="slider-container">
127
+ <label class="slider-label">
128
+ X: <span class="slider-value" id="startXValue">0</span>
129
+ </label>
130
+ <input type="range" class="form-range" id="startX" min="0" max="11" value="0">
131
+ </div>
132
+ <div class="slider-container">
133
+ <label class="slider-label">
134
+ Y: <span class="slider-value" id="startYValue">7</span>
135
+ </label>
136
+ <input type="range" class="form-range" id="startY" min="0" max="7" value="7">
137
+ </div>
138
+
139
+ <!-- Goal Position -->
140
+ <h6 class="mt-4">🎯 Goal Position</h6>
141
+ <div class="slider-container">
142
+ <label class="slider-label">
143
+ X: <span class="slider-value" id="goalXValue">11</span>
144
+ </label>
145
+ <input type="range" class="form-range" id="goalX" min="0" max="11" value="11">
146
+ </div>
147
+ <div class="slider-container">
148
+ <label class="slider-label">
149
+ Y: <span class="slider-value" id="goalYValue">0</span>
150
+ </label>
151
+ <input type="range" class="form-range" id="goalY" min="0" max="7" value="0">
152
+ </div>
153
+
154
+ <!-- Find Path Button -->
155
+ <button class="btn btn-primary btn-find" onclick="findPath()">
156
+ 🔍 Find Path
157
+ </button>
158
+
159
+ <!-- Info Box -->
160
+ <div class="info-box">
161
+ <h6>📝 Grid Info</h6>
162
+ <ul class="small mb-0">
163
+ <li><strong>Size:</strong> 12x8 cells</li>
164
+ <li><strong>Cost Range:</strong> 1-9</li>
165
+ <li><strong>Green:</strong> Start</li>
166
+ <li><strong>Red:</strong> Goal</li>
167
+ <li><strong>Blue/Orange/Red:</strong> Path</li>
168
+ </ul>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <div class="col-lg-8">
174
+ <div class="visualization-panel">
175
+ <h5 class="mb-3">🗺️ Visualization</h5>
176
+ <div id="loading" class="loading">
177
+ <div class="spinner-border" role="status">
178
+ <span class="visually-hidden">Loading...</span>
179
+ </div>
180
+ <p class="mt-3">Calculating path...</p>
181
+ </div>
182
+ <div id="imageContainer">
183
+ <img id="resultImage" src="" alt="Path visualization will appear here">
184
+ </div>
185
+ </div>
186
+ </div>
187
+ </div>
188
+ </div>
189
+
190
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
191
+ <script>
192
+ // Update slider values
193
+ document.getElementById('startX').addEventListener('input', function() {
194
+ document.getElementById('startXValue').textContent = this.value;
195
+ });
196
+ document.getElementById('startY').addEventListener('input', function() {
197
+ document.getElementById('startYValue').textContent = this.value;
198
+ });
199
+ document.getElementById('goalX').addEventListener('input', function() {
200
+ document.getElementById('goalXValue').textContent = this.value;
201
+ });
202
+ document.getElementById('goalY').addEventListener('input', function() {
203
+ document.getElementById('goalYValue').textContent = this.value;
204
+ });
205
+
206
+ // Load initial visualization
207
+ window.onload = function() {
208
+ findPath();
209
+ };
210
+
211
+ // Find Path function
212
+ async function findPath() {
213
+ const startX = document.getElementById('startX').value;
214
+ const startY = document.getElementById('startY').value;
215
+ const goalX = document.getElementById('goalX').value;
216
+ const goalY = document.getElementById('goalY').value;
217
+ const algorithm = document.querySelector('input[name="algorithm"]:checked').value;
218
+
219
+ // Show loading
220
+ document.getElementById('loading').style.display = 'block';
221
+ document.getElementById('imageContainer').style.display = 'none';
222
+
223
+ try {
224
+ const response = await fetch('/find_path', {
225
+ method: 'POST',
226
+ headers: {
227
+ 'Content-Type': 'application/json',
228
+ },
229
+ body: JSON.stringify({
230
+ start_x: startX,
231
+ start_y: startY,
232
+ goal_x: goalX,
233
+ goal_y: goalY,
234
+ algorithm: algorithm
235
+ })
236
+ });
237
+
238
+ const data = await response.json();
239
+
240
+ // Hide loading, show image
241
+ document.getElementById('loading').style.display = 'none';
242
+ document.getElementById('imageContainer').style.display = 'block';
243
+ document.getElementById('resultImage').src = data.image;
244
+ } catch (error) {
245
+ console.error('Error:', error);
246
+ alert('An error occurred while finding the path. Please try again.');
247
+ document.getElementById('loading').style.display = 'none';
248
+ document.getElementById('imageContainer').style.display = 'block';
249
+ }
250
+ }
251
+ </script>
252
+ </body>
253
+ </html>