├── ACO.py ├── Best solution found at 0 iterations by colony.png ├── Best solution found at 112 iterations by colony.png ├── Best solution found at 128 iterations by colony.png ├── Best solution found at 144 iterations by colony.png ├── Best solution found at 16 iterations by colony.png ├── Best solution found at 160 iterations by colony.png ├── Best solution found at 32 iterations by colony.png ├── Best solution found at 48 iterations by colony.png ├── Best solution found at 64 iterations by colony.png ├── Best solution found at 80 iterations by colony.png ├── Best solution found at 96 iterations by colony.png ├── Cities List.txt ├── README.md └── random solution for 20 cities.png /ACO.py: -------------------------------------------------------------------------------- 1 | # solving Travelling salesman(TSP) using ant colony 2 | import math 3 | import random 4 | import matplotlib.pyplot as plt 5 | 6 | class Draw: 7 | def DrawSolutionPlot(self, cities, path: list, gen=""): 8 | if gen != "": 9 | plt.title(f'Best Path untill Generation:{gen}') 10 | x = [] 11 | y = [] 12 | for point in cities: 13 | x.append(point['x']) 14 | y.append(point['y']) 15 | plt.plot(x, y, 'co') 16 | for route in range(1, len(path)): 17 | source = path[route - 1] 18 | destination = path[route] 19 | plt.arrow(x[source], y[source], x[destination] - x[source], y[destination] - y[source], color='r', 20 | length_includes_head=True) 21 | plt.xlim(0, max(x) * 1.1) 22 | plt.ylim(0, max(y) * 1.1) 23 | plt.show() 24 | 25 | class ACO: 26 | def __init__(self, cities, cityCount, antCount, evaporationRate): 27 | self.cities = cities 28 | self.cityCount = cityCount 29 | self.costMatrix = [] 30 | self.antCount = antCount 31 | self.PheromoneMatrix = [] 32 | self.initialDistances() 33 | self.evaporationRate = evaporationRate 34 | self.draw = Draw() 35 | 36 | def applyEvaporatio(self):#every generation we reduce all cells in pheromone matrix to simulate evaporation of pheromone 37 | for row in range(self.cityCount): 38 | for col in range(self.cityCount): 39 | if (self.PheromoneMatrix[row][col] - self.evaporationRate) < 0.000001: 40 | self.PheromoneMatrix[row][col] = 0.000001 41 | else: 42 | self.PheromoneMatrix[row][col] -= self.evaporationRate 43 | 44 | def solve(self, generations): 45 | step = 0 46 | if generations > 10: 47 | step = int(generations / 10) 48 | bestRoute = list(range(self.cityCount)) 49 | random.shuffle(bestRoute) 50 | self.draw.DrawSolutionPlot(self.cities, bestRoute,f"random solution with cost: {self.getRouteCost(bestRoute)}") 51 | for generation in range(generations): 52 | for ant in range(self.antCount): 53 | route = [] 54 | allowedList = list(range(self.cityCount)) 55 | currentCity = random.randint(0, cityCount - 1) 56 | allowedList.remove(currentCity) 57 | route.append(currentCity) 58 | for cityNum in range(self.cityCount - 1): 59 | nextCity = self.getNextCity(currentCity, allowedList,generation) 60 | route.append(nextCity) 61 | allowedList.remove(nextCity) 62 | currentCity = nextCity 63 | if self.getRouteCost(route) < self.getRouteCost(bestRoute): 64 | bestRoute = route[::] 65 | self.updatePheromone(route,generation+1) 66 | self.applyEvaporatio() 67 | if (generation % step) == 0: 68 | self.draw.DrawSolutionPlot(self.cities, bestRoute, 69 | f"{generation} with cost: {self.getRouteCost(bestRoute)}") 70 | print(f"generation:{generation} best route is: {bestRoute} with cost of: {self.getRouteCost(bestRoute)}") 71 | self.draw.DrawSolutionPlot(self.cities, bestRoute, f"{generations} with cost: {self.getRouteCost(bestRoute)}") 72 | self.draw.DrawSolutionPlot(self.cities, bestRoute, f"{generations} with cost: {self.getRouteCost(bestRoute)}") 73 | print("-------------------------------------------------------") 74 | for line in self.PheromoneMatrix: 75 | print(line) 76 | 77 | def getNextCity(self, currentCity, allowedList, generation):#we give this function a list of reamainedc cities and it choose one for next destination of ant by selection chance of every city 78 | probabilities = [] 79 | sum = 0 80 | for city in allowedList: 81 | sum += self.PheromoneMatrix[currentCity][city]/self.costMatrix[currentCity][city]#we sum all phromones, if we divide it by cost of path then the chace of shorter pathes will increase 82 | for city in allowedList: 83 | probabilities.append(((self.PheromoneMatrix[currentCity][city]/self.costMatrix[currentCity][city]) / sum)) #we divide phromone in path of every city we can go and devide it to sum of all phromones to get the real chance of choosing the city, more phromone of a path leads to more chance to be selected by ant to go 84 | return random.choices(allowedList, weights=probabilities, k=1)[0]# we choose one city in list of allowed cities by its chance 85 | 86 | def updatePheromone(self, route: list,generation): 87 | pheromoneChange = math.sqrt(1/self.getRouteCost(route)) #divideng 1 by route cost will give greater number for shorter distances, so shorter path get greater phromone in cities sequences 88 | for case in range(1, len(route)): 89 | source = route[case - 1] 90 | destination = route[case] 91 | self.PheromoneMatrix[source][destination] += pheromoneChange 92 | self.PheromoneMatrix[destination][source] += pheromoneChange # we update i,j in pheromone matrix just like j,i so the phromone for city1,city2 is equal to phromone of city2,city1 93 | 94 | def getRouteCost(self, route: list): #return cost of a route. for route like: "a,b,c" we sum "a->b" and "b->c" distances and returns it 95 | totalRouteCost = 0 96 | for case in range(1, len(route)): 97 | source = route[case - 1] 98 | destination = route[case] 99 | totalRouteCost += self.costMatrix[source][destination] 100 | return totalRouteCost 101 | 102 | def initialDistances(self): # initial n*n distance matrix and put Euclidean distances in it and n*n pheromone matrix gets initialized with 0.1 in every cell 103 | for i in range(cityCount): 104 | row = [] 105 | pheromone = [] 106 | for j in range(cityCount): 107 | row.append(self.getDistance(self.cities[i], self.cities[j])) 108 | pheromone.append(0.1) 109 | self.costMatrix.append(row) 110 | self.PheromoneMatrix.append(pheromone)#phromone matrix will be initialized to 0.1 111 | 112 | def getDistance(self, city1: dict, city2: dict): # return Euclidean distance between two cities 113 | return math.sqrt((city1['x'] - city2['x']) ** 2 + (city1['y'] - city2['y']) ** 2) 114 | 115 | 116 | # main commands 117 | # read cities names and disctances from "Cities List.txt" file in project directory 118 | cities = [] 119 | cityCount = 0 120 | with open('./Cities List.txt') as f: 121 | for line in f.readlines(): 122 | city = line.split(' ') 123 | cities.append(dict(index=int(city[0]), x=int(city[1]), y=int(city[2]))) 124 | cityCount += 1 125 | 126 | # cities, cityCount, antCount, evaporationRate) 127 | aco = ACO(cities, cityCount, 15, 0.0008) 128 | aco.solve(160) #run aco for 400 iteration 129 | -------------------------------------------------------------------------------- /Best solution found at 0 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 0 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 112 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 112 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 128 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 128 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 144 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 144 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 16 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 16 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 160 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 160 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 32 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 32 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 48 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 48 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 64 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 64 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 80 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 80 iterations by colony.png -------------------------------------------------------------------------------- /Best solution found at 96 iterations by colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/Best solution found at 96 iterations by colony.png -------------------------------------------------------------------------------- /Cities List.txt: -------------------------------------------------------------------------------- 1 | 1 909 649 2 | 2 239 197 3 | 3 627 893 4 | 4 472 730 5 | 5 827 766 6 | 6 661 410 7 | 7 890 230 8 | 8 559 465 9 | 9 945 684 10 | 10 527 928 11 | 11 242 892 12 | 12 100 420 13 | 13 431 350 14 | 14 368 199 15 | 15 112 736 16 | 16 244 667 17 | 17 257 386 18 | 18 640 568 19 | 19 755 726 20 | 20 702 717 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solving-TSP-with-ACO-python 2 | Solving tsp with ACO (ant colony optimization) in python 3 | using heuristic algorithm to solve high dimensional tsp problem 4 | **Cities are included in "Cities List.txt" in repo to add or remove cities you've got to include or exclude cities in every line like: "1 909 649" 5 | First number is city index and next two numbers are city euclidean coordinates: x,y which are set to 0 to 1000 but you can change the range to any range 6 | The distance between cities are calculated by Euclidean Distance which is: 7 | ![Euclidean Distance](https://wikimedia.org/api/rest_v1/media/math/render/svg/2e0c9ce1b3455cb9e92c6bad6684dbda02f69c82)** 8 | **I look forward to you questions about the project!** 9 | 10 | ### a random solution: 11 | ![random solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/random%20solution%20for%2020%20cities.png) 12 | ### route found by algorithm at iteration of 16(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 13 | ![iteration 16 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%2016%20iterations%20by%20colony.png) 14 | ### route found by algorithm at iteration of 32(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 15 | ![iteration 32 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%2032%20iterations%20by%20colony.png) 16 | ### route found by algorithm at iteration of 48(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 17 | ![iteration 48 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%2048%20iterations%20by%20colony.png) 18 | ### route found by algorithm at iteration of 64(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 19 | ![iteration 64 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%2064%20iterations%20by%20colony.png) 20 | ### route found by algorithm at iteration of 80(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 21 | ![iteration 80 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%2080%20iterations%20by%20colony.png) 22 | ### route found by algorithm at iteration of 96(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 23 | ![iteration 96 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%2096%20iterations%20by%20colony.png) 24 | ### route found by algorithm at iteration of 112(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 25 | ![iteration 112 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%20112%20iterations%20by%20colony.png) 26 | ### route found by algorithm at iteration of 128(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 27 | ![iteration 128 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%20128%20iterations%20by%20colony.png) 28 | ### route found by algorithm at iteration of 144(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 29 | ![iteration 144 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%20144%20iterations%20by%20colony.png) 30 | ### route found by algorithm at iteration of 160(feeding algorithm with list of 20 city euclidean coordinates: x,y from 0 to 1000 ): 31 | ![iteration 160 solution](https://github.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/blob/main/Best%20solution%20found%20at%20160%20iterations%20by%20colony.png) 32 | -------------------------------------------------------------------------------- /random solution for 20 cities.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elktrn/solving-TSP-problem-with-ACO-Heuristic-Algorithm-in-python/6dbbfbc92703ff909a5d55556b91aa1d49b85112/random solution for 20 cities.png --------------------------------------------------------------------------------