Cieľom je merať stratu materiálu pri použití rôznych metód selekcie. Ide o to, že selekčná metóda vyvíja určitý špecifický selekčný tlak, meniteľný parametrami selekčnej metódy. Následkom toho niektoré jedince sú preferované na úkor iných jedincov - niektoré jedince sa nedostanú do skupiny rodičov zatiaľ čo iné jedince sa stanú rodičmi aj viacnásobne. Keďže každý jedinec je nositeľom určitého stavebného materiálu, z ktorého je možné vytvárať nových jedincov, tak nevybratie nejakého jedinca znamená ignoráciu materiálu neseného daným nevybratým jedincom.
V konečnom dôsledku dochádza k redukcii dostupného materiálu - nie všetok materiál, reprezentovaný pôvodnými jedincami, je dostupný v selektovanej skupine jedincov.
Je daná skupina jedincov, pričom každý z nich má pridelenú náhodne vybratú hodnotu vhodnosti. Na základe tejto vhodnosti a použitej vzorkovacej metódy je možné pre každého jedinca určiť očakávanú pravdepodobnosť vzorkovania a následne pravdepodobnosť toho, že daný jedinec nebude vybratý a teda ním reprezentovaný materál bude ignorovaný.
Realizuje sa selekčný proces (keďže sa jedná o stochastický proces, tak sa viackrát opakuje pre získanie spoľahlivejšej vzorky dát). Pre každého jedinca sa zaznamená, koľkokrát bol počas jednotlivých opakovaní selekcie vyberaný za rodiča. Z týchto dát je možné pre každého jedinca určiť skutočnú hodnotu pravdepodobnosti, s ktorou bol daný jedinec výberom ignorovaný.
Určené pravdepodobnosti ignorovania jedincov sa použijú pre výpočet priemernej pravdepodobnosti ignorácie, ktorá reprezentuje stratu materiálu.
Pre prípravu experimentu je potrebné doplniť (nahradiť) kód v bunke venovanej metódam premapovania vhodnosti a v bunke venovanej selekčnej metóde. Aktuálne je v nich imlementované premapovanie identitou (nemeniace hodnoty vhodnosti jedincov) a vzorkovanie SSwR (teda základná ruleta). Je možné meniť kód pre:
Taktiež je potrebné vhodne (od/za)komentovať volania pre výpočet hodnôt strata_ocak a strata_skut v závislosti na použitom type selekčnej metódy (opakovanej alebo jednorazovej).
import random
from functools import reduce
from operator import add
import matplotlib.pyplot as plt
# Generovanie populácie
μ = 100 # veľkosť populácie
jedince = [(i,random.random()) for i in range(μ)]
# Premapovanie vhodnosti jedincov
def Φmap_identity(jedince): # identita
map_fun = lambda x: x
premap_Φ = [(i,map_fun(x)) for (i,x) in jedince]
return premap_Φ
def Φmap_lin(jedince): # lineárne zotriedenie - TBD
neimplementovane
def Φmap_exp(jedince): # exponenciálne zotriedenie - TBD
neimplementovane
def Φmap_qtur(jedince): # q-turnaj premapovanie - TBD
neimplementovane
def Φmap_orez(jedince): # orezavacie zotriedenie - TBD
neimplementovane
# zvolená metóda premapovania vhodnosti
Φmap = Φmap_identity
#Φmap = Φmap_lin
#Φmap = Φmap_exp
#Φmap = Φmap_qtur
#Φmap = Φmap_orez
populacia = Φmap(jedince)
# Pravdepodobnosť selekcie pri proporcionálnej selekcii
Φsum = reduce(lambda x, y: x + y[1], populacia, 0)
ps = [(i,Φi / Φsum) for (i, Φi) in populacia]
# Teoretická strata materiálu
def strata_opakovany_vyber(x):
return pow(1-x,μ)
def strata_jednorazovy_vyber(x):
return max(1-x*μ,0)
# Selekčná metóda - vyberá sa toľko rodičov, koľko je jedincov v populácii
def vyber_rodica_SSwR(ps, jedince): # SSwR vzorkovanie - nepresne (maximalne rozpatie)
jazycek = μ * random.random()
index = 0
sum_η = ps[index][1] * μ
while(sum_η < jazycek):
index += 1
sum_η += ps[index][1] * μ
return jedince[index]
def vyber_rodica_RSSwoR(ps, jedince): # RSSwoR vzorkovanie - TBD
neimplementovane
def vyber_rodica_qturnaj(ps, jedince): # q-turnaj vzorkovanie - TBD
neimplementovane
def vyber_rodica_orezanie(ps, jedince): # Orezávacie vzorkovanie - TBD
neimplementovane
def selekcia_opakovana(jedince): # opakovaná ruleta, turnaj, orezanie
rodicia = []
for _ in range(μ):
rodicia.append(vyber_rodica_SSwR(ps, jedince))
#rodicia.append(vyber_rodica_RSSwoR(ps, jedince))
#rodicia.append(vyber_rodica_qturnaj(ps, jedince))
#rodicia.append(vyber_rodica_orezanie(ps, jedince))
return rodicia
def selekcia_jednorazova(jedince): # SUS ruleta - TBD
neimplementovane
def selekcia(jedince):
rodicia = selekcia_opakovana(populacia)
#rodicia = selekcia_jednorazova(populacia)
return rodicia
# Experiment - opakované selekcie
OPAKOVANIA = 1000
vyber_poc = [0] * μ # kumulovanie počty vyberov jedincov
for _ in range(OPAKOVANIA):
vybery = [0] * μ
for rodic in selekcia(populacia):
vybery[rodic[0]] += 1
for jedinec, vyber in enumerate(vybery):
vyber_poc[jedinec] += vyber
# Strata materiálu po jedincoch
## teoretická strata jedinca
strata_ocak = [ps for (_,ps) in sorted(ps, key=lambda x: x[1])]
strata_ocak = list(map(strata_opakovany_vyber,strata_ocak)) # vybrat podľa použitého vzorkovania
#strata_ocak = list(map(strata_jednorazovy_vyber,strata_ocak)) # vybrat podľa použitého vzorkovania
# skutocná strata materiálu
strata_skut = [vyber_poc[i] / (OPAKOVANIA * μ) for (i,_) in sorted(ps, key=lambda x: x[1])]
strata_skut = list(map(strata_opakovany_vyber,strata_skut)) # vybrat podľa použitého vzorkovania
#strata_skut = list(map(strata_jednorazovy_vyber,strata_skut)) # vybrat podľa použitého vzorkovania
plt.suptitle("Očakávaná a realizovaná strata materiálu")
plt.xlabel("jedince")
plt.ylabel("pravdepodobnosť nevýberu")
plt.ylim([0.05,1.05])
plt.plot(strata_ocak,"b-", label="očakávaná")
plt.plot(strata_skut,"r-", label="realizovaná")
plt.legend(loc="upper right")
plt.show()
# Strata materiálu celkovo
ocak = reduce(add, strata_ocak) / μ
skut = reduce(add, strata_skut) / μ
print(
f"Celková strata materiálu"
f"\n teoretická : {ocak}"
f"\n realizovaná : {skut}"
)