Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.17 KB | None | 0 0
  1. from numpy.random import choice
  2. import numpy as np
  3. import csv
  4. import matplotlib.pyplot as plt
  5. import math
  6.  
  7. def sigmoid(x):
  8.   return 1 / (1 + math.exp(-x))
  9.  
  10. with open('Lokalizacje.csv', newline='') as csvfile:
  11.     localizations = list(csv.reader(csvfile, delimiter=';'))
  12.  
  13. with open('Odleglosci.csv', newline='') as csvfile:
  14.     distances = list(csv.reader(csvfile, delimiter=';'))
  15.  
  16. with open('tydzien2_2016.csv', newline='') as csvfile:
  17.     demands = list(csv.reader(csvfile, delimiter=';'))
  18.  
  19. def get_demand(city_name):
  20.     for i in range(0, len(demands)):
  21.         if (demands[i][0] == city_name):
  22.             return int(demands[i][1])
  23.     return 0
  24.  
  25.  
  26. def get_distance(name1, name2):
  27.     for i in range(0, len(distances)):
  28.         if (distances[i][0] == name1 and distances[i][1] == name2):
  29.             return float(distances[i][3])
  30.         if (distances[i][1] == name1 and distances[i][0] == name2):
  31.             return float(distances[i][3])
  32.     return 0
  33.  
  34. minimal_distance = 10000000000000
  35. minimal_path = []
  36. NUM_OF_CITIES = len(localizations)
  37.  
  38.  
  39. class AntWalk:
  40.  
  41. #read values from files
  42.     def __init__(self):
  43.         self.points = np.zeros((NUM_OF_CITIES, 2))
  44.         self.names = []
  45.         self.city_demand = np.zeros(NUM_OF_CITIES)
  46.         self.pheromones = np.zeros((NUM_OF_CITIES, NUM_OF_CITIES))
  47.         self.distances = np.zeros((NUM_OF_CITIES, NUM_OF_CITIES))
  48.  
  49.         for i in range(0, NUM_OF_CITIES):
  50.             self.names.append((localizations[i][0]))
  51.  
  52.         for i in range(0, NUM_OF_CITIES):
  53.             self.points[i, 0] = float(localizations[i][1])
  54.             self.points[i, 1] = float(localizations[i][2])
  55.  
  56.         for i in range(0, NUM_OF_CITIES):
  57.             self.city_demand[i] = get_demand(self.names[i])
  58.  
  59.         for i in range(0, NUM_OF_CITIES):
  60.             for j in range(i, NUM_OF_CITIES):
  61.                 if (i == j):
  62.                     self.distances[i][j] = 0
  63.                     continue
  64.                 self.distances[i][j] = get_distance(self.names[i], self.names[j])
  65.                 self.distances[j][i] = get_distance(self.names[i], self.names[j])
  66.                 if (get_distance(self.names[i], self.names[j]) == 0):
  67.                     print(str(self.names[i]) + ":::" + str(self.names[j]))
  68.  
  69.         self.total_dist_traveled = 0
  70.         self.paths_traveled = []
  71.  
  72.     def get_paths_distance(self,paths):
  73.         distance_traveled = 0
  74.         for path in paths:
  75.             for i in range(0,len(path)-1):
  76.                 distance_traveled += self.distances[path[i],path[i+1]]
  77.         return distance_traveled
  78.  
  79. #bring capacities, distance traveled and paths traveled to initial state
  80.     def reset(self):
  81.         self.city_demand = np.zeros(NUM_OF_CITIES)
  82.         for i in range(0, NUM_OF_CITIES):
  83.             self.city_demand[i] = get_demand(self.names[i])
  84.         self.total_dist_traveled = 0
  85.         self.paths_traveled = []
  86.  
  87.     def get_probabilites(self, current_city, possible_destinations):
  88.  
  89.         # if nowhere to go return empty list
  90.         if (len(possible_destinations) == 0): return []
  91.         probs = []
  92.         sum_of_probs = 0
  93.         sum_of_pheromones = sum([self.pheromones[current_city][i] for i in possible_destinations])
  94.         max_dist = max([self.distances[current_city][i] for i in possible_destinations])
  95.         min_dist = min([self.distances[current_city][i] for i in possible_destinations])
  96.         if(sum_of_pheromones == 0):
  97.             return [1 / len(possible_destinations) for i in possible_destinations]
  98.         for destination in possible_destinations:
  99.             prob = ((max_dist - self.distances[current_city][destination]) ** 2) * (1 / len(possible_destinations) + self.pheromones[current_city][destination])
  100.             sum_of_probs += prob
  101.             probs.append(prob)
  102.  
  103.         if (sum_of_probs == 0):
  104.             probs = [1 / len(probs) for i in probs]
  105.         else:
  106.             for i in range(0, len(probs)):
  107.                 probs[i] = probs[i] / sum_of_probs
  108.  
  109.         return probs
  110.  
  111.     def walk(self, starting_city, cargo):
  112.  
  113.         visited = []
  114.         distance_traveled = 0
  115.         current_city = starting_city
  116.         while (cargo > 0 and sum(self.city_demand) > 0):
  117.             dropped_cargo = min(cargo, self.city_demand[current_city])
  118.             self.city_demand[current_city] -= dropped_cargo
  119.  
  120.             cargo -= dropped_cargo
  121.  
  122.             visited.append(current_city)
  123.  
  124.             #possible points are those which were not visited and have non-zero demand for supplies
  125.             possible_points = [i for i in range(0, NUM_OF_CITIES) if (i not in visited and self.city_demand[i] > 0)]
  126.  
  127.             #if nowhere to go finish
  128.             if (len(possible_points) == 0 or cargo == 0): break
  129.  
  130.             probabilities = self.get_probabilites(current_city, possible_points)
  131.  
  132.             #choose next point from list of possible points basing on probabilities
  133.             next_point = choice(possible_points, 1, p=probabilities)
  134.  
  135.             #next point is one element list
  136.             next_point = next_point[0]
  137.  
  138.             distance_traveled += self.distances[current_city][next_point]
  139.             current_city = next_point
  140.         #if truck did any travel
  141.         if (distance_traveled > 0):
  142.             for i in range(0, len(visited) - 1):
  143.                 self.pheromones[visited[i]][visited[i + 1]] += (1 / distance_traveled)
  144.                 self.pheromones[visited[i + 1]][visited[i]] += (1 / distance_traveled)
  145.  
  146.         #add path traveled to list of all path traveled
  147.         print(str(distance_traveled) + ":" + str([self.names[i] for i in visited]))
  148.  
  149.         #visited is list of city numbers, translate it to city names
  150.         self.paths_traveled.append([i for i in visited])
  151.         self.total_dist_traveled += distance_traveled
  152.  
  153.     def update_pheromones(self):
  154.         for i in range(0, NUM_OF_CITIES):
  155.             for j in range(i, NUM_OF_CITIES):
  156.                 ant.pheromones[i][j] = ant.pheromones[i][j]*(0.4)
  157.  
  158.  
  159. ant = AntWalk()
  160. x_vals = [i for i in range(0,4000)]
  161. y_vals = [0 for i in range(0,4000)]
  162. for k in range(0, 4000):
  163.     print(k)
  164.     for i in range(0, 5):
  165.         ant.walk(66, 34)
  166.     ant.update_pheromones()
  167.     # if we did better than before, remember result
  168.  
  169.     y_vals[k] = ant.total_dist_traveled
  170.     if (ant.total_dist_traveled < minimal_distance):
  171.         minimal_distance = ant.total_dist_traveled
  172.         minimal_path = ant.paths_traveled
  173.     ant.reset()
  174.  
  175. plt.scatter(x_vals,y_vals)
  176. plt.show()
  177.  
  178.  
  179.     # reset demands,
  180.  
  181. for i in range(0, NUM_OF_CITIES):
  182.     if (ant.city_demand[i] > 0):
  183.         plt.scatter(ant.points[i, 1], ant.points[i, 0])
  184.         plt.annotate(ant.city_demand[i], (ant.points[i, 1], ant.points[i, 0]))
  185. print("!!!!!!!!!!!!!")
  186. print(minimal_distance)
  187. print(minimal_path)
  188. for i in range(0, NUM_OF_CITIES):
  189.     for j in range(0, NUM_OF_CITIES):
  190.         if (ant.pheromones[i][j] != 0.0):
  191.             plt.plot(
  192.                 [ant.points[i][1], ant.points[j][1]],
  193.                 [ant.points[i][0], ant.points[j][0]],
  194.                 'k-', color='r', linewidth=(50 * ant.pheromones[i][j]) / (sum(sum(ant.pheromones))))
  195.             print(ant.pheromones[i][j])
  196.  
  197. plt.ylim(48, 58)
  198. plt.xlim(14, 24)
  199. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement