-
Notifications
You must be signed in to change notification settings - Fork 0
/
GeneticAlgorithm.py
73 lines (61 loc) · 2.6 KB
/
GeneticAlgorithm.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
import random, heapq
class GeneticAlgorithm:
def __init__(self, init_state, n):
self.n = n
self.init_state = init_state
self.generation = 0
def initialize_population(self, n):
pop_list = []
num = random.randint(2, n)
while num != 0:
temp = [random.randint(0, self.n - 1) for _ in range(self.n)]
heapq.heappush(pop_list, (self.fitness(temp), temp))
num -= 1
return pop_list
def fitness(self, cur_state):
collisions = 0
for i in range(len(cur_state)):
for j in range(i + 1, len(cur_state)):
if cur_state[i] == cur_state[j] or abs(cur_state[i] - cur_state[j]) == j - i:
collisions += 1
return collisions
def goal_test(self, population: list):
for i in population:
if self.fitness(i[1]) == 0:
return i[1]
return None
def random_pick(self, population):
new_population = []
n = random.randint(2, len(population))
for i in range(n):
new_population.append(population[i][1])
return new_population
def crossover(self, parent1, parent2):
p_len = len(parent1)
cross_point = random.randint(0, p_len - 1)
return parent1[:cross_point] + parent2[cross_point:p_len], parent2[:cross_point] + parent1[cross_point:p_len]
def mutate(self, state):
state_len = len(state)
mutate_point = random.randint(0, state_len - 1)
mutation = random.randint(0, state_len - 1)
state[mutate_point] = mutation
return state
def solve(self):
population = self.initialize_population(self.n)
heapq.heappush(population, (self.fitness(self.init_state), self.init_state))
result = self.goal_test(population)
while result == None:
random_pop = self.random_pick(population)
for i in range(0, len(random_pop), 2):
if i + 2 <= len(random_pop):
#Crossover
random_pop[i], random_pop[i + 1] = self.crossover(random_pop[i], random_pop[i + 1])
#mutate
random_pop[i] = self.mutate(random_pop[i])
random_pop[i + 1] = self.mutate(random_pop[i + 1])
for board in random_pop:
population.pop()
for board in random_pop:
heapq.heappush(population, (self.fitness(board), board))
result = self.goal_test(population)
return result