Advertisement
marklonek

Mownit - TSP

Nov 23rd, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.27 KB | None | 0 0
  1. import random
  2.  
  3. import math
  4. from matplotlib import pyplot as plt
  5.  
  6.  
  7. class RandomPointsGenerator:
  8.     def random_uniform(self, number, x0, x1, y0, y1):
  9.         points = []
  10.         for i in range(number):
  11.             points.append((random.uniform(x0, x1), random.uniform(y0, y1)))
  12.         random.shuffle(points)
  13.         return points
  14.  
  15.     def group_random(self, number, x, y, group_num, e=0.3):
  16.         points = []
  17.         segment_x = x / group_num
  18.         segment_y = y / group_num
  19.         for i in range(group_num):
  20.             for j in range(group_num):
  21.                 group_x0 = i * segment_x + segment_x * e
  22.                 group_x1 = (i + 1) * segment_x - segment_x * e
  23.                 group_y0 = j * segment_y + segment_y * e
  24.                 group_y1 = (j + 1) * segment_y - segment_y * e
  25.                 points += self.random_uniform(int(number / (group_num * group_num)), group_x0, group_x1, group_y0,
  26.                                               group_y1)
  27.         random.shuffle(points)
  28.         return points
  29.  
  30.  
  31. class Plot:
  32.     def plot_points(self, cities, dx, dy):
  33.         fig = plt.figure()
  34.         canvas = fig.add_subplot(1, 1, 1)
  35.  
  36.         canvas.clear()
  37.         canvas.set_xlim(0, dx)
  38.         canvas.set_ylim(0, dy)
  39.  
  40.         for (x1, y1) in cities:
  41.             plt.plot(x1, y1, color='b', linewidth=0.4, marker='o')
  42.         plt.show()
  43.  
  44.     def plot_energy_history(self, information):
  45.         iterations = [x['iteration'] for x in information]
  46.         energies = [x['energy'] for x in information]
  47.         plt.plot(iterations, energies, '.')
  48.         plt.show()
  49.  
  50.     def plot_result(self, cities, x, y):
  51.         fig = plt.figure()
  52.         canvas = fig.add_subplot(1, 1, 1)
  53.  
  54.         canvas.clear()
  55.         canvas.set_xlim(0, x)
  56.         canvas.set_ylim(0, y)
  57.  
  58.         for ((x1, y1), (x2, y2)) in zip(cities, cities[1:]):
  59.             plt.plot([x1, x2], [y1, y2], color='b', linestyle='-', linewidth=0.4, marker='o')
  60.  
  61.         x1, y1 = cities[0]
  62.         x2, y2 = cities[-1]
  63.         plt.plot([x1, x2], [y1, y2], color='b', linestyle='-', linewidth=0.4, marker='o')
  64.  
  65.         plt.show()
  66.  
  67.  
  68. class Swap:
  69.     def consecutive_swap(self, cities):
  70.         new_cities = list(cities)
  71.         l = len(cities)
  72.         i = random.randint(0, l - 1)
  73.         j = (i + 1) % l
  74.         new_cities[i], new_cities[j] = new_cities[j], new_cities[i]
  75.         return new_cities
  76.  
  77.     def arbitrary_swap(self, cities):
  78.         new_cities = list(cities)
  79.         l = len(cities)
  80.         j = i = random.randint(0, l - 1)
  81.         while j == i:
  82.             j = random.randint(0, l - 1)
  83.  
  84.         new_cities[i], new_cities[j] = new_cities[j], new_cities[i]
  85.         return new_cities
  86.  
  87.  
  88. class CoolingFunctions:
  89.     def fun1(self, rate):
  90.         def f(temperature):
  91.             new_temperature = temperature*rate
  92.             return new_temperature
  93.         return f
  94.  
  95.     def fun2(self, rate):
  96.         def f(temperature):
  97.             new_temperature = temperature - rate
  98.             return new_temperature
  99.         return f
  100.  
  101.  
  102. class TSP:
  103.     def distance(self, x, y):
  104.         (a, b) = x
  105.         (c, d) = y
  106.         return math.sqrt((a - c) ** 2 + (b - d) ** 2)
  107.  
  108.     def current_energy(self, cities):
  109.         return sum([self.distance(a, b) for (a, b) in zip(cities, cities[1:])])
  110.  
  111.     def simulate_annealing(self, cities, max_iterations, starting_temperature, cooling_function, swap_function, t_min=0.1):
  112.         energy = self.current_energy(cities)
  113.  
  114.         iteration = 0
  115.         temperature = starting_temperature
  116.         energy_history = []
  117.         best_configuration = {'energy': energy, 'cities': cities}
  118.  
  119.         for i in range(max_iterations):
  120.             energy_history.append({'iteration': iteration, 'energy': energy})
  121.             new_cities = swap_function(cities)
  122.             if iteration % 1000 == 0:
  123.                 print('Iteration {}, energy {}'.format(iteration, energy))
  124.             new_energy = self.current_energy(new_cities)
  125.             if new_energy < best_configuration['energy']:
  126.                 best_configuration = {'energy': new_energy, 'cities': new_cities}
  127.                 cities = new_cities
  128.                 energy = new_energy
  129.             elif math.exp((energy - new_energy) / temperature) > random.random():
  130.                 cities = new_cities
  131.                 energy = new_energy
  132.  
  133.             temperature = cooling_function(temperature)
  134.             if temperature < t_min:
  135.                 print("Return due to temperature")
  136.                 return best_configuration, energy_history
  137.             iteration += 1
  138.         print("Return due to iterations")
  139.         return best_configuration, energy_history
  140.  
  141.  
  142. if __name__ == "__main__":
  143.     generator = RandomPointsGenerator()
  144.     n = 40
  145.     x = 10
  146.     y = 10
  147.     # points = generator.group_random(n, x, y, 3, 0.25)
  148.     points = generator.group_random(n, x, y, 2, 0.2)
  149.     plot = Plot()
  150.     swap = Swap().arbitrary_swap
  151.     cooling = CoolingFunctions().fun1(0.99999)
  152.     best_configuration, energy_history = \
  153.         TSP().simulate_annealing(cities=points, max_iterations=2000000, starting_temperature=20,
  154.                                  cooling_function=cooling, swap_function=swap, t_min=0.001)
  155.  
  156.     plot.plot_result(best_configuration['cities'], x, y)
  157.  
  158.     plot.plot_energy_history(energy_history)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement