MLE_Assignments/Aufgabe_3.py

108 lines
3.1 KiB
Python

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()