Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from numpy.random import choice
- import numpy as np
- import csv
- import matplotlib.pyplot as plt
- import math
- def sigmoid(x):
- return 1 / (1 + math.exp(-x))
- with open('Lokalizacje.csv', newline='') as csvfile:
- localizations = list(csv.reader(csvfile, delimiter=';'))
- with open('Odleglosci.csv', newline='') as csvfile:
- distances = list(csv.reader(csvfile, delimiter=';'))
- with open('tydzien2_2016.csv', newline='') as csvfile:
- demands = list(csv.reader(csvfile, delimiter=';'))
- def get_demand(city_name):
- for i in range(0, len(demands)):
- if (demands[i][0] == city_name):
- return int(demands[i][1])
- return 0
- def get_distance(name1, name2):
- for i in range(0, len(distances)):
- if (distances[i][0] == name1 and distances[i][1] == name2):
- return float(distances[i][3])
- if (distances[i][1] == name1 and distances[i][0] == name2):
- return float(distances[i][3])
- return 0
- minimal_distance = 10000000000000
- minimal_path = []
- NUM_OF_CITIES = len(localizations)
- class AntWalk:
- #read values from files
- def __init__(self):
- self.points = np.zeros((NUM_OF_CITIES, 2))
- self.names = []
- self.city_demand = np.zeros(NUM_OF_CITIES)
- self.pheromones = np.zeros((NUM_OF_CITIES, NUM_OF_CITIES))
- self.distances = np.zeros((NUM_OF_CITIES, NUM_OF_CITIES))
- for i in range(0, NUM_OF_CITIES):
- self.names.append((localizations[i][0]))
- for i in range(0, NUM_OF_CITIES):
- self.points[i, 0] = float(localizations[i][1])
- self.points[i, 1] = float(localizations[i][2])
- for i in range(0, NUM_OF_CITIES):
- self.city_demand[i] = get_demand(self.names[i])
- for i in range(0, NUM_OF_CITIES):
- for j in range(i, NUM_OF_CITIES):
- if (i == j):
- self.distances[i][j] = 0
- continue
- self.distances[i][j] = get_distance(self.names[i], self.names[j])
- self.distances[j][i] = get_distance(self.names[i], self.names[j])
- if (get_distance(self.names[i], self.names[j]) == 0):
- print(str(self.names[i]) + ":::" + str(self.names[j]))
- self.total_dist_traveled = 0
- self.paths_traveled = []
- def get_paths_distance(self,paths):
- distance_traveled = 0
- for path in paths:
- for i in range(0,len(path)-1):
- distance_traveled += self.distances[path[i],path[i+1]]
- return distance_traveled
- #bring capacities, distance traveled and paths traveled to initial state
- def reset(self):
- self.city_demand = np.zeros(NUM_OF_CITIES)
- for i in range(0, NUM_OF_CITIES):
- self.city_demand[i] = get_demand(self.names[i])
- self.total_dist_traveled = 0
- self.paths_traveled = []
- def get_probabilites(self, current_city, possible_destinations):
- # if nowhere to go return empty list
- if (len(possible_destinations) == 0): return []
- probs = []
- sum_of_probs = 0
- sum_of_pheromones = sum([self.pheromones[current_city][i] for i in possible_destinations])
- max_dist = max([self.distances[current_city][i] for i in possible_destinations])
- min_dist = min([self.distances[current_city][i] for i in possible_destinations])
- if(sum_of_pheromones == 0):
- return [1 / len(possible_destinations) for i in possible_destinations]
- for destination in possible_destinations:
- prob = ((max_dist - self.distances[current_city][destination]) ** 2) * (1 / len(possible_destinations) + self.pheromones[current_city][destination])
- sum_of_probs += prob
- probs.append(prob)
- if (sum_of_probs == 0):
- probs = [1 / len(probs) for i in probs]
- else:
- for i in range(0, len(probs)):
- probs[i] = probs[i] / sum_of_probs
- return probs
- def walk(self, starting_city, cargo):
- visited = []
- distance_traveled = 0
- current_city = starting_city
- while (cargo > 0 and sum(self.city_demand) > 0):
- dropped_cargo = min(cargo, self.city_demand[current_city])
- self.city_demand[current_city] -= dropped_cargo
- cargo -= dropped_cargo
- visited.append(current_city)
- #possible points are those which were not visited and have non-zero demand for supplies
- possible_points = [i for i in range(0, NUM_OF_CITIES) if (i not in visited and self.city_demand[i] > 0)]
- #if nowhere to go finish
- if (len(possible_points) == 0 or cargo == 0): break
- probabilities = self.get_probabilites(current_city, possible_points)
- #choose next point from list of possible points basing on probabilities
- next_point = choice(possible_points, 1, p=probabilities)
- #next point is one element list
- next_point = next_point[0]
- distance_traveled += self.distances[current_city][next_point]
- current_city = next_point
- #if truck did any travel
- if (distance_traveled > 0):
- for i in range(0, len(visited) - 1):
- self.pheromones[visited[i]][visited[i + 1]] += (1 / distance_traveled)
- self.pheromones[visited[i + 1]][visited[i]] += (1 / distance_traveled)
- #add path traveled to list of all path traveled
- print(str(distance_traveled) + ":" + str([self.names[i] for i in visited]))
- #visited is list of city numbers, translate it to city names
- self.paths_traveled.append([i for i in visited])
- self.total_dist_traveled += distance_traveled
- def update_pheromones(self):
- for i in range(0, NUM_OF_CITIES):
- for j in range(i, NUM_OF_CITIES):
- ant.pheromones[i][j] = ant.pheromones[i][j]*(0.4)
- ant = AntWalk()
- x_vals = [i for i in range(0,4000)]
- y_vals = [0 for i in range(0,4000)]
- for k in range(0, 4000):
- print(k)
- for i in range(0, 5):
- ant.walk(66, 34)
- ant.update_pheromones()
- # if we did better than before, remember result
- y_vals[k] = ant.total_dist_traveled
- if (ant.total_dist_traveled < minimal_distance):
- minimal_distance = ant.total_dist_traveled
- minimal_path = ant.paths_traveled
- ant.reset()
- plt.scatter(x_vals,y_vals)
- plt.show()
- # reset demands,
- for i in range(0, NUM_OF_CITIES):
- if (ant.city_demand[i] > 0):
- plt.scatter(ant.points[i, 1], ant.points[i, 0])
- plt.annotate(ant.city_demand[i], (ant.points[i, 1], ant.points[i, 0]))
- print("!!!!!!!!!!!!!")
- print(minimal_distance)
- print(minimal_path)
- for i in range(0, NUM_OF_CITIES):
- for j in range(0, NUM_OF_CITIES):
- if (ant.pheromones[i][j] != 0.0):
- plt.plot(
- [ant.points[i][1], ant.points[j][1]],
- [ant.points[i][0], ant.points[j][0]],
- 'k-', color='r', linewidth=(50 * ant.pheromones[i][j]) / (sum(sum(ant.pheromones))))
- print(ant.pheromones[i][j])
- plt.ylim(48, 58)
- plt.xlim(14, 24)
- plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement