Traktor/algorytm_genetyczny.py
2024-06-09 14:14:03 +02:00

119 lines
3.3 KiB
Python

import pygame
from constant import rows, cols
import random
import numpy as np
ROZMIAR_POPULACJI = 50
GENERACJI = 60
LICZBA_ROSLIN = 30
MUTATION_RATE = 0.1
def wygeneruj_populacje_poczatkowa():
populacja = []
for i in range(ROZMIAR_POPULACJI):
osobnik = []
for j in range(LICZBA_ROSLIN):
x, y = random.randint(0, 7), random.randint(0, 7)
e = (x, y)
# Zastępowanie powtórek
while e in osobnik:
x, y = random.randint(0, 7), random.randint(0, 7)
e = (x, y)
osobnik.append(e)
populacja.append(osobnik)
return populacja
def ocena_osobnika(osobnik):
ocena = 0
if len(osobnik) == len(set(osobnik)):
ocena += 5
else:
ocena -= 5
# Czy dana roślina ma sąsiedzi niepotrzebnym dystansie pomiędzy koordynatami
positions = set(osobnik)
for (x, y) in osobnik:
if ((x + 1, y) in positions or (x - 1, y) in positions or
(x, y + 1) in positions or (x, y - 1) in positions):
ocena -= 1
else:
ocena += 1
return ocena
def selekcja(populacja):
populacja = sorted(populacja, key=lambda x: ocena_osobnika(x), reverse=True)
return populacja[:int(ROZMIAR_POPULACJI * 0.4)]
def mutacja(osobnik, mutation_rate):
# mutacja poprzez randomową zamiane jednej pary koordynatow
for i in range(len(osobnik)):
if random.random() < mutation_rate:
osobnik[i] = (random.randint(0, 7), random.randint(0, 7))
return osobnik
def krzyzowanie(rodzic1, rodzic2):
# krzyzowanie pomiedzy dwojka rodzicow i tworzenie dziecka
dziecko = []
for i in range(len(rodzic1)):
if random.random() < 0.5:
dziecko.append(rodzic1[i])
else:
dziecko.append(rodzic2[i])
return dziecko
def ewolucja():
populacja = (wygeneruj_populacje_poczatkowa())
for gen in range(GENERACJI):
# wybranie jedynie najlepszych osobnikow
rodzice = selekcja(populacja)
# stworz nowa generacje poprzez krzyzowanie i mutacje
potomek = []
while len(potomek) < ROZMIAR_POPULACJI:
rodzic1, rodzic2 = random.sample(rodzice, 2)
dziecko = krzyzowanie(rodzic1, rodzic2)
dziecko = mutacja(dziecko, MUTATION_RATE)
potomek.append(dziecko)
populacja = potomek
najlepszy_potomek = max(populacja, key=ocena_osobnika)
print(f'Generacja {gen}: Best Fitness = {ocena_osobnika(najlepszy_potomek)}')
return max(populacja, key=ocena_osobnika)
wynikowa_populacja = ewolucja()
print('Wynikowa populacja: ' , wynikowa_populacja)
liczba_roslin = 0
karta = np.zeros((rows, cols))
for koord in wynikowa_populacja:
i = koord[0]
j = koord[1]
if karta[i][j] != 7.7:
liczba_roslin += 1
karta[i][j] = 7.7
print('Liczba roślin: ' , liczba_roslin)
for i in range(cols):
for j in range(rows):
print(karta[i][j], end=' ')
print(' ')
print(' ')
#Krzyrzowanie z zastępowaniem powtórek wartościami randomowymi
#kandydat = rodzic1[i] if random.random() < 0.5 else rodzic2[i]
# zastępowanie powtóra koordynatów wartością randomową (mutacja)
#while(kandydat in dziecko):
#x = random.randint(0, ZASIEG - 1)
#y = random.randint(0, ZASIEG - 1)
#kandydat = (x, y)