-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathant_algorith_demo.py
111 lines (92 loc) · 3.42 KB
/
ant_algorith_demo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import numpy as np
np.random.seed = 7
class Ant:
graph = []
EVA = 0.75
Q = 1000000 # for easy comprehension of possibilities
pheromone_random_range = 0.01, 0.1
ALPHA = 0.5
BETA = 1
def __init__(self, vertex, num_vertices):
self.graph_shape = num_vertices, num_vertices
self.graph_pheromones = np.random.random(size=self.graph_shape)
self.graph_pheromones = np.random.uniform(low=Ant.pheromone_random_range[0],
high=Ant.pheromone_random_range[0],
size=self.graph_shape)
self.vertex = vertex or 0
self.visited = np.zeros(num_vertices)
self.num_vertices = num_vertices
self.path = [vertex]
self.length = 0
self.visited[self.vertex] = 1
self.move()
def can_move(self):
return np.count_nonzero(self.visited) < len(self.visited)
def available_vertices(self):
available = []
for num, status in enumerate(self.visited):
if status == 0:
available.append(num)
return available
def move_on(self, vertices):
probabilities = [(vertex, self.p(vertex, vertices)) for vertex in vertices]
vertex, p = probabilities[0]
best_vertex = vertex
max_prob = p
for vertex, p in probabilities:
if max_prob < p:
best_vertex = vertex
max_prob = p
self.path.append(best_vertex)
self.length += Ant.graph[self.vertex][best_vertex]
self.visited[best_vertex] = 1
self.vertex = best_vertex
def move(self):
while self.can_move():
self.move_on(self.available_vertices())
else:
index = 1
while index < len(self.path):
tau0 = self.graph_pheromones[self.path[index - 1]][self.path[index]]
self.graph_pheromones[self.path[index - 1]][self.path[index]] = (1 - Ant.EVA) * tau0 + 1 / self.length
index += 1
self.back()
def p(self, vertex, vertices):
i = self.vertex
j = vertex
length = Ant.graph[i][j]
tau = self.graph_pheromones[i][j]
summary = 0
for vertex in vertices:
summary += Ant.graph[self.vertex][vertex] ** Ant.ALPHA / self.graph_pheromones[self.vertex][vertex] ** Ant.BETA
if length != 0:
return Ant.Q * (tau ** Ant.ALPHA) / (length ** Ant.BETA) / summary
else:
return 0
def back(self):
self.path.append(self.path[0])
self.length += Ant.graph[self.vertex][self.path[0]]
@staticmethod
def calculate_min_path(input_matrix):
"""
:param input_matrix: square matrix with lengths between vertices
:return: minimum length to move along all vertices
"""
for raw in input_matrix:
Ant.graph.append(raw)
size = len(Ant.graph[0])
ants = [Ant(i, size) for i in range(size)]
min_path = min(ant.length for ant in ants)
return min_path
if __name__ == '__main__':
row_number = 0
lines = []
while True:
line = input()
lines.append([int(i) for i in line.split()])
row_number += 1
number_of_vertices = len(lines[0])
if number_of_vertices == row_number:
break
min_path_length = Ant.calculate_min_path(lines)
print(min_path_length)