119 lines
3.3 KiB
Python
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)
|