import numpy as np from matplotlib import pyplot as plt qmin = -4 qmax = 4 GENE_LENGTH = 16 POPULATION_SIZE = 250 GENERATION_COUNT = 250 TOURNAMENT_SIZE = 5 x_values = np.linspace(-1, 1, 100) mut_rate = 0.05 # Mutationsrate def initGen(): return [np.random.randint(2, size=4 * GENE_LENGTH) for _ in range(POPULATION_SIZE)] def gray_to_binary(gray_array): binary_array = [gray_array[0]] for i in range(1, len(gray_array)): binary_array.append(binary_array[i - 1] ^ gray_array[i]) return binary_array def binary_array_to_int(binary_array): binary_string = ''.join(map(str, binary_array)) return int(binary_string, 2) def grayToInt(gray_array): return binary_array_to_int(gray_to_binary(gray_array)) def getCoefficents(gene): params = [] for i in range(4): dezimahl = grayToInt(gene[i * GENE_LENGTH: (i+1) * GENE_LENGTH]) q = qmin + (qmax - qmin) / (2**GENE_LENGTH - 1) * dezimahl params.append(q) return params def goalFunction(x): return np.exp(x) def approxFunction(x, gen): a, b, c, d = getCoefficents(gen) return a*x**3 + b*x**2 + c*x + d def fitnessFunction(gen): squared_differences = (approxFunction(x_values, gen) - goalFunction(x_values)) ** 2 quadratic_error = np.mean(squared_differences) return -quadratic_error def tournament_selection(generation): selected = [generation[np.random.randint(0, POPULATION_SIZE)] for _ in range(TOURNAMENT_SIZE)] selected = sorted(selected, key=fitnessFunction, reverse=True) return selected[0] def crossover(gene1, gene2): split = np.random.randint(1, len(gene1) - 1) newGene1 = np.append(gene1[:split], gene2[split:]) newGene2 = np.append(gene2[:split], gene1[split:]) return newGene1, newGene2 def mutateL(gene): if np.random.rand() < mut_rate: bit = np.random.randint(0, GENE_LENGTH) gene[bit] = 1 - gene[bit] return gene def mutate(gene): for bit in range(len(gene)): if np.random.rand() < mut_rate: gene[bit] = 1 - gene[bit] return gene def main(): oldGen = initGen() allTimeGene = oldGen[0] alltimeFitness = -1000 for i in range(GENERATION_COUNT): newGen = [] while len(newGen) < POPULATION_SIZE: gene1 = tournament_selection(oldGen) gene2 = tournament_selection(oldGen) newgene1, newgene2 = crossover(gene1, gene2) newGen.append(mutate(newgene1)) newGen.append(mutate(newgene2)) oldGen = np.array(newGen) oldGen = sorted(oldGen, key=fitnessFunction, reverse=True) if fitnessFunction(oldGen[0]) > alltimeFitness: alltimeFitness = fitnessFunction(oldGen[0]) allTimeGene = oldGen[0] print("Generation", i, "Best fitness:", alltimeFitness) print("Final fitness:", alltimeFitness) plt.plot(x_values, approxFunction(x_values, allTimeGene), label='Approximated f(x)') plt.plot(x_values, goalFunction(x_values), label='Target g(x)', linestyle='dashed') plt.title('Genetic Algorithm') plt.xlabel('x') plt.ylabel('y') plt.legend() plt.show() if __name__ == "__main__": main()