def init(su): su.population = [] su.varLength = [] #Setting the variables boundaries for domain in su.varDomain: if(su.geneType == "Binary string"): su.varLength.append(32) else: su.varLength.append(1) i = 0 #Counter for population individuals counter = 0 #Validity counter '''Initial population starts the proccess with random values''' while True: #Checking if population number was reached if(i == su.populationSize) : break if(counter == 2 * su.populationSize): #If the counter doubles the population size, tere is something wrong with the function or domain so the evolution stops return False su.population.append([]) for domain in su.varDomain: if(su.geneType == "Binary string"): floatVar = round(rd.uniform(domain[0], domain[1]), 3) binaryVar = float2bin(floatVar) su.population[i].extend(binaryVar) elif(su.geneType == "Integer string"): intVar = rd.randint(domain[0], domain[1]) su.population[i].append(intVar) else: floatVar = rd.uniform(domain[0], domain[1]) su.population[i].append(round(floatVar, 3)) su.population[i].append(None) #Appending fitness value fit.getFitness(su.population[i], su) #Calculating fitness #If the fitness couldn't be calculated, the individual is eliminated and the validity counter is incremented if(su.population[i][-1] == None): del su.population[i] counter += 1 else: counter = 0 i += 1 op.sort(su) #Sorting the individuals according to fitnessHistory su.currentGeneration = 1 return True #All individuals were created and evaluated
def nonUniformMutation(chrom, su): i = 0 aux = chrom.copy() for domain in su.varDomain: rand = rd.random() if (rand <= su.mutationRate): if su.geneType == "Float string": if (rd.random() <= .5): aux[i] += delta(su.currentGeneration, su.maxGenerations, domain[1] - aux[i]) else: aux[i] -= delta(su.currentGeneration, su.maxGenerations, aux[i] - domain[0]) else: if (rd.random() <= .5): aux[i] += int( delta(su.currentGeneration, su.maxGenerations, domain[1] - aux[i])) else: aux[i] -= int( delta(su.currentGeneration, su.maxGenerations, aux[i] - domain[0])) i += 1 aux = fit.getFitness(aux, su) if aux[0]: chrom = aux return chrom
def flipMutation(chrom, su): aux = chrom.copy() for i in range(len(chrom) - 1): rand = rd.random() if (rand <= su.mutationRate): aux[i] = '0' if aux[i] == '1' else '1' #Bit inversion aux = fit.getFitness(aux, su) if aux[0]: chrom = aux return chrom
def geneticAlgo(): func, ranges = fitnessfunction() strings = [] k = 10 for i in range(k): strings.append(generatestring(ranges)) m = 10000000000000000 state = strings[0] for _ in range(1000): strings = selection(strings, func) for i in range(0, k, 2): strings[i], strings[i + 1] = crossover(strings[i], strings[i + 1]) for i in range(k): strings[i] = mutation(strings[i], ranges) strings.sort(key=lambda x: getFitness(func, x)) x = getFitness(func, strings[0]) if x < m: m = x state = strings[0] x = int(state[:len(state) // 2], 2) y = int(state[len(state) // 2:], 2) print("Minimum of the function found: {} at x = {} and y = {}".format( m, x, y))
def uniformMutation(chrom, su): i = 0 aux = chrom.copy() for domain in su.varDomain: rand = rd.random() if (rand <= su.mutationRate): if su.geneType == "Float string": aux[i] = rd.uniform(domain[0], domain[1]) else: aux[i] = rd.randint(domain[0], domain[1]) i += 1 aux = fit.getFitness(aux, su) if aux[0]: chrom = aux return chrom
def selection(strings: list, f): a = [] for i in strings: a.append([i, getFitness(f, i)]) a.sort(key=lambda x: x[1]) b = [] for _ in range(len(strings) // 2): x = random.randint(0, len(a) - 1) y = random.randint(0, len(a) - 1) if a[x][1] < a[y][1]: b.append(a[x][0]) else: b.append(a[y][0]) last = b[-1] while last == a[x][0]: x = random.randint(0, len(a) - 1) while last == a[y][0]: y = random.randint(0, len(a) - 1) if a[x][1] < a[y][1]: b.append(a[x][0]) else: b.append(a[y][0]) return b