Commit 8eca4f08d57da4a4bb88c151bcd3a0161e014d75

Authored by Olav Kjartan Larseng
1 parent 3c8fa9fa

redesign with class chromosome

__pycache__/chromsome.cpython-36.pyc 0 → 100644
No preview for this file type
chromsome.py 0 → 100644
  1 +# -*- coding: utf-8 -*-
  2 +"""
  3 +Created on Thu May 10 16:49:45 2018
  4 +
  5 +@author: Olav
  6 +"""
  7 +import numpy as np
  8 +
  9 +class Chromosome:
  10 + fitness = 0
  11 + gene = np.array
  12 +
  13 + def __init__(self, _gene):
  14 + self.gene = _gene
  15 +
  16 + def __repr__(self):
  17 + return 'Gene: ' + str(self.gene) + ' Fitness: ' + str(self.fitness)
  18 +
  19 + def geneAt(self, index):
  20 + return self.gene[index]
  21 +
  22 + def geneSet(self, index, value):
  23 + self.gene[index] = value
@@ -5,8 +5,9 @@ Created on Mon May 7 12:46:27 2018 @@ -5,8 +5,9 @@ Created on Mon May 7 12:46:27 2018
5 @author: Olav 5 @author: Olav
6 """ 6 """
7 import numpy as np 7 import numpy as np
8 -from math import floor, ceil 8 +from math import floor, ceil, sqrt
9 import random 9 import random
  10 +from chromsome import Chromosome
10 #pip install bitstring in anaconda prompt, remember to update pip: pip install --upgrade pip 11 #pip install bitstring in anaconda prompt, remember to update pip: pip install --upgrade pip
11 from bitstring import BitArray 12 from bitstring import BitArray
12 13
@@ -26,7 +27,7 @@ def fitnessCheckBounds(fitness, corners): @@ -26,7 +27,7 @@ def fitnessCheckBounds(fitness, corners):
26 allCornersInBound = False 27 allCornersInBound = False
27 28
28 if corners[corner+1] >= yHeight: 29 if corners[corner+1] >= yHeight:
29 - fitness += reward 30 + fitness += reward*2
30 else: 31 else:
31 allCornersInBound = False 32 allCornersInBound = False
32 33
@@ -50,43 +51,53 @@ def fitnessCheckLeastEnergyJump(fitness, corners): @@ -50,43 +51,53 @@ def fitnessCheckLeastEnergyJump(fitness, corners):
50 return fitness 51 return fitness
51 52
52 def fitnessCheckQuadrant(fitness, corners): 53 def fitnessCheckQuadrant(fitness, corners):
53 - #reward = 300  
54 - rewardOne = 10  
55 - rewardTwo = -20  
56 - #isAQuadrant = True  
57 -  
58 - cornerDx1 = corners[0] - corners[2]  
59 - cornerDy1 = corners[1] - corners[3]  
60 -  
61 - cornerDx2 = corners[2] - corners[4]  
62 - cornerDy2 = corners[3] - corners[5]  
63 -  
64 - cornerDx3 = corners[4] - corners[6]  
65 - cornerDy3 = corners[5] - corners[7]  
66 -  
67 - if cornerDx1 == cornerDx2:  
68 - fitness += rewardOne  
69 - else:  
70 - fitness += rewardTwo  
71 -  
72 - if cornerDy1 == cornerDy2:  
73 - fitness += rewardOne  
74 - else:  
75 - fitness += rewardTwo  
76 -  
77 - if cornerDx2 == cornerDx3:  
78 - fitness += rewardOne  
79 - else:  
80 - fitness += rewardTwo  
81 -  
82 - if cornerDy2 == cornerDy3:  
83 - fitness += rewardOne  
84 - else:  
85 - fitness += rewardTwo  
86 - 54 + reward = 100
  55 +
  56 + #Check length of all corners
  57 + sideLen1 = getSideLength(corners[0], corners[1], corners[2], corners[3])
  58 + sideLen2 = getSideLength(corners[2], corners[3], corners[4], corners[5])
  59 + sideLen3 = getSideLength(corners[4], corners[5], corners[6], corners[7])
  60 + sideLen4 = getSideLength(corners[6], corners[7], corners[0], corners[1])
  61 + allSides = np.array([sideLen1, sideLen2, sideLen3, sideLen4])
  62 +
  63 + #How far away is the sides from chromosome original height
  64 + for i in range(0, 4):
  65 + diff = getDifferenceSide(sideLen1, agentHeight)
  66 + diff = round(diff, 1)
  67 + if diff == 0.0:
  68 + diff = 0.1
  69 + fitness += int((1/diff) * reward)
  70 +
  71 + #Are the sides of same length?
  72 + allSidesEqual = True
  73 + for i in range(0, 4):
  74 + if i != 3:
  75 + diff = round(getDifferenceSide(allSides[i], allSides[i+1]), 1)
  76 + else:
  77 + diff = round(getDifferenceSide(allSides[i], allSides[0]), 1)
  78 +
  79 + if diff == 0.0:
  80 + diff = 0.1
  81 + else:
  82 + allSidesEqual = False
  83 +
  84 + fitness += (1/diff) * reward
  85 +
  86 + if allSidesEqual:
  87 + fitness += reward * 1000
  88 +
87 return fitness 89 return fitness
88 90
  91 +def getSideLength(x1, y1, x2, y2):
  92 + return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2))
  93 +
  94 +def getDifferenceSide(side1, side2):
  95 + return abs(side1 - side2)
  96 +
89 def fitnessValue(chromosome): 97 def fitnessValue(chromosome):
  98 + chromosomeAgent = chromosome[0]
  99 + chromosome = chromosomeAgent.gene
  100 +
90 fitness = 0 101 fitness = 0
91 102
92 x1 = float(BitArray(bin=''.join(map(str, chromosome[0:chromosomeBitsValue]))).uint) 103 x1 = float(BitArray(bin=''.join(map(str, chromosome[0:chromosomeBitsValue]))).uint)
@@ -120,7 +131,8 @@ def fitnessValue(chromosome): @@ -120,7 +131,8 @@ def fitnessValue(chromosome):
120 fitness = fitnessCheckLeastEnergyJump(fitness, corners) 131 fitness = fitnessCheckLeastEnergyJump(fitness, corners)
121 fitness = fitnessCheckQuadrant(fitness, corners) 132 fitness = fitnessCheckQuadrant(fitness, corners)
122 133
123 - 134 + fitness = int(fitness)
  135 + chromosomeAgent.fitness = fitness
124 return fitness 136 return fitness
125 137
126 def fitness(population): 138 def fitness(population):
@@ -131,6 +143,7 @@ def fitness(population): @@ -131,6 +143,7 @@ def fitness(population):
131 return population 143 return population
132 144
133 def mutation(population): 145 def mutation(population):
  146 + """
134 for i in range(len(population)): 147 for i in range(len(population)):
135 for j in range(len(population[i])): 148 for j in range(len(population[i])):
136 if random.uniform(0.0, 1.0) <= mutationRatio: 149 if random.uniform(0.0, 1.0) <= mutationRatio:
@@ -138,6 +151,23 @@ def mutation(population): @@ -138,6 +151,23 @@ def mutation(population):
138 population[i][j] = 0 151 population[i][j] = 0
139 else: 152 else:
140 population[i][j] = 1 153 population[i][j] = 1
  154 + """
  155 + chromosomePick = np.random.randint(len(population))
  156 + for j in range(populationSize):
  157 + if random.uniform(0.0, 1.0) <= mutationRatio:
  158 + chromosome = population[chromosomePick][0]
  159 + chromosomeBit = chromosome.geneAt(j)
  160 +
  161 + if chromosomeBit != 0:
  162 + chromosome.geneSet(j, 0)
  163 + else:
  164 + chromosome.geneSet(j, 1)
  165 +
  166 +
  167 + return population
  168 +
  169 +def roulette(population):
  170 + populationSize = len(population)
141 171
142 return population 172 return population
143 173
@@ -149,8 +179,9 @@ def crossover(population): @@ -149,8 +179,9 @@ def crossover(population):
149 if i >= populationSize-1: 179 if i >= populationSize-1:
150 break 180 break
151 181
152 - parent1 = population[i]  
153 - parent2 = population[i+1] 182 + parent1 = population.item(i).gene
  183 + parent2 = population.item(i+1).gene
  184 +
154 #print('paren1' + str(parent1)) 185 #print('paren1' + str(parent1))
155 #print('paren2' + str(parent2)) 186 #print('paren2' + str(parent2))
156 187
@@ -183,19 +214,19 @@ def crossover(population): @@ -183,19 +214,19 @@ def crossover(population):
183 parent2[count:count+4], #p1 take the whole x/y 214 parent2[count:count+4], #p1 take the whole x/y
184 ), axis=0) 215 ), axis=0)
185 216
186 - count += 4 217 + count += chromosomeBitsValue
187 itr += 1 218 itr += 1
188 219
189 220
190 #print('child1' + str(child1)) 221 #print('child1' + str(child1))
191 #print('child2' + str(child2)) 222 #print('child2' + str(child2))
192 if i == 0: 223 if i == 0:
193 - offspring = np.vstack([child1, child2]) 224 + offspring = np.vstack([Chromosome(child1), Chromosome(child2)])
194 else: 225 else:
195 - offspring = np.vstack([offspring, child1, child2]) 226 + offspring = np.vstack([offspring, Chromosome(child1), Chromosome(child2)])
196 227
197 #Remove 228 #Remove
198 - population = np.delete(population, np.s_[len(population)-len(offspring):len(population)], axis = 0) 229 + #population = np.delete(population, np.s_[len(population)-len(offspring):len(population)], axis = 0)
199 230
200 #Insert 231 #Insert
201 population = np.vstack([offspring, population]) 232 population = np.vstack([offspring, population])
@@ -205,6 +236,7 @@ def crossover(population): @@ -205,6 +236,7 @@ def crossover(population):
205 236
206 237
207 238
  239 +# Init agent values
208 yHeight = 4.0 240 yHeight = 4.0
209 xStart = 3.0 241 xStart = 3.0
210 xTo = 0.0 242 xTo = 0.0
@@ -215,46 +247,69 @@ lowerLCorner = np.array([xStart-(agentHeight/2), 0.0]) @@ -215,46 +247,69 @@ lowerLCorner = np.array([xStart-(agentHeight/2), 0.0])
215 lowerRCorner = np.array([xStart+(agentHeight/2), 0.0]) 247 lowerRCorner = np.array([xStart+(agentHeight/2), 0.0])
216 248
217 249
  250 +# Size of population
  251 +populationSize = 12
218 252
219 -populationSize = 20  
220 -#percentage of parents which will produce two childrens  
221 -populationProduce = 0.2  
222 -populationProduction = floor(ceil(populationSize * populationProduce)/2) 253 +# percentage of parents which will produce two childrens
  254 +populationProduce = 0.5
223 255
224 -mutationRatio = 0.05 256 +# WARNING: OLD below, not that relevant
  257 +# Population production will determine how many chromosomes will be able to mate.
  258 +# The chromosomes are "cheating" on eachother so that we pick chromosome 0 - 1 to mate
  259 +# then 1 - 2, 2 - 3 and so on. Hence 100% populationProduce (see above) will yield a
  260 +# populationProduction of 12 chromosomes, although it says 6. Check crossover function.
  261 +populationProduction = floor(ceil(populationSize * populationProduce)/2)
225 print('populationProduction ' + str(populationProduction)) 262 print('populationProduction ' + str(populationProduction))
226 -print('mutationRatio ' + str(mutationRatio))  
227 263
228 -generationSize = 1000  
229 -highestFitness = 0 264 +# How often a bit will flip during a mutation
  265 +mutationRatio = 0.3
  266 +print('mutationRatio ' + str(mutationRatio))
230 267
  268 +# How many interation of generations
  269 +generationSize = 100
231 270
232 # A value eg. x coordinate for a corner on a rectangle represents 4 bit value 271 # A value eg. x coordinate for a corner on a rectangle represents 4 bit value
233 chromosomeBitsValue = 4 272 chromosomeBitsValue = 4
  273 +
234 # A rectangle has 4 points x,y where one point x is equal to 4 binaries. 274 # A rectangle has 4 points x,y where one point x is equal to 4 binaries.
235 # eg. 15 decimal is the highest point 275 # eg. 15 decimal is the highest point
236 # Times two since a corner has two values and times 4 since a rect has 4 corners 276 # Times two since a corner has two values and times 4 since a rect has 4 corners
237 chromosomeSize = chromosomeBitsValue*2*4 277 chromosomeSize = chromosomeBitsValue*2*4
238 278
239 -#sorting for later  
240 -#self._stack.sort(key=lambda x: self.fv(x)) 279 +# Init random population
  280 +#population = np.random.randint(2, size=(populationSize, chromosomeSize))
  281 +for i in range(populationSize):
  282 + chromosomeGene = np.random.randint(2, size=(chromosomeSize))
  283 + if i == 0:
  284 + population = np.array(Chromosome(chromosomeGene))
  285 + else:
  286 + population = np.vstack([population, Chromosome(chromosomeGene)])
241 287
242 -#initialize random population  
243 288
244 -population = np.random.randint(2, size=(populationSize, chromosomeSize)) 289 +# How many cycles until a mutation
  290 +mutationCycle = 2
245 291
246 threshold = False 292 threshold = False
247 for generation in range(generationSize): 293 for generation in range(generationSize):
248 294
249 print ('Generation: ' + str(generation)) 295 print ('Generation: ' + str(generation))
250 - population = crossover(population)  
251 - population = mutation(population)  
252 - population = fitness(population) 296 + #population = roulette(population) #roulette wheel
  297 + population = crossover(population) #crossing
  298 + if generation % mutationCycle == 0:
  299 + population = mutation(population)
  300 +
  301 + population = fitness(population) #sort by fitness
  302 +
  303 + #test numb
  304 + numb = 0
253 for c in population: 305 for c in population:
254 - fit = int(fitnessValue(c))  
255 - print(fit)  
256 - if fit >= 260:  
257 - threshold = True 306 + numb += 1
  307 + print(c[0].fitness)
  308 + if numb == populationSize:
  309 + break
  310 +
  311 + #if fit >= 260:
  312 + # threshold = True
258 313
259 if threshold: 314 if threshold:
260 break 315 break
@@ -262,7 +317,3 @@ for generation in range(generationSize): @@ -262,7 +317,3 @@ for generation in range(generationSize):
262 317
263 318
264 print(population) 319 print(population)
265 -  
266 -#Fi = qi /Sum(qj)  
267 -  
268 -