From: Skullheadx <704277@pdsb.net> Date: Wed, 28 Dec 2022 02:07:30 +0000 (-0500) Subject: Nearest Neighbor Heuristic added X-Git-Url: http://git.skullheadx.com/about.html?a=commitdiff_plain;h=5d6942c064f6230e0befbfaabebcdbe0779d27d4;p=The-Traveling-Salesman-Problem.git Nearest Neighbor Heuristic added --- diff --git a/README.md b/README.md index b116199..97d518f 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,8 @@ Assuming that: **Method 1: Brute Force** By checking every single possibility and calculating the distance of each route, the shortest path can be determined. As **n**, the number of towns, increases, on the first turn, (starting at any town) there are n-1 towns to choose from, then on the second turn there are n-2 choices and so on until there is only one option left which is to return to the starting town. This means that there are `(n - 1)! / 2` total possibilities accounting for duplicates. This strategy while easy to implement, is not suited to calculating more than 20 nodes as the number possibilities that would be considered at _n=20_ is `(20-1)!/2 = 60,822,550,204,416,000`. + +-------------------------------------------------------------------------------------------------------------- +**Method 2: Nearest Neighbor (NN) Heuristic** + +If we start at any town and find the closest town that we haven't been to yet and continue this until all the cities have been visited, this creates a complete tour. diff --git a/main.py b/main.py index a8c1ebe..6959aa6 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,8 @@ -from graph import create +from graph import create, print_info from display import Display from brute_force import brute_force +from nearest_neighbor import nearest_neighbor +from time import perf_counter import os GRAPH_PATH = "graphs/" @@ -18,12 +20,17 @@ def main(): else: print("The file does not exist") - graph, filename = create(GRAPH_PATH, 640, 640, 5) - display = Display(os.path.join(GRAPH_PATH, filename)) + graph, filename = create(GRAPH_PATH, 720, 720, 100) - route = brute_force(graph) + 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() - display.show(route) + print_info(route, time_end - time_start, "NN Heuristic", r=100) + + display = Display(os.path.join(GRAPH_PATH, filename), route) + display.show() if __name__ == "__main__": diff --git a/nearest_neighbor.py b/nearest_neighbor.py new file mode 100644 index 0000000..582a009 --- /dev/null +++ b/nearest_neighbor.py @@ -0,0 +1,33 @@ +from graph import distance, find_shortest_route + + +def nearest_neighbor(graph: list) -> list: + routes = [] + for start_index in range(len(graph)): + routes.append(NN(graph, start_index)) + + return find_shortest_route(routes) + + +def NN(graph: list, start_index): + route = [] + seen = set() + start = graph[start_index] + route.append(start) + seen.add(start) + + for i in range(len(graph) - 1): + shortest_distance = None + next_town = None + for town in graph: + if town in seen: + continue + d = distance(route[-1], town) + if shortest_distance is None or d < shortest_distance: + shortest_distance = d + next_town = town + route.append(next_town) + seen.add(next_town) + + route.append(start) + return route