]> Skullheadx's Git Forge - The-Traveling-Salesman-Problem.git/commitdiff
mst
authorSkullheadx <94652084+Skullheadx@users.noreply.github.com>
Wed, 28 Dec 2022 04:14:50 +0000 (23:14 -0500)
committerSkullheadx <94652084+Skullheadx@users.noreply.github.com>
Wed, 28 Dec 2022 04:14:50 +0000 (23:14 -0500)
display.py
graph.py
main.py

index 5faebd340718f4b98a31fd73c7c513af8eff7aaa..dbb42346c01b96f5838fb9b12ccde9f09f943c6b 100644 (file)
@@ -1,5 +1,6 @@
 import pygame
 import math
+from graph import distance
 
 pygame.init()
 
@@ -8,6 +9,41 @@ BLACK = (0, 0, 0)
 GRAY = (128, 128, 128)
 BLUE = (0, 0, 255)
 ORANGE = (255, 165, 0)
+RED = (255, 0, 0)
+GREEN = (0, 255, 0)
+
+
+def find_MST(route: list) -> list:
+    visited = [route[0]]
+    unvisited = route[1:]
+    for i in range(len(route) - 1):
+        v1 = visited[i]
+        minimum = None
+        min_town = None
+        for v2 in unvisited:
+            d = distance(v1, v2)
+            if minimum is None or d <= minimum:
+                minimum = d
+                min_town = v2
+        visited.append(min_town)
+        unvisited.remove(min_town)
+    return visited
+
+
+def find_one_tree(route: list) -> list:
+    removed_vertex = route[0]
+    mst = find_MST(route[1:-1])
+    distances = []
+    for town in route[1:-1]:
+        distances.append((distance(removed_vertex, town), town))
+    distances.sort()
+    mst.insert(0, removed_vertex)
+    mst.insert(0, distances[0][1])
+    mst.insert(0, removed_vertex)
+    mst.insert(0, distances[1][1])
+    mst.insert(0, removed_vertex)
+
+    return mst
 
 
 class Node:
@@ -85,6 +121,9 @@ class Display:
         self.route = route
         self.salesman = Salesman(self.route)
 
+        # self.mst = find_MST(route[:-1])
+        # self.ot = find_one_tree(route)
+
     def update(self, delta: float) -> None:
         self.salesman.update(delta)
 
@@ -103,8 +142,9 @@ class Display:
             self.screen.fill(WHITE)
 
             if len(self.route) > 1:
-                pygame.draw.aalines(self.screen, BLUE, True, self.route, 5)
-
+                # pygame.draw.lines(self.screen, GREEN, False, self.ot, 15)  # One Tree
+                # pygame.draw.lines(self.screen, RED, False, self.mst, 10)  # Minimum Spanning Tree
+                pygame.draw.lines(self.screen, BLUE, True, self.route, 3)  # Route
             for node in self.nodes:
                 node.draw(self.screen)
 
index e37cc1e5eead28fb177bbde2a9c8430ebee04b21..52423ccc80fe346f8bf8e957e03c6003c44cfdfa 100644 (file)
--- a/graph.py
+++ b/graph.py
@@ -31,6 +31,16 @@ def create(path: str, width: int, height: int, nodes: int):
     return graph, filename
 
 
+def read(path: str, filename: str) -> list:
+    with open(os.path.join(path, filename)) as f:
+        contents = f.read().split("\n")[1:]
+        if contents[-1] == "":
+            contents = contents[:-1]
+    graph = [tuple(map(int, i.split(" "))) for i in contents]
+
+    return graph
+
+
 def distance(town1: tuple, town2: tuple) -> float:
     return pow(pow(town1[0] - town2[0], 2) + pow(town1[1] - town2[1], 2), 0.5)
 
@@ -102,18 +112,20 @@ def find_MST(graph: list) -> float:
     mst = 0.0
     visited = [graph[0]]
     unvisited = graph[1:]
-    for i in range(len(graph)-1):
-        v1 = visited[i]
+    for i in range(len(graph) - 1):
         minimum = None
-        min_town = None
-        for v2 in unvisited:
-            d = distance(v1, v2)
-            if minimum is None or d <= minimum:
-                minimum = d
-                min_town = v2
-        visited.append(min_town)
-        unvisited.remove(min_town)
-        mst += distance(v1, min_town)
+        min_town1 = None
+        min_town2 = None
+        for v1 in visited:
+            for v2 in unvisited:
+                d = distance(v1, v2)
+                if minimum is None or d <= minimum:
+                    minimum = d
+                    min_town1 = v1
+                    min_town2 = v2
+        visited.append(min_town2)
+        unvisited.remove(min_town2)
+        mst += distance(min_town1, min_town2)
     return mst
 
 
@@ -124,4 +136,5 @@ def find_one_tree(graph: list) -> float:
     for town in graph[1:]:
         distances.append(distance(removed_vertex, town))
     distances.sort()
-    return mst + distances[0] + distances[1]
+
+    return mst + distances[1]
diff --git a/main.py b/main.py
index f167ab5063443ad8b25e8145872aa510a14893de..d20e379bf145ae3d82bd5d5d6a2b30e775468b40 100644 (file)
--- a/main.py
+++ b/main.py
@@ -1,4 +1,4 @@
-from graph import create, print_info, find_MST, find_one_tree
+from graph import create, read, print_info, find_MST, find_one_tree
 from display import Display
 from brute_force import brute_force
 from nearest_neighbor import nearest_neighbor
@@ -7,6 +7,7 @@ import os
 
 GRAPH_PATH = "graphs/"
 DELETE_PREVIOUS_FILES = True
+CREATE_NEW_GRAPHS = True
 
 
 def main():
@@ -20,17 +21,21 @@ def main():
                 else:
                     print("The file does not exist")
 
-    graph, filename = create(GRAPH_PATH, 720, 720, 100)
+    if CREATE_NEW_GRAPHS:
+        graph, filename = create(GRAPH_PATH, 640, 640, 500)
+    else:
+        filename = "graph1.txt"
+        graph = read(GRAPH_PATH, filename)
 
     time_start = perf_counter()
     # route = brute_force(graph)  # 10 nodes in 85.042 seconds. Optimal = 2,262.29
     route = nearest_neighbor(graph)  # 100 nodes in 0.5762094999663532 seconds. Distance = 6,270.568142156188
     time_end = perf_counter()
 
-    MST = find_MST(graph)
+    MST = find_MST(graph)
     ONE_TREE = find_one_tree(graph)
 
-    print_info(route, time_end - time_start, "NN Heuristic", MST, ONE_TREE, r=100)
+    print_info(route, time_end - time_start, "NN Heuristic", 0.0, ONE_TREE, r=100)
 
     display = Display(os.path.join(GRAPH_PATH, filename), route)
     display.show()