Genetické algoritmy: populácia, kríženie, mutácia a výber na batohu na výlet
Genóm a zdatnosť, turnajový výber, jednobodové kríženie, mutácia a elitizmus, veta o schémach a predčasná konvergencia — na úlohe batohu so známym optimom, od stanu po FunSearch a AlphaEvolve.
Séria Základy AI Diel 27 z 52
- Mapa umelej inteligencie: čo je čo a ako to do seba zapadá
- Stručná história umelej inteligencie: od Turinga po jazykové modely
- Dáta, model, tréning, inferencia: základné pojmy na jednom príklade
- Ako čítať matematický zápis: symboly, indexy, sumy a kvantifikátory
- Množiny a relácie: stavebnica, z ktorej sa skladajú definície v AI
- Funkcie a zobrazenia: prečo je každý model v AI funkcia
- Logika a dôkazy: pravidlá, podľa ktorých sa v AI uvažuje
- Grafy a stromy: štruktúra, na ktorej stojí hľadanie aj neurónové siete
- Lineárna algebra pre strojové učenie: vektory, matice a prečo AI hlavne násobí
- Derivácie, gradient a reťazové pravidlo: ako model zistí, ktorým smerom sa učiť
- Gradientný zostup: ako sa model učí
- Čo je pravdepodobnosť: od hodu kockou ku Kolmogorovovým axiómam
- Podmienená pravdepodobnosť a Bayesova veta: ako zmeniť odhad, keď sa dozviete niečo nové
- Náhodná premenná a distribučná funkcia: jedna funkcia, ktorá o rozdelení povie všetko
- Funkcia hustoty a pravdepodobnostná funkcia: prečo má spojitá premenná v bode pravdepodobnosť nula
- Stredná hodnota, rozptyl a kovariancia: kde rozdelenie leží, aké je široké a čo s čím súvisí
- Prehľad pravdepodobnostných rozdelení: Bernoulliho, binomické, Poissonovo, rovnomerné, normálne a exponenciálne
- Zákon veľkých čísel a centrálna limitná veta: prečo sa priemery správajú tak predvídateľne
- Štatistika a odhady parametrov: maximálna vierohodnosť, MAP a intervaly spoľahlivosti
- Teória informácie: entropia, krížová entropia a KL divergencia — odkiaľ sa berú stratové funkcie
- Prehľadávanie stavového priestoru: BFS, DFS, UCS a A* s animáciami
- Hry a protivník: minimax, alfa-beta orezávanie a Monte Carlo tree search
- Splňovanie obmedzujúcich podmienok: backtracking, propagácia obmedzení a AC-3 na sudoku a mape krajov
- Logika a znalostné systémy: dopredné a spätné reťazenie, rezolúcia a expertné systémy
- Plánovanie: STRIPS, svet kociek, heuristiky z relaxácie a plánovanie v AI agentoch
- Lokálne hľadanie a simulované žíhanie: obchodný cestujúci cez krajské mestá
- Genetické algoritmy: populácia, kríženie, mutácia a výber na batohu na výlet
- Evolučné stratégie a genetické programovanie: od pravidla jednej pätiny po Keplerov zákon
- Optimalizácia mravčou kolóniou: ako feromónová stopa nájde krátku cestu
- Optimalizácia rojom častíc: zotrvačnosť, vlastná skúsenosť a skúsenosť roja
- Neuroevolúcia: evolúcia váh aj tvaru neurónových sietí a algoritmus NEAT
- Fuzzy množiny a funkcie príslušnosti: ako zapísať „trochu teplo“
- Fuzzy logika a pravdepodobnosť: prečo „trochu teplo“ neznamená „pravdepodobne teplo“
- Fuzzy logika: t-normy, implikácie a pravidlá AK–TAK
- Fuzzy riadenie: Mamdani a Sugeno od ventilátora po kyvadlo na vozíku
- Fuzzy zhlukovanie: algoritmus fuzzy c-means a body medzi zhlukmi
- Neuro-fuzzy systémy (ANFIS): fuzzy pravidlá, ktoré sa učia z dát
- Markovove reťazce: prechodová matica, stacionárne rozdelenie a PageRank
- Skryté Markovove modely: Viterbiho algoritmus a nepoctivé kasíno
- Bayesovské siete: prečo je tráva mokrá a čo z toho vyplýva pre postrekovač
- Kalmanov filter: ako z nepresných meraní odhadnúť, kde auto je a ako rýchlo ide
- Druhy strojového učenia: s učiteľom, bez učiteľa, s čiastočným učiteľom a ďalšie
- Prompty, kontext a RAG: ako modelu dať správne informácie
- Variačné autoenkodéry (VAE): nové obrázky zo spojitého latentného priestoru
- Generatívne adversariálne siete (GAN): falšovateľ proti detektívovi
- Difúzne modely: ako sa z čistého šumu stane obrázok
- Markovove rozhodovacie procesy: stavy, akcie, odmeny a Bellmanove rovnice
- Q-learning a DQN: učenie hodnoty akcií od tabuľky po neurónovú sieť
- Policy gradient a PPO: učenie priamo stratégie
- Ako funguje AI agent: jazykový model v slučke s nástrojmi
- Programovanie s AI agentmi: zadanie, testy a kontrola
- Vyhodnocovanie a bezpečnosť AI systémov: ako merať a ako strážiť
Celá osnova série Hotovo: 52 z 83 tém
- Ako zakódovať riešenie ako genóm a ako výber, kríženie a mutácia vylepšujú celú populáciu.
- Prečo bez mutácie evolúcia predčasne skonverguje a na čo je kríženie.
- Kde sa genetické algoritmy používajú dnes — aj s jazykovým modelom v úlohe mutácie.
Čo sa hodí vedieť vopred: Lokálne hľadanie a simulované žíhanie: obchodný cestujúci cez krajské mestá
Príroda nemá inžiniera, a predsa vyrobila oko, krídlo aj mozog. Stačili jej tri veci: jedince sa od seba líšia, svoje vlastnosti odovzdávajú potomkom a tí zdatnejší majú potomkov viac. V sedemdesiatych rokoch John Holland z Michiganskej univerzity ukázal, že tie isté tri veci fungujú aj v počítači — ako všeobecná metóda, ako hľadať dobré riešenia úloh, pri ktorých nevieme, ako ich riešiť šikovne. Genetický algoritmus nepotrebuje gradient, nepotrebuje vzorec, potrebuje len vedieť povedať, ktoré z dvoch riešení je lepšie.
Nadväzuje na diel Lokálne hľadanie a simulované žíhanie. Žíhanie vylepšovalo jedno riešenie; genetický algoritmus ich vylepšuje celú populáciu naraz.
1. Úloha: batoh na výlet
Chystáte sa na niekoľkodňový výlet. Doma máte 24 vecí — stan, spací vak, varič, fotoaparát, knihu… — a každá niečo váži a na niečo je. Batoh smie vážiť najviac 10 kg. Čo vziať, aby bol úžitok čo najväčší?
Definícia — úloha batohu (0/1)
Nech n ∈ ℕ, n ≥ 1, je počet vecí, w1, …, wn > 0 ich hmotnosti, u1, …, un > 0 ich úžitky a W > 0 nosnosť batohu. Výber vecí zapíšeme vektorom x = (x1, …, xn) ∈ {0, 1}n, kde xi = 1 práve vtedy, keď i-tú vec berieme. Výber x je prípustný práve vtedy, keď ∑i=1n wixi ≤ W. Úloha batohu (0/1) je úloha nájsť
x* ∈ argmax { ∑i=1n uixi : x ∈ {0, 1}n, ∑i=1n wixi ≤ W }.
Hľadáme teda prípustný výber s najväčším súčtom úžitkov; „0/1“ v názve znamená, že každú vec možno vziať len celú a najviac raz.
Každá vec je otázka „beriem, neberiem“ — jednotka, alebo nula. Možností je 224, teda 16 777 216 batohov. Pažravá stratégia „najprv to najužitočnejšie na kilo“ často funguje, ale optimum nezaručí: jedna ťažká vec môže vytlačiť tri ľahké, ktoré boli dohromady cennejšie.
Pre celočíselné hmotnosti sa dá optimum spočítať presne dynamickým programovaním — zo všetkých 24 vecí a nosnosti 1 000 dekagramov je to 24 000 krokov. Najlepší batoh má 727 bodov úžitku a váži 9,9 kg; doma zostane jedlo navyše, fotoaparát, kniha, sandále a opaľovací krém. Vďaka tomu zase presne uvidíme, ako blízko sa evolúcia dostane. Genetický algoritmus sa však hodí hlavne tam, kde taký presný postup neexistuje.
Dynamické programovanie vypĺňa tabuľku T[i][c] — najlepší úžitok, ktorý možno dosiahnuť len z prvých i vecí, keď smú vážiť najviac c. Každé políčko sa spočíta z riadka nad ním:
T[i][c] = max( T[i − 1][c] , T[i − 1][c − wi] + ui )
- T[i][c]
- najlepší úžitok z prvých i vecí pri nosnosti c; políčko T[n][W] je odpoveď na celú úlohu
- T[i − 1][c]
- možnosť „i-tú vec neberiem“ — potom je najlepšie to, čo sa dalo poskladať z predchádzajúcich vecí s rovnakou nosnosťou
- T[i − 1][c − wi]
- možnosť „beriem“ — vec zaberie wi, takže na ostatné zostane len c − wi; najlepšie využitie zvyšku už v tabuľke máme (smie sa len pre c ≥ wi)
- ui
- úžitok veci, ktorú sme v tej druhej možnosti pribalili
Príklad — tabuľka pre štyri veci a nosnosť 50 dkg
Čelovka (10 dkg, 25 bodov), nôž (10 dkg, 18), varič (40 dkg, 30) a karimatka (50 dkg, 45). Všetky hmotnosti sú násobky desiatich, takže stačia stĺpce po 10 dkg:
| veci | c = 0 | 10 | 20 | 30 | 40 | 50 |
|---|---|---|---|---|---|---|
| žiadna | 0 | 0 | 0 | 0 | 0 | 0 |
| + čelovka | 0 | 25 | 25 | 25 | 25 | 25 |
| + nôž | 0 | 25 | 43 | 43 | 43 | 43 |
| + varič | 0 | 25 | 43 | 43 | 43 | 55 |
| + karimatka | 0 | 25 | 43 | 43 | 43 | 55 |
Nôž, c = 20: T[2][20] = max(T[1][20], T[1][10] + 18) = max(25, 25 + 18) = 43
Varič, c = 40: T[3][40] = max(T[2][40], T[2][0] + 30) = max(43, 0 + 30) = 43 — varič sa neoplatí
Varič, c = 50: T[3][50] = max(T[2][50], T[2][10] + 30) = max(43, 25 + 30) = 55 — varič a čelovka
Karimatka, c = 50: T[4][50] = max(T[3][50], T[3][0] + 45) = max(55, 0 + 45) = 55
(Farby podľa vzorca vyššie.)
Pažravá stratégia by vzala veci podľa úžitku na dekagram: čelovku (2,5 bodu/dkg), nôž (1,8), potom by sa karimatka (0,9) ani varič (0,75) do zvyšných 30 dkg nezmestili — len 43 bodov. Vo veľkej úlohe s 24 vecami skončí pažravá stratégia na 702 bodoch: naplní batoh drobnosťami a na stan (220 dkg) už nezostane miesto.
def batoh(w, u, W): # w, u: hmotnosti a úžitky, W: nosnosť
T = [0] * (W + 1) # riadok pre „žiadna vec“
for i in range(len(w)):
for c in range(W, w[i] - 1, -1): # odzadu: T[c − w[i]] je ešte z riadka i − 1
T[c] = max(T[c], T[c - w[i]] + u[i])
return T[W] # n · W krokov: 24 · 1000 = 24 000
2. Jedinec, genóm a zdatnosť
Definícia — genóm, populácia, zdatnosť
Nech je daná úloha batohu s n vecami, hmotnosťami wi a nosnosťou W v dekagramoch a úžitkami ui (i = 1, …, n; u nás n = 24).
- Genóm (chromozóm) je zakódované riešenie; pre batoh je to reťazec x = (x1, …, xn) ∈ {0, 1}n. Jeho zložky xi — jeden bit na vec — nazývame gény.
- Populácia veľkosti μ ∈ ℕ je μ-tica genómov P = (x(1), …, x(μ)), x(j) ∈ {0, 1}n; ten istý genóm v nej môže byť viackrát (na poradí nezáleží, ide teda o multimnožinu s μ prvkami). Prvkom populácie hovoríme jedince.
- Zdatnosť (fitness) je funkcia F : {0, 1}n → ℝ, ktorú algoritmus maximalizuje. Pre batoh ju definujeme s trestom za preťaženie: F(x) = ∑i=1n uixi, ak ∑i=1n wixi ≤ W, F(x) = ∑i=1n uixi − 3 · (∑i=1n wixi − W), inak.
Pre prípustný batoh je teda zdatnosť rovná jeho úžitku a za každý dekagram cez nosnosť sa odčítajú 3 body.
Jedinec je jeden konkrétny batoh zapísaný ako rad jednotiek a núl. Zdatnosť hovorí, aký je dobrý. Preťažený batoh nezakážeme, len ho potrestáme — za každý dekagram navyše tri body dole. Algoritmus sa tak o hranici nosnosti dozvie postupne, a aj preťažený batoh môže mať gény, ktoré sa neskôr zídu.
F(x) = ∑ uixi − 3 · max(0, ∑ wixi − W)
- F(x)
- zdatnosť batohu x — jediné číslo, podľa ktorého výber porovnáva jedincov
- ∑ uixi
- úžitok zabalených vecí (xi = 1 vec započíta, 0 vynechá) — to, čo naozaj chceme maximalizovať
- 3
- cena jedného dekagramu cez limit — je väčšia ako najlepší pomer úžitku a hmotnosti (čelovka, 2,5 bodu/dkg), takže pribaliť čokoľvek do už preťaženého batohu zdatnosť vždy zníži
- max(0, ∑ wixi − W)
- preťaženie v dekagramoch; max s nulou zaistí, že batoh, ktorý sa zmestí, trest nedostane a ľahší batoh nie je zvýhodnený
Príklad — zdatnosť dvoch batohov
Optimum: úžitok 727, hmotnosť 990 dkg ≤ 1 000 ⇒ F = 727 − 3 · 0 = 727
Optimum + fotoaparát (80 dkg, 20 bodov): úžitok 747, hmotnosť 1 070 dkg ⇒ F = 747 − 3 · 70 = 537
(Farby podľa vzorca vyššie.)
Fotoaparát pridá 20 bodov, ale preťaženie 70 dkg stojí 210 — výber taký batoh spoľahlivo odsunie.
3. Výber
Definícia — turnajový a ruletový výber
Nech P = (x(1), …, x(μ)) je populácia veľkosti μ a F : {0, 1}n → ℝ zdatnosť. Výber je náhodný postup, ktorý z P vráti jedného jedinca (rodiča):
- Turnajový výber veľkosti k ∈ ℕ, k ≥ 1: vylosuj nezávisle a rovnomerne indexy i1, …, ik ∈ {1, …, μ} (s vracaním, ten istý index môže padnúť viackrát) a vráť jedinca x(i*), kde i* ∈ argmaxj ∈ {i1, …, ik} F(x(j)) (pri zhode zdatností ktoréhokoľvek z najlepších).
- Ruletový výber (predpokladá F(x(j)) > 0 pre všetky j): vráť jedinca x(i), i ∈ {1, …, μ}, s pravdepodobnosťou P(vybraný x(i)) = F(x(i))/∑j=1μ F(x(j)).
Selekčný tlak je kvalitatívny pojem: ako silno výber uprednostňuje zdatnejších jedincov. Merať ho možno napríklad pomerom očakávaného počtu výberov najlepšieho a priemerného jedinca (pozri príklad nižšie); pri turnaji rastie s k.
Turnaj: vytiahnete tri náhodné batohy a rodičom sa stane ten najlepší z nich. Lepšie batohy tak majú viac detí, ale aj priemerný má šancu, keď sa stretne so slabšími. Keby sa množili len tí úplne najlepší, populácia by rýchlo zdegenerovala na kópie jedného jedinca — a s ňou by zmizla rozmanitosť, z ktorej evolúcia žije.
Aký silný je turnaj, sa dá spočítať presne. Náš program losuje k jedincov s vracaním (ten istý jedinec sa môže do turnaja dostať dvakrát). Zoraďme populáciu od najlepšieho (i = 1) po najhoršieho (i = μ):
P(vyhrá i-ty) = (μ − i + 1)k − (μ − i)k/μk
- P(vyhrá i-ty)
- šanca, že sa rodičom stane práve i-ty najlepší jedinec
- (μ − i + 1)k
- počet turnajov, v ktorých nikto nie je lepší ako i-ty — všetkých k žrebov padne medzi neho a horších
- (μ − i)k
- z nich odčítame turnaje, v ktorých i-ty vôbec nie je — tie by vyhral niekto horší; rozdiel sú turnaje, kde je i-ty najlepší prítomný
- μk
- počet všetkých možných turnajov (k žrebov, každý z μ jedincov) — delením dostaneme pravdepodobnosť
Príklad — turnaj z troch v 40 batohoch
μk = 403 = 64 000. Za generáciu sa vyberá 38 rodičov (dve miesta zaberú elitní jedinci); farby podľa vzorca vyššie:
najlepší: 403 − 393/64 000 = 64 000 − 59 319/64 000 ≈ 7,31 %, očakávane 38 · 0,0731 ≈ 2,78 výberu
20. najlepší: 213 − 203/64 000 = 9 261 − 8 000/64 000 ≈ 1,97 %, očakávane ≈ 0,75 výberu
najhorší: 13 − 03/64 000 ≈ 0,0016 %, očakávane ≈ 0,0006 výberu
Priemerný jedinec dostane 38/40 = 0,95 výberu, najlepší skoro trikrát toľko. Všeobecne pre veľkú populáciu vychádza najlepšiemu zhruba k-krát viac ako priemeru — preto selekčný tlak rastie s k.
4. Kríženie a mutácia
Definícia — jednobodové kríženie
Nech n ≥ 2, a = (a1, …, an) a b = (b1, …, bn) ∈ {0, 1}n sú genómy rodičov a pc ∈ [0, 1] pravdepodobnosť kríženia. Jednobodové kríženie vytvorí dvoch potomkov takto:
- S pravdepodobnosťou 1 − pc kríženie neprebehne a potomkovia sú kópie rodičov a a b.
- Inak vylosuj rovnomerne bod kríženia c ∈ {1, …, n − 1} a potomkovia sú a′ = (a1, …, ac, bc+1, …, bn), b′ = (b1, …, bc, ac+1, …, an).
Potomkovia teda prevezmú prvých c génov od jedného rodiča a zvyšných n − c od druhého. Ďalšie varianty sú dvojbodové kríženie (dva body, vymení sa úsek medzi nimi) a uniformné kríženie, kde pre každé i = 1, …, n nezávisle s pravdepodobnosťou 1/2 platí a′i = ai, b′i = bi, inak a′i = bi, b′i = ai.
Dva batohy si rozstrihnete na rovnakom mieste a vymeníte konce. Dieťa dostane začiatok zoznamu od jedného rodiča a koniec od druhého. Ak jeden rodič dobre vyriešil spanie a druhý jedlo, má dieťa šancu zdediť oboje.
Definícia — bitová mutácia
Nech x = (x1, …, xn) ∈ {0, 1}n je genóm a pm ∈ [0, 1] pravdepodobnosť mutácie. Bitová mutácia vytvorí genóm x′ ∈ {0, 1}n tak, že pre každé i = 1, …, n nezávisle od ostatných génov
x′i = 1 − xi s pravdepodobnosťou pm, x′i = xi s pravdepodobnosťou 1 − pm.
Každý gén sa teda s pravdepodobnosťou pm preklopí (0 ↔ 1). Obvykle sa volí pm = 1/n, takže sa v priemere preklopí n · pm = 1 gén na jedinca.
Občas sa dieťa od rodičov v jednej drobnosti líši: pribalí vec, ktorú nikto z rodičov nemal, alebo nejakú vyberie. Mutácia je jediný zdroj úplne nových génov — kríženie vie len preskladať to, čo už v populácii je.
Príklad — koľko génov mutácia preklopí
Počet preklopených génov má binomické rozdelenie: P(j génov) = (n nad j) · pmj · (1 − pm)n−j. Pre n = 24 a pm = 1/24:
očakávaný počet: n · pm = 24 · 1/24 = 1
žiadna zmena: (23/24)24 ≈ 0,360 (pre veľké n sa blíži 1/e ≈ 0,368)
práve jeden gén: 24 · 1/24 · (23/24)23 ≈ 0,376
Zhruba tretina potomkov teda zostane bez zmeny, tretina sa líši v jednom géne a zvyšok v dvoch a viacerých.
Rodičia sú dva najlepšie batohy z počiatočnej populácie (423 a 398 bodov), strih je za dvanástou vecou. Žiadny z potomkov nie je lepší ako lepší z rodičov — majú 403 a 418 bodov. Kríženie zlepšenie nezaručuje; len ponúka nové kombinácie a výber potom rozhodne, ktoré prežijú. Mutácia u prvého potomka pribalila filter na vodu (15 dkg, 32 bodov) a ten má razom 435 bodov — viac ako obaja rodičia.
Príklad — prepočet kríženia z obrázka
Úžitok sa sčítava po génoch, takže stačí sčítať úžitok začiatku (veci 1–12) a konca (veci 13–24) zvlášť:
rodič 1: 310 + 113 = 423, rodič 2: 305 + 93 = 398
potomok 1 = začiatok rodiča 1 + koniec rodiča 2: 310 + 93 = 403
potomok 2 = začiatok rodiča 2 + koniec rodiča 1: 305 + 113 = 418
mutácia pribalí filter na vodu: 403 + 32 = 435
Rodič 1 je lepší v oboch polovicách (310 > 305 a 113 > 93), takže s týmto strihom ho žiadny potomok prekonať nemôže — kríženie nemá z čoho poskladať lepší celok. Zlepšenie prinesla až mutácia.
5. Celý algoritmus
Algoritmus — genetický algoritmus
Vstup: dĺžka genómu n ≥ 2, zdatnosť F : {0, 1}n → ℝ, veľkosť populácie μ ∈ ℕ, počet elitných jedincov e ∈ {0, …, μ − 1}, veľkosť turnaja k ≥ 1, pravdepodobnosť kríženia pc ∈ [0, 1], pravdepodobnosť mutácie pm ∈ [0, 1] a počet generácií G ∈ ℕ. Výstup: najzdatnejší jedinec poslednej generácie; pri e ≥ 1 je to zároveň najzdatnejší jedinec, ktorého algoritmus kedy ohodnotil.
- Vytvor náhodnú počiatočnú populáciu P0 s μ jedincami (u nás má každý gén hodnotu 1 s pravdepodobnosťou 0,3), ohodnoť ich funkciou F a polož t ← 0.
- Ak je t = G, skonči a vráť jedinca z Pt s najväčšou zdatnosťou.
- Do novej generácie Pt+1 skopíruj e najzdatnejších jedincov z Pt bez zmeny (elitizmus).
- Kým má Pt+1 menej než μ jedincov: vyber z Pt turnajom veľkosti k dvoch rodičov, vykonaj ich jednobodové kríženie s pravdepodobnosťou pc, oboch potomkov zmutuj bitovou mutáciou s pm a pridaj ich do Pt+1; ak nakoniec prebýva jedinec nad μ, zahoď ho.
- Ohodnoť jedincov Pt+1, polož t ← t + 1 a pokračuj krokom 2.
Algoritmus sa zastaví v kroku 2 po presne G generáciách.
Generácia za generáciou: najlepší dvaja prežijú rovno, ostatné miesta obsadia deti zdatných rodičov, trochu preskladané a trochu pozmenené. Elitizmus zaručí, že najlepší nájdený batoh sa nikdy nestratí.
import random
def evoluce(zdatnost, n, velikost=40, generaci=60, p_krizeni=0.9, elita=2):
pop = [[int(random.random() < 0.3) for _ in range(n)] for _ in range(velikost)]
for _ in range(generaci):
pop.sort(key=zdatnost, reverse=True)
dalsi = [g[:] for g in pop[:elita]] # elitizmus
while len(dalsi) < velikost:
a, b = turnaj(pop, zdatnost), turnaj(pop, zdatnost)
if random.random() < p_krizeni:
bod = random.randrange(1, n)
a, b = a[:bod] + b[bod:], b[:bod] + a[bod:]
dalsi += [mutuj(a), mutuj(b)]
pop = dalsi[:velikost]
return max(pop, key=zdatnost)
def turnaj(pop, zdatnost, k=3):
return max(random.choices(pop, k=k), key=zdatnost) # k žrebov s vracaním
def mutuj(g):
return [1 - x if random.random() < 1 / len(g) else x for x in g]
Cenu algoritmu meriame počtom ohodnotení zdatnosti — pri skutočných úlohách (simulácie, merania) je to najdrahší krok. Ohodnotí sa počiatočná populácia a potom každá generácia: μ + G · μ = 40 + 60 · 40 = 2 440 ohodnotení pre μ = 40 jedincov a G = 60 generácií. Elitní jedinci sa ohodnocujú znova, aj keď sa nezmenili; šikovnejší program by si ich zdatnosť pamätal.
6. Evolúcia batohu
Pustime algoritmus: 40 batohov, 60 generácií, turnaj z troch, kríženie s pravdepodobnosťou 0,9, mutácia 1/24 a dvaja elitní jedinci. Obrázok ukazuje populáciu v generáciách 0, 5, 15, 30 a 60 — každý riadok je jeden batoh, každý stĺpec jedna vec, hore na porovnanie optimum:
Na začiatku je populácia pestrá a batohy sú skôr poloprázdne: každá vec sa do nich dostala s pravdepodobnosťou 0,3, takže vážia okolo štyroch kíl (očakávaná hmotnosť je 0,3 · ∑ wi = 0,3 · 12,75 kg ≈ 3,8 kg). Najlepší má 423 bodov, priemer 231. Po piatich generáciách nesie stan 36 zo 40 batohov, fľašu s vodou 35 a najlepší batoh má 634 bodov. Okolo pätnástej generácie populácia narazí na nosnosť — 12 batohov je preťažených — a začne sa učiť, čo obetovať: jedlo navyše a sandále skoro zmizli, fotoaparát však zatiaľ nesie 39 batohov. Optimum, 727 bodov, nájde algoritmus prvýkrát v generácii 26; v generácii 30 už fotoaparát zostal len v jednom batohu. Populácia sa však nikdy nezleje do jediného riešenia — mutácia stále skúša drobné odchýlky.
Algoritmus na to ohodnotil 2 440 batohov — necelé dve stotiny percenta zo všetkých 16 777 216 možností. Náhodné hľadanie s rovnakým počtom pokusov v sto opakovaniach optimum nenašlo ani raz a v priemere skončilo na 574 bodoch.
Príklad — prečo náhodné hľadanie optimum nenájde
Náhodný batoh berie každú vec nezávisle s pravdepodobnosťou 0,3. Optimum obsahuje 19 vecí a 5 ich vynecháva, takže
P(náhodný batoh = optimum) = 0,319 · 0,75 ≈ 1,16 · 10−10 · 0,168 ≈ 1,95 · 10−11
očakávaný počet zásahov v 2 440 pokusoch: 2 440 · 1,95 · 10−11 ≈ 4,8 · 10−8
Aj keby sa losovalo rovnomerne (každá vec s pravdepodobnosťou 1/2), je šanca jedna ku 16 777 216 na pokus. Genetický algoritmus nevylosuje optimum naraz — skladá ho po kúskoch z batohov, ktoré už sú dobré.
7. Na čo je kríženie a na čo mutácia
Oranžová čiara v grafe je ten istý beh s vypnutou mutáciou. Po jedenástich generáciách uviazne na 573 bodoch a už sa nepohne. Prečo, ukáže porovnanie zo sto behov s rôznymi semienkami:
| Variant | Našla optimum | Priemerný úžitok |
|---|---|---|
| Výber + kríženie + mutácia | 88 zo 100 | 726,6 |
| Výber + mutácia (bez kríženia) | 70 zo 100 | 725,0 |
| Výber + kríženie (bez mutácie) | 0 zo 100 | 596,8 |
| Náhodné hľadanie, rovnako pokusov | 0 zo 100 | 573,5 |
Bez mutácie stratí populácia rozmanitosť: keď gén v žiadnom jedincovi nie je, kríženie ho nevyrobí, a výber navyše rýchlo vytlačí všetko okrem najlepších. Tomu sa hovorí predčasná konvergencia. Bez kríženia algoritmus funguje — je to vlastne populácia horolezcov s výberom —, ale je pomalší. Kríženie pomáha skladať dohromady dobré kúsky, ktoré vznikli v rôznych jedincoch.
Veta — Hollandova veta o schémach
Nech n ≥ 2. Schéma je reťazec H = (H1, …, Hn) ∈ {0, 1, ∗}n, kde ∗ znamená „čokoľvek“. Genóm x ∈ {0, 1}n zodpovedá schéme H práve vtedy, keď xi = Hi pre všetky i s Hi ≠ ∗. Pozície i s Hi ≠ ∗ sú pevné; predpokladajme, že aspoň jedna existuje. Definujme
- rád o(H) = |{i : Hi ≠ ∗}| — počet pevných pozícií,
- dĺžku δ(H) = max{i : Hi ≠ ∗} − min{i : Hi ≠ ∗} — vzdialenosť prvej a poslednej pevnej pozície.
Nech genetický algoritmus s populáciou veľkosti μ a kladnou zdatnosťou F > 0 tvorí celú novú generáciu ruletovým výberom, jednobodovým krížením s pravdepodobnosťou pc a bitovou mutáciou s pravdepodobnosťou pm (bez elitizmu). Nech m(H, t) je počet jedincov generácie t, ktorí zodpovedajú H, a ak je m(H, t) > 0, nech F(H) je ich priemerná zdatnosť a F̄ priemerná zdatnosť celej generácie t. Potom pre očakávaný počet v ďalšej generácii (pri danej generácii t) platí
E[m(H, t + 1)] ≥ m(H, t) · F(H)/F̄ · [1 − pc · δ(H)/n − 1 − o(H) · pm].
Slovami: výber počet nositeľov schémy násobí pomerom ich zdatnosti k priemeru a kríženie s mutáciou z neho najviac odčítajú uvedené straty.
Schéma je „stavebný kameň“, napríklad „beriem stan aj spací vak, na ostatnom nezáleží“. Veta hovorí, že krátke stavebné kamene s nadpriemernou zdatnosťou sa v populácii šíria — a to exponenciálne rýchlo, pretože každú generáciu sa ich počet zhruba násobí pomerom F(H)/F̄. Krátke preto, že ich kríženie menej často rozstrihne. Veta je len dolný odhad a o tom, ako dobre algoritmus funguje, sa dodnes vedú diskusie.
E[m(H, t + 1)] ≥ m(H, t) · F(H)/F̄ · [1 − pc · δ(H)/n − 1 −o(H) · pm]
- m(H, t)
- koľko jedincov nesie stavebný kameň teraz — ďalšia generácia z nich vychádza, preto sa s ním násobí
- F(H)/F̄
- o koľko sú nositelia schémy zdatnejší ako priemer — ruleta im dá úmerne viac potomkov; nad 1 sa schéma množí, pod 1 vymiera
- pc · δ(H)/n − 1
- šanca (zhora), že kríženie schému rozstrihne: kríženie prebehne s pc a bod strihu padne s pravdepodobnosťou δ(H)/n − 1 medzi pevné pozície — preto vadia dlhé schémy
- o(H) · pm
- šanca (zhora), že mutácia preklopí niektorú z o(H) pevných pozícií — preto vadia schémy vysokého rádu
Príklad — krátka a dlhá schéma na batohu
Hranatá zátvorka pre nastavenie nášho behu (pc = 0,9, n = 24, pm = 1/24). Obe schémy majú rád 2; farby podľa vzorca vyššie:
„stan aj spací vak“ (gény 1 a 2, δ = 1): 1 − 0,9 · 1/23 − 2 · 1/24 ≈ 1 − 0,039 − 0,083 = 0,878
„stan aj ponožky navyše“ (gény 1 a 24, δ = 23): 1 − 0,9 · 23/23 − 2 · 1/24 ≈ 1 − 0,9 − 0,083 = 0,017
Krátkej schéme stačí, aby jej nositelia boli o 14 % zdatnejší ako priemer (1/0,878 ≈ 1,14), a podľa vety sa už šíri. Dlhá schéma by musela byť šesťdesiatkrát zdatnejšia — veta o nej v podstate nič nesľubuje. Náš algoritmus používa turnaj, nie ruletu, takže pre neho platí len hranatá zátvorka; prvé dva činitele by sa počítali inak.
8. Genetické algoritmy v praxi
- Návrh tvarov. Anténa družíc NASA ST5 (vypustených v roku 2006) bola navrhnutá evolučným algoritmom: zvláštne pokrútený drôtik, ktorý by inžiniera nenapadol, ale splnil zadanie aspoň rovnako dobre ako ručne navrhnutá anténa (v neskorších pokusoch aj lepšie).
- Rozvrhy a logistika. Rozvrhy, plány zmien alebo usporiadanie skladu — úlohy s mnohými podmienkami, kde sa zdatnosť dá spočítať, ale presný algoritmus by bežal veky.
- Strojové učenie. Evolúcia ladí hyperparametre modelov a v neuroevolúcii, ktorá má v osnove vlastný diel, aj váhy a architektúry neurónových sietí.
- Evolúcia s jazykovými modelmi. Systémy ako FunSearch (2023) a AlphaEvolve (2025) od Google DeepMind udržiavajú populáciu programov a ako mutáciu používajú jazykový model, ktorý program upraví. Výber zaistí automatické hodnotenie. Takto sa podarilo nájsť nové matematické konštrukcie aj rýchlejšie algoritmy.
9. Zhrnutie
- Genetický algoritmus vylepšuje celú populáciu riešení: výberom zdatných, krížením a mutáciou.
- Zdatnosť je jediné, čo o úlohe potrebuje vedieť; porušenie podmienok sa dá riešiť trestom.
- Turnajový výber drží selekčný tlak, elitizmus nedovolí stratiť najlepšie riešenie.
- Na batohu so 16,7 milióna možností našiel optimum v 88 zo 100 behov po ohodnotení 2 440 batohov; náhodné hľadanie s rovnakým rozpočtom ani raz.
- Mutácia dodáva rozmanitosť — bez nej populácia predčasne skonverguje. Kríženie skladá dobré stavebné kamene a evolúciu zrýchľuje.
Chcete si to vyskúšať? Nechajte AI agenta napísať genetický algoritmus pre váš vlastný batoh na výlet — a potom skúste vypnúť mutáciu, zväčšiť turnaj alebo zmenšiť populáciu a sledujte, čo sa stane s rozmanitosťou.
Máte na to iný názor? Napíšte na support@coden-app.com.