-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenetic.py
161 lines (124 loc) · 5.13 KB
/
genetic.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import random
import numpy as np
from generation import Generation
from chromosome import Chromosome
from cluster import Clustering
random.seed(1)
class Genetic:
def __init__(self, numberOfIndividual, Ps, Pm, Pc, budget, data, generationCount, kmax):
self.numberOfIndividual = numberOfIndividual
self.Ps = Ps
self.Pm = Pm
self.Pc = Pc
self.budget = budget
self.data = data
self.generationCount = generationCount
self.kmax = kmax
def geneticProcess(self, generation):
budget = self.budget
Ps = self.Ps
Pm = self.Pm
Pc = self.Pc
numOfInd = self.numberOfIndividual
print("------------Generation:",
self.generationCount, "-----------------")
generation.sortChromosomes()
# ------------------------simple ranking selection------------------------
generation = self.selection(generation)
# ------------------------------Crossover---------------------------------
generation = self.crossover(generation)
# ------------------------------Mutation---------------------------------
generation = self.mutation(generation)
self.generationCount += 1
return generation, self.generationCount
def selection(self, generation):
numOfInd = self.numberOfIndividual
Ps = self.Ps
# replace the worst Ps*numOfInd individual with the best Ps*numOfInd individual
for i in range(0, int(Ps * numOfInd)):
generation.chromosomes[numOfInd -
1 - i] = generation.chromosomes[i]
# sort chromosomes after ranking selection
generation.sortChromosomes()
return generation
def crossover(self, generation):
numOfInd = self.numberOfIndividual
Pc = self.Pc
index = random.sample(
range(0, numOfInd - 1), int(Pc * numOfInd))
for i in range(int(len(index) / 2),+2): # do how many time
generation = self.doCrossover(
generation, i, index)
generation.sortChromosomes()
return generation
def doCrossover(self, generation, i, index):
chromo = generation.chromosomes
length = chromo[0].length
cut = random.randint(1, length - 1)
parent1 = chromo[index[i]]
parent2 = chromo[index[i + 1]]
genesChild1 = parent1.genes[0:cut] + parent2.genes[cut:length]
genesChild2 = parent1.genes[cut:length] + parent2.genes[0:cut]
child1 = Chromosome(genesChild1, len(genesChild1))
child2 = Chromosome(genesChild2, len(genesChild2))
# ----clustering----
clustering = Clustering(generation, self.data, self.kmax)
child1 = clustering.calcChildFit(child1)
child2 = clustering.calcChildFit(child2)
# -------------------
listA = []
listA.append(parent1)
listA.append(parent2)
listA.append(child1)
listA.append(child2)
# sort parent and child by fitness / dec
listA = sorted(listA, reverse=True,
key=lambda elem: elem.fitness)
generation.chromosomes[index[i]] = listA[0]
generation.chromosomes[index[i + 1]] = listA[1]
return generation
def mutation(self, generation):
numOfInd = self.numberOfIndividual
fitnessList = []
generationAfterM = Generation(numOfInd, generation.generationCount)
flagMutation = (np.zeros(numOfInd)).tolist()
for i in range(numOfInd):
temp = generation.chromosomes[i]
fitnessList.append(temp.fitness)
for i in range(numOfInd):
if i == 0: # Ibest doesn't need mutation
generationAfterM.chromosomes.append(generation.chromosomes[0])
flagMutation[0] = 0
else:
generationAfterM = self.doMutation(
generation.chromosomes[i], generationAfterM, flagMutation, fitnessList, i)
generationAfterM.sortChromosomes()
return generationAfterM
def doMutation(self, chromosomeBeforeM, generationAfterM, flagMutation, fitnessList, i):
Pm = self.Pm
dice = []
length = len(chromosomeBeforeM.genes)
chromosome = Chromosome([], length)
geneFlag = []
for j in range(length):
dice.append(float('%.2f' % random.uniform(0.0, 1.0)))
if dice[j] > Pm:
chromosome.genes.append(chromosomeBeforeM.genes[j])
geneFlag.append(0)
if dice[j] <= Pm:
chromosome.genes.append(
float('%.2f' % random.uniform(0.0, 1.0)))
geneFlag.append(1)
check = sum(geneFlag)
if check == 0:
flagMutation[i] = 0
chromosome.fitness = fitnessList[i]
else:
flagMutation[i] = 1
#---clustering----
clustering = Clustering(chromosomeBeforeM, self.data, self.kmax)
chromosome = clustering.calcChildFit(
chromosome)
#------------------
generationAfterM.chromosomes.append(chromosome)
return generationAfterM