-
Notifications
You must be signed in to change notification settings - Fork 0
/
advanced.py
117 lines (94 loc) · 3.06 KB
/
advanced.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
112
113
114
115
116
117
import random
import numpy as np
import matplotlib.pyplot as plt
LOW = -1
HIGH = 2
MUTATION_P = 0.5
POPSIZE = 30
def genotypeToFenotype(element):
f = 0
for i, j in zip(element, range(11, -1, -1)):
f += i * 2 ** j
return (f / 2 ** 12) * (HIGH - LOW) + LOW
def getFitness(x):
return x * np.sin(10 * np.pi * x) + 2
def represent():
population = np.random.randint(0, 2, (POPSIZE, 12))
fenotype = np.empty(POPSIZE, np.float64)
for i in range(POPSIZE):
fenotype[i] = genotypeToFenotype(population[i])
fitness = getFitness(fenotype)
p = fitness / fitness.sum()
return population, fenotype, p
def crossover(population: list):
out = []
while len(population) > 0:
a1 = random.choice(population)
population.remove(a1)
a2 = random.choice(population)
population.remove(a2)
border = random.randint(0, 11)
a3 = np.concatenate((a1[:border], a2[border:])).tolist()
a4 = np.concatenate((a2[:border], a1[border:])).tolist()
points = [a1, a2, a3, a4]
fenotype = np.empty(4, np.float64)
for i in range(4):
fenotype[i] = genotypeToFenotype(points[i])
fitness = getFitness(fenotype).tolist()
i = fitness.index(max(fitness))
out.append(points[i])
fitness.remove(fitness[i])
points.remove(points[i])
i = fitness.index(max(fitness))
out.append(points[i])
return np.array(out)
def mutation(population):
for e in population:
r = np.random.random()
if r <= MUTATION_P:
b = random.randint(0, 11)
e[b] = not e[b]
population, fenotype, p = represent()
solutions = [] # it will contain (fitness,fenotype)
search_num = 5
z = 0
while search_num > 0:
# select
z += 1
new_population = []
for _ in range(POPSIZE):
r = np.random.random()
s = 0
for i in range(len(p)):
s += p[i]
if r < s:
new_population.append(population[i].tolist())
break
# cross over
population = crossover(new_population)
# mutation
mutation(population)
# update fenotype and p
for i in range(len(population)):
fenotype[i] = genotypeToFenotype(population[i])
fitness = getFitness(fenotype)
p = fitness / fitness.sum()
if len(solutions) > 0:
if max(fitness) > solutions[-1][0]:
inds = fitness.tolist().index(max(fitness))
solutions.append((max(fitness), fenotype[inds]))
search_num = 5
elif max(fitness) < solutions[-1][0]:
search_num -= 1
else:
inds = fitness.tolist().index(max(fitness))
solutions.append((max(fitness), fenotype[inds]))
x = np.arange(-1, 2, 0.01)
graph_y = x * np.sin(10 * np.pi * x) + 2
point_y = np.full_like(x, None)
point_y[int((solutions[-1][1] + 1) // 0.01)] = solutions[-1][0]
plt.plot(x, graph_y)
plt.plot(x, point_y, marker='o')
plt.show()
print(f"maximum value finded is :\n x = {solutions[-1][1]}\n y = {solutions[-1][0]}")
print(f"number of main loop run : {z}")