Commit 3c8fa9face184f2f427954397f8e3294589ae81b

Authored by Olav Kjartan Larseng
1 parent cf1a093c

mutation and fitness added, however fitness not fully implemented

Showing 1 changed file with 175 additions and 17 deletions   Show diff stats
... ... @@ -6,28 +6,159 @@ Created on Mon May 7 12:46:27 2018
6 6 """
7 7 import numpy as np
8 8 from math import floor, ceil
  9 +import random
  10 +#pip install bitstring in anaconda prompt, remember to update pip: pip install --upgrade pip
  11 +from bitstring import BitArray
9 12  
10   -def crossover(population):
  13 +def fitnessCheckBounds(fitness, corners):
  14 + reward = 10
  15 + rewardAll = 100
  16 + allCornersInBound = True
  17 +
  18 + #print(corners)
  19 + for corner in range(len(corners)):
  20 + if corner >= 7:
  21 + break
  22 +
  23 + if corners[corner] >= xTo:
  24 + fitness += reward
  25 + else:
  26 + allCornersInBound = False
  27 +
  28 + if corners[corner+1] >= yHeight:
  29 + fitness += reward
  30 + else:
  31 + allCornersInBound = False
  32 +
  33 +
  34 + if allCornersInBound:
  35 + fitness += rewardAll
  36 + else:
  37 + fitness -= ceil(rewardAll/2)
  38 +
  39 + return fitness
  40 +
  41 +def fitnessCheckLeastEnergyJump(fitness, corners):
  42 + reward = 10
  43 + heights = np.array([corners[1], corners[3], corners[5], corners[7]])
  44 +
  45 + avgHeights = np.average(heights)
  46 + avgHeights = avgHeights - yHeight
  47 +
  48 + fitness += (1/avgHeights) * reward
  49 +
  50 + return fitness
  51 +
  52 +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 +
  87 + return fitness
  88 +
  89 +def fitnessValue(chromosome):
  90 + fitness = 0
  91 +
  92 + x1 = float(BitArray(bin=''.join(map(str, chromosome[0:chromosomeBitsValue]))).uint)
  93 + y1 = float(BitArray(bin=''.join(map(str, chromosome[chromosomeBitsValue:chromosomeBitsValue*2]))).uint)
  94 +
  95 + x2 = float(BitArray(bin=''.join(map(str, chromosome[chromosomeBitsValue*2:chromosomeBitsValue*3]))).uint)
  96 + y2 = float(BitArray(bin=''.join(map(str, chromosome[chromosomeBitsValue*3:chromosomeBitsValue*4]))).uint)
  97 +
  98 + x3 = float(BitArray(bin=''.join(map(str, chromosome[chromosomeBitsValue*4:chromosomeBitsValue*5]))).uint)
  99 + y3 = float(BitArray(bin=''.join(map(str, chromosome[chromosomeBitsValue*5:chromosomeBitsValue*6]))).uint)
  100 +
  101 + x4 = float(BitArray(bin=''.join(map(str, chromosome[chromosomeBitsValue*6:chromosomeBitsValue*7]))).uint)
  102 + y4 = float(BitArray(bin=''.join(map(str, chromosome[chromosomeBitsValue*7:chromosomeBitsValue*8]))).uint)
  103 +
  104 +
  105 + dx1 = x1 + upperLCorner[0]
  106 + dy1 = y1 + upperLCorner[1]
  107 +
  108 + dx2 = x2 + upperRCorner[0]
  109 + dy2 = y2 + upperRCorner[1]
  110 +
  111 + dx3 = x3 + lowerLCorner[0]
  112 + dy3 = y3 + lowerLCorner[1]
  113 +
  114 + dx4 = x4 + lowerRCorner[0]
  115 + dy4 = y4 + lowerRCorner[1]
  116 +
  117 + corners = np.array([dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4])
  118 +
  119 + fitness = fitnessCheckBounds(fitness, corners)
  120 + fitness = fitnessCheckLeastEnergyJump(fitness, corners)
  121 + fitness = fitnessCheckQuadrant(fitness, corners)
  122 +
  123 +
  124 + return fitness
  125 +
  126 +def fitness(population):
  127 + l = list(population)
  128 + l.sort(key=lambda chromosome: fitnessValue(chromosome), reverse=True)
  129 + population = np.array(l)
  130 +
  131 + return population
  132 +
  133 +def mutation(population):
  134 + for i in range(len(population)):
  135 + for j in range(len(population[i])):
  136 + if random.uniform(0.0, 1.0) <= mutationRatio:
  137 + if population[i][j] != 0:
  138 + population[i][j] = 0
  139 + else:
  140 + population[i][j] = 1
  141 +
  142 + return population
11 143  
12   - print("Before: \n" + str(population))
  144 +def crossover(population):
  145 + #print("Before: \n" + str(population))
13 146 offspring = np.array
14 147 splitSize = 2
15   - #splitSize -= 1
16 148 for i in range(populationProduction):
17 149 if i >= populationSize-1:
18 150 break
19 151  
20   -
21 152 parent1 = population[i]
22 153 parent2 = population[i+1]
23 154 #print('paren1' + str(parent1))
24 155 #print('paren2' + str(parent2))
25 156  
26   - count = 0
27   - itr = 0
28 157 child1 = np.array([], dtype=int)
29 158 child2 = np.array([], dtype=int)
30 159  
  160 + itr = 0
  161 + count = 0
31 162 while (count < chromosomeSize):
32 163 if itr%2 != 0:
33 164 child1 = np.concatenate((
... ... @@ -64,32 +195,45 @@ def crossover(population):
64 195 offspring = np.vstack([offspring, child1, child2])
65 196  
66 197 #Remove
67   - population = np.delete(population, np.s_[0:len(offspring)], axis = 0)
  198 + population = np.delete(population, np.s_[len(population)-len(offspring):len(population)], axis = 0)
68 199  
69 200 #Insert
70   - population = np.vstack([population, offspring])
71   -
72   - print("After: \n" + str(population))
  201 + population = np.vstack([offspring, population])
  202 +
  203 + #print("After: \n" + str(population))
73 204 return population
74 205  
75 206  
76 207  
77   -xStart = 3.0
78 208 yHeight = 4.0
79   -chromosomeHeight = 0.2
  209 +xStart = 3.0
  210 +xTo = 0.0
  211 +agentHeight = 0.2
  212 +upperLCorner = np.array([xStart-(agentHeight/2), agentHeight])
  213 +upperRCorner = np.array([xStart+(agentHeight/2), agentHeight])
  214 +lowerLCorner = np.array([xStart-(agentHeight/2), 0.0])
  215 +lowerRCorner = np.array([xStart+(agentHeight/2), 0.0])
  216 +
80 217  
81   -populationSize = 12
82   -populationProduce = 0.3
  218 +
  219 +populationSize = 20
  220 +#percentage of parents which will produce two childrens
  221 +populationProduce = 0.2
83 222 populationProduction = floor(ceil(populationSize * populationProduce)/2)
  223 +
  224 +mutationRatio = 0.05
84 225 print('populationProduction ' + str(populationProduction))
  226 +print('mutationRatio ' + str(mutationRatio))
  227 +
85 228 generationSize = 1000
  229 +highestFitness = 0
86 230  
87 231  
88 232 # A value eg. x coordinate for a corner on a rectangle represents 4 bit value
89 233 chromosomeBitsValue = 4
90 234 # A rectangle has 4 points x,y where one point x is equal to 4 binaries.
91 235 # eg. 15 decimal is the highest point
92   -# Times two since a corner has two values
  236 +# Times two since a corner has two values and times 4 since a rect has 4 corners
93 237 chromosomeSize = chromosomeBitsValue*2*4
94 238  
95 239 #sorting for later
... ... @@ -99,11 +243,25 @@ chromosomeSize = chromosomeBitsValue*2*4
99 243  
100 244 population = np.random.randint(2, size=(populationSize, chromosomeSize))
101 245  
  246 +threshold = False
102 247 for generation in range(generationSize):
103 248  
104 249 print ('Generation: ' + str(generation))
105   - crossover(population)
106   - break
  250 + population = crossover(population)
  251 + population = mutation(population)
  252 + population = fitness(population)
  253 + for c in population:
  254 + fit = int(fitnessValue(c))
  255 + print(fit)
  256 + if fit >= 260:
  257 + threshold = True
  258 +
  259 + if threshold:
  260 + break
  261 +
  262 +
  263 +
  264 +print(population)
107 265  
108 266 #Fi = qi /Sum(qj)
109 267  
... ...