From: Skullheadx <94652084+Skullheadx@users.noreply.github.com> Date: Wed, 28 Dec 2022 06:34:36 +0000 (-0500) Subject: MST + One Tree bounds added X-Git-Url: http://git.skullheadx.com/sitemap.xml?a=commitdiff_plain;h=57e8544e7d04f2504f97ba95b577d947e494ab88;p=The-Traveling-Salesman-Problem.git MST + One Tree bounds added --- diff --git a/display.py b/display.py index dbb4234..afeeae0 100644 --- a/display.py +++ b/display.py @@ -1,6 +1,7 @@ import pygame import math from graph import distance +from queue import PriorityQueue pygame.init() @@ -14,20 +15,24 @@ 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 + q = PriorityQueue() + head = route[0] + seen = set() + mst = [] + for town in route: + q.put((distance(town, head), head, town)) + while not q.empty(): + d, start, end = q.get() + if end in seen: + continue + seen.add(end) + + mst.append((start, end)) + + for town in route: + q.put((distance(town, end), end, town)) + + return mst def find_one_tree(route: list) -> list: @@ -37,13 +42,10 @@ def find_one_tree(route: list) -> list: 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) + mst.append((distances[0][1], removed_vertex)) + mst.append((distances[1][1], removed_vertex)) - return mst + return mst, removed_vertex class Node: @@ -51,10 +53,10 @@ class Node: outline_colour = BLACK text_colour = WHITE - radius = 5 + radius = 6 thickness = 1 - # font = pygame.font.SysFont("arial", 12) + # font = pygame.font.SysFont("arial", 20) def __init__(self, position: tuple, number: int) -> None: self.position = pygame.Vector2(position) @@ -115,14 +117,14 @@ class Display: contents = contents[:-1] self.WIDTH, self.HEIGHT, self.N = tuple(map(int, contents[0].split(" "))) - self.nodes = [Node(node, num) for num, node in enumerate(route)] + self.nodes = [Node(tuple(map(int, node.split(" "))), num) for num, node in enumerate(contents[1:])] self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT)) self.route = route self.salesman = Salesman(self.route) - # self.mst = find_MST(route[:-1]) - # self.ot = find_one_tree(route) + self.mst = find_MST(route[:-1]) + self.ot,self.ot_removed_point = find_one_tree(route) def update(self, delta: float) -> None: self.salesman.update(delta) @@ -141,14 +143,18 @@ class Display: self.screen.fill(WHITE) + pygame.draw.circle(self.screen,BLUE,self.ot_removed_point,15) + if len(self.route) > 1: - # 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 line in self.ot: # One Tree + start, end = line + pygame.draw.line(self.screen, GREEN, start, end, 12) + for line in self.mst: # Minimum Spanning Tree + start, end = line + pygame.draw.line(self.screen, RED, start, end, 7) + pygame.draw.aalines(self.screen, BLUE, True, self.route) # Route for node in self.nodes: node.draw(self.screen) - self.salesman.draw(self.screen) - pygame.display.update() delta = clock.tick(60) / 1000 # Seconds diff --git a/graph.py b/graph.py index 52423cc..b3cad99 100644 --- a/graph.py +++ b/graph.py @@ -1,5 +1,6 @@ import os import random +from queue import PriorityQueue def prune_filename(filename: str) -> int: @@ -50,7 +51,8 @@ def get_distances(graph: list) -> dict: for town1 in graph: distances[town1] = dict() for town2 in graph: - distances[town1][town2] = distance(town1, town2) + if town1 != town2: + distances[town1][town2] = distance(town1, town2) return distances @@ -79,14 +81,14 @@ def find_shortest_route(routes: list) -> list: def print_info(route: list, time: float, method_name: str, mst: float, ot: float, r=0) -> None: print( f""" - Traveling Salesman Problem - Method Used: {method_name} - Time Used: {round(time, r):,} seconds - Number of Nodes: {(len(route) - 1):,} - Distance: {round(calculate_route(route), r):,} - Minimum Spanning Tree: {round(mst, r):,} - One Tree: {round(ot, r):,} - """) +Traveling Salesman Problem +Method Used: {method_name} +Time Used: {round(time, r):,} seconds +Number of Nodes: {(len(route) - 1):,} +Distance: {round(calculate_route(route), r):,} +Minimum Spanning Tree: {round(mst, r):,} +One Tree: {round(ot, r):,} +""") """ @@ -110,22 +112,19 @@ MST cost <= cost(T) def find_MST(graph: list) -> float: mst = 0.0 - visited = [graph[0]] - unvisited = graph[1:] - for i in range(len(graph) - 1): - minimum = None - 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) + q = PriorityQueue() + head = graph[0] + seen = set() + for town in graph: + q.put((distance(town, head), head, town)) + while not q.empty(): + d, start, end = q.get() + if end in seen: + continue + seen.add(end) + mst += d + for town in graph: + q.put((distance(town, end), end, town)) return mst @@ -136,5 +135,4 @@ def find_one_tree(graph: list) -> float: for town in graph[1:]: distances.append(distance(removed_vertex, town)) distances.sort() - return mst + distances[1] diff --git a/main.py b/main.py index d20e379..eedd9ff 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ def main(): print("The file does not exist") if CREATE_NEW_GRAPHS: - graph, filename = create(GRAPH_PATH, 640, 640, 500) + graph, filename = create(GRAPH_PATH, 640, 640, 100) else: filename = "graph1.txt" graph = read(GRAPH_PATH, filename) @@ -32,10 +32,10 @@ def main(): 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", 0.0, ONE_TREE, r=100) + print_info(route, time_end - time_start, "NN Heuristic", MST, ONE_TREE, r=100) display = Display(os.path.join(GRAPH_PATH, filename), route) display.show()