-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTSP_GA.py
100 lines (72 loc) · 2.24 KB
/
TSP_GA.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
distances = {}
num_cities = 5
pop_size = 500
population = []
fitness = []
curr_best_dist = 0
best_order = []
curr_best_order = []
import random
order = list(range(num_cities))
for i in range(pop_size):
population[i] = random.sample(order, len(order))
def calc_distance(order):
pass
def calc_fitness(population, fitness):
curr_rec = 10e6
for i in range(len(population)):
d = calc_distance(population[i])
if d < curr_best_dist:
curr_best_dist=d
best_order=population[i]
if d < curr_rec:
curr_rec=d
curr_best_order=population[i]
fitness[i]=1/(pow(d,8)+1)
return fitness
def normalize_fitness(fitness):
res = sum(fitness)
return [x/res for x in fitness]
import random, copy
def pick_one(population, fitness):
index = 0
r = random.random()
while r:
r = r - fitness[index]
index += 1
index -= 1
return copy.copy(population[index])
def crossover(order_a, order_b):
st = random.randint(0,len(order_a)-1)
en = random.randint(st+1, len(order_a)-1)
new_order = order_a[st:en]
for i in range(len(order_b)):
city = order_b[i]
if city not in new_order:
new_order.append(city)
return new_order
def mutate(order, mutation_rate):
total_cities = len(order)
for i in range(total_cities):
if random.random() < mutation_rate:
index_a = random.randint(0, len(order)-1)
index_b = (index_a+1)%total_cities
order[index_a],order[index_b]=order[index_b],order[index_a]
def next_generation(population, fitness):
new_population = []
for i in range(len(population)):
order_a = pick_one(population, fitness)
order_b = pick_one(population, fitness)
order = crossover(order_a, order_b)
mutate(order, 0.01)
new_population[i]=order
population=new_population
return population
num_generation = 1000
curr_generation = 1
while curr_generation < num_generation:
curr_generation += 1
calc_fitness(population, fitness)
normalize_fitness(fitness)
next_generation(population, fitness)
#results