2023-06-14 13:02:11 +02:00
|
|
|
import random
|
|
|
|
|
|
|
|
EKRAN_SZEROKOSC = 770
|
|
|
|
EKRAN_WYSOKOSC = 770
|
|
|
|
blockSize = 70
|
2023-06-15 17:34:10 +02:00
|
|
|
LICZBA_REGALOW = 4
|
|
|
|
LICZBA_MIEJSC_NA_PACZKE = 1
|
2023-06-14 13:02:11 +02:00
|
|
|
LICZBA_SKRZYNEK_NA_LISTY = 1
|
|
|
|
|
2023-06-15 17:34:10 +02:00
|
|
|
ROZMIAR_POPULACJI = 100
|
|
|
|
LICZBA_GENERACJI = 100
|
|
|
|
|
2023-06-14 13:02:11 +02:00
|
|
|
|
|
|
|
def wygeneruj_osobnika(zasieg_wspolrzednych, ilosc_wspolrzednych):
|
|
|
|
osobnik = list()
|
|
|
|
for j in range(ilosc_wspolrzednych):
|
2023-06-15 17:34:10 +02:00
|
|
|
x = random.randint(1, zasieg_wspolrzednych)
|
|
|
|
y = random.randint(1, zasieg_wspolrzednych)
|
2023-06-14 13:02:11 +02:00
|
|
|
e = (x, y)
|
|
|
|
osobnik.append(e)
|
|
|
|
return osobnik
|
2023-06-14 13:04:08 +02:00
|
|
|
|
|
|
|
|
|
|
|
def wygeneruj_populacje_poczatkowa(liczebnosc_populacji):
|
|
|
|
populacja = list()
|
2023-06-15 17:58:27 +02:00
|
|
|
zasieg = int((EKRAN_WYSOKOSC / blockSize) - 3)
|
2023-06-15 17:34:10 +02:00
|
|
|
ilosc_wspolrzednych = (LICZBA_REGALOW + LICZBA_MIEJSC_NA_PACZKE + LICZBA_SKRZYNEK_NA_LISTY)
|
2023-06-14 13:04:08 +02:00
|
|
|
for i in range(liczebnosc_populacji):
|
|
|
|
osobnik = wygeneruj_osobnika(zasieg, ilosc_wspolrzednych)
|
|
|
|
while osobnik in populacja:
|
|
|
|
osobnik = wygeneruj_osobnika(zasieg, ilosc_wspolrzednych)
|
|
|
|
populacja.append(osobnik)
|
|
|
|
return populacja
|
|
|
|
|
|
|
|
|
2023-06-15 17:34:10 +02:00
|
|
|
def ocena_osobnika(osobnik):
|
|
|
|
ocena = 0
|
|
|
|
|
|
|
|
# Czy koordynaty sie nie powtarzaja
|
|
|
|
if len(osobnik) == len(set(osobnik)):
|
|
|
|
ocena += 10
|
|
|
|
else:
|
|
|
|
ocena -= 10
|
|
|
|
|
|
|
|
# Czy zachowany jest minimalny dystans miedzy koordynatami
|
|
|
|
for i in range(len(osobnik)):
|
|
|
|
for j in range(i + 1, len(osobnik)):
|
|
|
|
x1, y1 = osobnik[i]
|
|
|
|
x2, y2 = osobnik[j]
|
|
|
|
distance = max(abs(x2 - x1), abs(y2 - y1))
|
|
|
|
if distance >= 3:
|
|
|
|
ocena += 10
|
|
|
|
else:
|
|
|
|
ocena -= 10
|
|
|
|
|
|
|
|
return ocena
|
|
|
|
|
|
|
|
def mutacja(osobnik):
|
|
|
|
# mutacja poprzez zamiane randomowej pary koordynatow
|
|
|
|
index_osobnika = random.randint(0, len(osobnik) - 1)
|
2023-06-15 17:58:27 +02:00
|
|
|
x = random.randint(1, (EKRAN_SZEROKOSC / blockSize) - 3)
|
|
|
|
y = random.randint(1, (EKRAN_WYSOKOSC / blockSize) - 3)
|
2023-06-15 17:34:10 +02:00
|
|
|
osobnik[index_osobnika] = (x, y)
|
|
|
|
|
|
|
|
def krzyzowanie(rodzic1, rodzic2):
|
|
|
|
# krzyzowanie pomiedzy dwojka rodzicow i tworzenie dziecka
|
|
|
|
dziecko = []
|
|
|
|
for i in range(len(rodzic1)):
|
|
|
|
dziecko.append(rodzic1[i] if random.random() < 0.5 else rodzic2[i])
|
|
|
|
return dziecko
|
|
|
|
|
|
|
|
def ewolucja():
|
|
|
|
|
|
|
|
populacja = (wygeneruj_populacje_poczatkowa(ROZMIAR_POPULACJI))
|
|
|
|
|
|
|
|
for i in range(LICZBA_GENERACJI):
|
|
|
|
|
|
|
|
# sortowanie populacji wynikami oceny osobnikow
|
|
|
|
populacja = sorted(populacja, key=lambda x: ocena_osobnika(x), reverse=True)
|
|
|
|
|
|
|
|
# wybranie jedynie najlepszych osobnikow
|
|
|
|
rodzice = populacja[:int(ROZMIAR_POPULACJI * 0.2)]
|
|
|
|
|
|
|
|
# stworz nowa generacje poprzez krzyzowanie i mutacje
|
|
|
|
potomek = rodzice[:]
|
|
|
|
while len(potomek) < ROZMIAR_POPULACJI:
|
|
|
|
rodzic1 = random.choice(rodzice)
|
|
|
|
rodzic2 = random.choice(rodzice)
|
|
|
|
dziecko = krzyzowanie(rodzic1, rodzic2)
|
|
|
|
mutacja(dziecko)
|
|
|
|
potomek.append(dziecko)
|
|
|
|
|
|
|
|
populacja = potomek
|
|
|
|
|
|
|
|
return populacja[0]
|
|
|
|
|
|
|
|
def print_board(osobnik):
|
|
|
|
board = [['-' for _ in range(EKRAN_SZEROKOSC // blockSize)] for _ in range(EKRAN_WYSOKOSC // blockSize)]
|
|
|
|
|
|
|
|
for x, y in osobnik:
|
|
|
|
if 0 <= x < EKRAN_SZEROKOSC // blockSize and 0 <= y < EKRAN_WYSOKOSC // blockSize:
|
|
|
|
board[y][x] = 'X'
|
|
|
|
|
|
|
|
for row in board:
|
|
|
|
print(' '.join(row))
|
|
|
|
|
|
|
|
# uruchomienie algorytmu genetycznego
|
|
|
|
# najlepszy_osobnik = ewolucja()
|
2023-06-18 13:07:05 +02:00
|
|
|
# print_board(najlepszy_osobnik)
|