Cieľom je merať drift rôznych metód selekcie. Ide o to, že aj v prípade, že jedince v populácii majú rovnakú vhodnosť, selekčná metóda môže uprednostňovať niektoré jedince na úkor iných jedincov. Teda aj napriek rovnakej vhodnosti niektoré jedince môžu z populácie vypadávať zatiaľ čo iné jedince môžu zvyšovať svoje zastúpenie v populácii.
Sú dané dve skupiny jedincov, pričom každá z nich obsahuje jedince s rovnakou pridelenou vhodnosťou. Obe skupiny jedincov sú rovnako veľké.
Realizuje sa selekčný proces ako séria selekcií tvaru P -> P' -> P'' -> ... -> P''''''', pričom každá selekcia robí výber zo skupiny jedincov, ktorá vznikla ako výsledok predchádzajúcej selekcie. Toto reťazenie pokračuje vopred stanovený počet vykonaných selekcií. Môže nastať prípad, že na konci série selekcií:
Keďže sa jedná o stochastický proces, tak pre získanie priemerného chovania musí byť viackrát opakovaný pre získanie spoľahlivej vzorky dát. Avšak v tomto experimente nie je ani tak zaujímavé priemerné chovanie, pretože spriemernením dvoch extrémnych chovaní (vytlačenie raz jedného a raz druhého typu jedincov z populácie) vedie na priemerné chovanie (priemerne rovnaké počty jedincov oboch typov), ktoré môže byť výrazne odlišné od skutočného priemerného chovania.
Pre prípravu experimentu je potrebné doplniť (nahradiť) kód v bunke venovanej selekčnej metóde. Aktuálne je v nej imlementované vzorkovanie SSwR (teda základná ruleta). Je možné meniť metódu pre:
import random
from functools import reduce
from operator import add
import matplotlib.pyplot as plt
# Generovanie populácie
μ = 100 # veľkosť populácie - parne cislo
jedince = [1 for i in range(μ//2)] + [0 for i in range(μ-μ//2)] # dva typy jedincov
#jedince
# Určenie vhodnosti jedincov
FIT = 0.2 # vhodnosť kazdeho jedinca bez ohladu na jeho typ
def Φ(jedinec):
return FIT
populacia = [(i, Φ(i)) for i in jedince]
#populacia
# Určenie distribúcie jedincov
def distribucia(populacia):
dist = reduce(add, map(lambda x: x[0], populacia))
return μ-dist, dist
distribucia(populacia)
# Selekčná metóda - vyberá sa toľko rodičov, koľko je jedincov v populácii
def premapovanie_vhodnosti(jedince): # identita
map_fun = lambda x: x
premap_Φ = [map_fun(x) for (_,x) in jedince]
return premap_Φ
def urcenie_pravdepodobnosti_selekcie(premap_Φ, jedince): # proporcionalna selekcia
sum_Φ = reduce(add, premap_Φ)
ps = [Φ/sum_Φ for Φ in premap_Φ]
return ps
def vyber_rodica(ps, jedince): # SSwR vzorkovanie - nepresne (maximalne rozpatie)
jazycek = μ * random.random()
index = 0
sum_η = ps[index] * μ
while(sum_η < jazycek):
index += 1
sum_η += ps[index] * μ
return jedince[index]
def selekcia(jedince):
premap_Φ = premapovanie_vhodnosti(jedince)
ps = urcenie_pravdepodobnosti_selekcie(premap_Φ, jedince)
rodicia = []
for _ in range(μ):
rodicia.append(vyber_rodica(ps, jedince))
return rodicia
distribucia(selekcia(populacia))
# Experiment - jeden beh
POC_SELEKCII = 300
def seria_selekcii(populacia):
pocet_jedincov_0 = [distribucia(populacia)[0]] # pocet jedincov 0 v populacii pred seriou selekcii
vyber_z_populacie = populacia
for i in range(POC_SELEKCII):
zdrojova_populacia = vyber_z_populacie
vyber_z_populacie = selekcia(zdrojova_populacia)
pocet_jedincov_0.append(distribucia(vyber_z_populacie)[0])
return pocet_jedincov_0
# Experiment - opakovane sekvencie selekcii
OPAKOVANIA = 1 # 1 vs 100
vysledky = [0 for _ in range(POC_SELEKCII+1)]
for _ in range(OPAKOVANIA):
seria = seria_selekcii(populacia)
vysledky = map(add, vysledky, seria)
vysledky = [x / OPAKOVANIA for x in vysledky]
plt.suptitle("Distribúcia typov jedincov")
plt.xlabel("selekcia")
plt.ylabel("pomer typov jedincov")
plt.ylim([-2,102])
plt.plot(vysledky)
plt.show()