def roulette_selection(self): genTotal = 0.0 sumProp = 0.0 popSize = len(self.population) for i in range(popSize): worst = self.population[self.get_maximum()] thisChromo = self.population[i] #zählt quasi die Fitness aller Chromosomen zusammen (abgezogen von Indivuduum mit höchstem Konfliktwert) genTotal += (Chromosome.get_fitness(worst) - Chromosome.get_fitness(thisChromo)) sys.stdout.write(str(genTotal) + " GenTotal(Roulette)\n") sys.stdout.write(str(popSize) + " popSize\n") for i in range(popSize): worst = self.population[self.get_maximum()] thisChromo = self.population[i] if genTotal != 0: probability = ((Chromosome.get_fitness(worst) - Chromosome.get_fitness(thisChromo)) / genTotal) else: probability = 0 sumProp += probability Chromosome.set_selection_probability(thisChromo, probability) sys.stdout.write(str(round(sumProp, 3)) + " alle Props\n") for i in range(self.mOffspringPerGeneration): rouletteSpin = random.uniform(0, 1) j = 0 selTotal = 0 done = False while not done: thisChromo = self.population[j] selTotal += Chromosome.get_selection_probability(thisChromo) if selTotal >= rouletteSpin: if j == 0: thatChromo = self.population[j] elif j >= popSize - 1: thatChromo = self.population[popSize - 1] else: thatChromo = self.population[j - 1] Chromosome.set_selected(thatChromo, True) done = True else: j += 1 #wenn nur noch Individuen mit 0 Konflikten vorhanden sind, immer die Chromosomen mit jeweiliger zahl #der anzahl an Nachwüchsen selected if sumProp == 0: Chromosome.set_selected(self.population[i], True) done = True return
def do_mating(self, recomb): for i in range(self.mOffspringPerGeneration): chromA = self.population[0] chromB = self.population[1] newChromo1 = Chromosome(self.mMaxLength, 0) newChromo2 = Chromosome(self.mMaxLength, 0) self.population.append(newChromo1) newIndex1 = len(self.population) - 1 self.population.append(newChromo2) newIndex2 = len(self.population) - 1 sys.stdout.write("Parent1 mit ") sys.stdout.write(str(chromA.get_fitness()) + " Konflikten: ") chromA.toStr() + "\n" sys.stdout.write("Parent2 mit ") sys.stdout.write(str(chromB.get_fitness()) + " Konflikten: ") chromB.toStr() + "\n" #TODO diese Zeile ändern, je nach gewünschter Rekombination Operations.position_based_crossover(self, chromA, chromB, newIndex1, newIndex2) newChromo1 = self.population[newIndex1] # Konsole: sys.stdout.write("Kind1 mit ") sys.stdout.write(str(newChromo1.get_fitness()) + " Konflikten: ") newChromo1.toStr() + "\n" newChromo2 = self.population[newIndex2] # Konsole: sys.stdout.write("Kind2 mit ") sys.stdout.write(str(newChromo2.get_fitness()) + " Konflikten: ") newChromo2.toStr() + "\n" self.childCount += 2 sys.stdout.write( str(len(self.population)) + " Länge der Population\n") self.set_conflict_array(chromA.get_fitness(), chromB.get_fitness(), newChromo1.get_fitness(), newChromo2.get_fitness()) # plot für jeden einzelnen Druchgang #self.show_conflicts(chromA, chromB, newChromo1, newChromo2) return
def get_fitness(self): #fitness entspricht den Konflikten. Niedrige Fitness ist gut, hohe ist schlecht popSize = len(self.population) for i in range(popSize): thisChromo = self.population[i] worst = self.population[self.get_maximum()] self.worst = Chromosome.get_fitness(worst) best = self.population[self.get_minimum()] self.best = Chromosome.get_fitness(best) #sys.stdout.write("\n"+str(Chromosome.get_fitness(worst)) + ": Maximale Fitness\n") #sys.stdout.write(str(Chromosome.get_fitness(best)) + ": Minimale Fitness\n") self.current_best_fitness = Chromosome.get_fitness(best) self.array_fitness.append(self.current_best_fitness) return
def do_mating(self, recomb): for i in range(self.mOffspringPerGeneration): chromA = self.population[0] chromB = self.population[1] #crossovertyp ist hier egal newChromo1 = ChromosomeDEAP(self.mMaxLength, 2) newChromo2 = ChromosomeDEAP(self.mMaxLength, 2) self.population.append(newChromo1) newIndex1 = len(self.population) - 1 self.population.append(newChromo2) newIndex2 = len(self.population) - 1 sys.stdout.write("Parent1 mit Fitness ") sys.stdout.write(str(Chromosome.get_fitness(chromA)) + " : ") Chromosome.toStr(chromA) + "\n" sys.stdout.write("Parent2 mit Fitness ") sys.stdout.write(str(Chromosome.get_fitness(chromB)) + " : ") Chromosome.toStr(chromB) + "\n" #TODO NQueen.(gewünschte rekombination), bei bad-recombination NDEAP.bad_recombination Operations.partially_mapped_crossover(self, chromA, chromB, newIndex1, newIndex2) newChromo1 = self.population[newIndex1] # Konsole: sys.stdout.write("Kind1 mit Fitness ") sys.stdout.write(str(Chromosome.get_fitness(newChromo1)) + " : ") Chromosome.toStr(newChromo1) + "\n" newChromo2 = self.population[newIndex2] # Konsole: sys.stdout.write("Kind2 mit Fitness ") sys.stdout.write(str(Chromosome.get_fitness(newChromo2)) + " : ") Chromosome.toStr(newChromo2) + "\n" self.childCount += 2 sys.stdout.write( str(len(self.population)) + " Länge der Population\n") SingleRekomb.set_conflict_array(self, Chromosome.get_fitness(chromA), Chromosome.get_fitness(chromB), Chromosome.get_fitness(newChromo1), Chromosome.get_fitness(newChromo2)) # plot für jeden einzelnen Druchgang #self.show_conflicts(chromA, chromB, newChromo1, newChromo2) return
def get_minimum(self): # Returns an array index. minimum = 0 done = False while not done: foundNewMinimum = False popSize = len(self.population) for i in range(popSize): if i != minimum: thisChromo = self.population[i] thatChromo = self.population[minimum] # Der Fitness-Betrag wird hier betrachtet. if abs(Chromosome.get_fitness(thisChromo)) < abs( Chromosome.get_fitness(thatChromo)): minimum = i foundNewMinimum = True if foundNewMinimum == False: done = True return minimum
def show_fitness_per_epoche(self): popSize = len(self.population) fitness_array = [0] for i in range(popSize): thisChromo = self.population[i] fitness_array.append(Chromosome.get_fitness(thisChromo)) array = np.asarray(self.array_fitness) x = np.arange(1, self.epoch, 1) y1 = array[x] fig = plt.figure() ax = fig.add_subplot(1, 1, 1) plt.xlabel('Epochen') plt.ylabel('Best Fitness/Population') ax.plot(x, y1, color='cornflowerblue', label='partially_mapped') plt.show() #plt.savefig('crossovers_per_epoche.png') return
class TestFitness(unittest.TestCase): def setUp(self): self.data1 = { 'capacity': 10, 'weights': [2, 3.14, 1.98, 5.0, 3.0], 'profits': [40, 50, 100, 95, 30] } self.data1['ratios'] = [ self.data1['profits'][i] / self.data1['weights'][i] for i in range(len(self.data1)) ] self.optimal1 = Chromosome([1, 0, 1, 1, 0], self.data1) self.data2 = { 'capacity': 26, 'weights': [12, 7, 11, 8, 9], 'profits': [24, 13, 23, 15, 16] } self.data2['ratios'] = [ self.data2['profits'][i] / self.data2['weights'][i] for i in range(len(self.data2)) ] self.optimal2 = Chromosome([0, 1, 1, 1, 0], self.data2) self.suboptimal1 = Chromosome([1, 1, 1, 1, 1], self.data1) self.suboptimal2 = Chromosome([1, 1, 1, 1, 1], self.data2) def test_withoutPenalty(self): self.assertEqual(235, self.optimal1.get_fitness(has_penalty=False), 'Incorrect fitness for dataset 1') self.assertLess(235, self.suboptimal1.get_fitness(has_penalty=False), 'Incorrect fitness for dataset 1') self.assertEqual(51, self.optimal2.get_fitness(has_penalty=False), 'Incorrect fitness for dataset 2') self.assertLess(51, self.suboptimal2.get_fitness(has_penalty=False), 'Incorrect fitness for dataset 2') def test_withPenalty(self): self.assertEqual(235, self.optimal1.get_fitness(has_penalty=True), 'Incorrect fitness for dataset 1') # self.assertLess(235, self.suboptimal1.get_fitness(has_penalty=True), 'Incorrect fitness for dataset 1') self.assertEqual(51, self.optimal2.get_fitness(has_penalty=True), 'Incorrect fitness for dataset 2')
def bad_recombination_deap(self, chromA, chromB, child1, child2): tempArray1 = [0] * self.mMaxLength tempArray2 = [0] * self.mMaxLength thisChromo = chromA thatChromo = chromB newChromo1 = self.population[child1] newChromo2 = self.population[child2] # Choose and sort the crosspoints. numPoints = random.randrange( 0, self.mPBCMax) # if PBC_MAX is set any higher than 6 or 8. crossPoints = [0] * numPoints for i in range(numPoints): crossPoints[i] = Operations.get_exclusive_random_integer_by_array( self, 0, self.mMaxLength - 1, crossPoints) # Get non-chosens from parent 2: Die Zahlen die bei P2 nicht an den ausgewählten Stellen bei P1 stehen werden in # einem Array gesammelt (tempArray1) k = 0 for i in range(self.mMaxLength): matchFound = False for j in range(numPoints): if Chromosome.get_data(thatChromo, i) == Chromosome.get_data( thisChromo, crossPoints[j]): matchFound = True if matchFound == False: tempArray1[k] = Chromosome.get_data(thatChromo, i) k += 1 # Insert chosens into child 1: in Child 1 werden die Zahlen von P1 an gewählter Position gesetzt, Rest # freigelassen for i in range(numPoints): Chromosome.set_data( newChromo1, crossPoints[i], Chromosome.get_data(thisChromo, crossPoints[i])) # Fill in non-chosens to child 1. k = 0 for i in range(self.mMaxLength): matchFound = False for j in range(numPoints): if i == crossPoints[j]: matchFound = True if matchFound == False: Chromosome.set_data(newChromo1, i, tempArray1[k]) k += 1 newChromo1.compute_fitness() # Kind1 wird rausgehauen und index child2 um eins heragesetzt weil sich population auch wieder ändert if Chromosome.get_fitness(newChromo1) < Chromosome.get_fitness(thisChromo) or \ Chromosome.get_fitness(newChromo1) < Chromosome.get_fitness(thatChromo): sys.stdout.write("Kind1 zu wenig Konflikte: " + str(Chromosome.get_fitness(newChromo2)) + "\n") Chromosome.set_fitness(newChromo1, 5000) sys.stdout.write("Kind1 wurde auf Fitness 5000 erhöht\n") # # Get non-chosens from parent 1 k = 0 for i in range(self.mMaxLength): matchFound = False for j in range(numPoints): if Chromosome.get_data(thisChromo, i) == Chromosome.get_data( thatChromo, crossPoints[j]): matchFound = True if matchFound == False: tempArray2[k] = Chromosome.get_data(thisChromo, i) k += 1 # Insert chosens into child 2. for i in range(numPoints): Chromosome.set_data( newChromo2, crossPoints[i], Chromosome.get_data(thatChromo, crossPoints[i])) # Fill in non-chosens to child 2. k = 0 for i in range(self.mMaxLength): matchFound = False for j in range(numPoints): if i == crossPoints[j]: matchFound = True if matchFound == False: Chromosome.set_data(newChromo2, i, tempArray2[k]) k += 1 newChromo2.compute_fitness() if Chromosome.get_fitness(newChromo2) < Chromosome.get_fitness(thisChromo) \ or Chromosome.get_fitness(newChromo2) < Chromosome.get_fitness(thatChromo): sys.stdout.write("Kind2 zu wenig Konflikte: " + str(Chromosome.get_fitness(newChromo2)) + "\n") Chromosome.set_fitness(newChromo2, 5000) sys.stdout.write("Kind2 wurde auf Fitness 5000 erhöht\n") sys.stdout.write(str(crossPoints) + " CrossPoints\n") sys.stdout.write("BAD_recombination verwendet.\n") return
def do_mating(self): for i in range(self.mOffspringPerGeneration): parentA = Operations.choose_first_parent(self) # Test probability of mating. getRand = random.randrange(0, 100) if getRand <= self.mMatingProbability * 100: parentB = Operations.choose_second_parent(self, parentA) #das crossover des Elternteils mit größerer Fitness wird gewählt chromA = self.population[parentA] chromB = self.population[parentB] if Chromosome.get_fitness(chromA) < Chromosome.get_fitness( chromB): type = Chromosome.get_crossover(chromA) else: type = Chromosome.get_crossover(chromB) if type == 0: newChromo1 = ChromosomeDEAP(self.mMaxLength, 0) newChromo2 = ChromosomeDEAP(self.mMaxLength, 0) self.population.append(newChromo1) newIndex1 = len(self.population) - 1 self.population.append(newChromo2) newIndex2 = len(self.population) - 1 Operations.partially_mapped_crossover( self, chromA, chromB, newIndex1, newIndex2) self.partielle_mapped_co += 1 self.current_p_m += 1 elif type == 1: newChromo1 = ChromosomeDEAP(self.mMaxLength, 1) newChromo2 = ChromosomeDEAP(self.mMaxLength, 1) self.population.append(newChromo1) newIndex1 = len(self.population) - 1 self.population.append(newChromo2) newIndex2 = len(self.population) - 1 # TODO entweder positionbased crossover oder bad_recombination, beides crossover-typ 1 #Operations.bad_recombination_deap(chromA, chromB, newIndex1, newIndex2) Operations.position_based_crossover( self, chromA, chromB, newIndex1, newIndex2) self.position_based_co += 1 self.current_p_b += 1 elif type == 2: newChromo1 = ChromosomeDEAP(self.mMaxLength, 2) newChromo2 = ChromosomeDEAP(self.mMaxLength, 2) self.population.append(newChromo1) newIndex1 = len(self.population) - 1 self.population.append(newChromo2) newIndex2 = len(self.population) - 1 Operations.two_point_crossover(self, chromA, chromB, newIndex1, newIndex2) self.two_point_co += 1 self.current_t_p += 1 else: newChromo1 = ChromosomeDEAP(self.mMaxLength, 3) newChromo2 = ChromosomeDEAP(self.mMaxLength, 3) self.population.append(newChromo1) newIndex1 = len(self.population) - 1 self.population.append(newChromo2) newIndex2 = len(self.population) - 1 Operations.order_based_crossover(self, chromA, chromB, newIndex1, newIndex2) self.order_based_co += 1 self.current_o_b += 1 if self.childCount - 1 == self.nextMutation: #Operations.new_gene_mutation(self,newIndex1) Operations.exchange_mutation(self, newIndex1, 1) elif self.childCount == self.nextMutation: #self.new_gene_mutation(newIndex2) Operations.exchange_mutation(self, newIndex2, 1) newChromo1 = self.population[newIndex1] self.childCount += 1 newChromo2 = self.population[newIndex2] self.childCount += 1 # Schedule next mutation. if math.fmod( self.childCount, Operations.math_round(self, 1.0 / self.mMutationRate)) == 0: self.nextMutation = self.childCount + random.randrange( 0, Operations.math_round(self, 1.0 / self.mMutationRate)) return
def genetic_algorithm(self): done = False self.mutations = 0 self.nextMutation = random.randrange( 0, Operations.math_round(self, 1.0 / self.mMutationRate)) while not done: popSize = len(self.population) for i in range(popSize): thisChromo = self.population[i] if Chromosome.get_fitness( thisChromo) == 0 or self.epoch == self.mEpochs: done = True Operations.get_fitness(self) Operations.roulette_selection(self) self.do_mating() Operations.prep_next_epoch(self) self.array_p_m.append(self.current_p_m) self.array_p_b.append(self.current_p_b) self.array_o_b.append(self.current_o_b) self.array_t_p.append(self.current_t_p) self.current_p_m = 0 self.current_p_b = 0 self.current_o_b = 0 self.current_t_p = 0 self.epoch += 1 # This is here simply to show the runtime status. sys.stdout.write("Epoche: " + str(self.epoch) + "\n") sys.stdout.write("done.\n") if self.epoch != self.mEpochs: popSize = len(self.population) for i in range(popSize): thisChromo = self.population[i] if Chromosome.get_fitness(thisChromo) == 0: sys.stdout.write( str(Chromosome.toStr(thisChromo)) + " hat " + str(Chromosome.get_fitness(thisChromo)) + " fitness.\n") Operations.set_foundMimimum(self, 1) break sys.stdout.write("Completed " + str(self.epoch) + " epochs.\n") sys.stdout.write("Encountered " + str(self.mutations) + " mutations in " + str(self.childCount) + " offspring.\n") sys.stdout.write("Encountered " + str(self.partielle_mapped_co) + " partiell-mapped , " + str(self.position_based_co) + " positioon-based and " + str(self.order_based_co) + " order-based Crossover." + str(self.two_point_co) + " two-point Crossover.\n") return