Preskočiť na obsah
coden

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.

14 minút Matěj Žalmánek 2026-10-15

Séria Základy AI Diel 27 z 52
  1. Mapa umelej inteligencie: čo je čo a ako to do seba zapadá
  2. Stručná história umelej inteligencie: od Turinga po jazykové modely
  3. Dáta, model, tréning, inferencia: základné pojmy na jednom príklade
  4. Ako čítať matematický zápis: symboly, indexy, sumy a kvantifikátory
  5. Množiny a relácie: stavebnica, z ktorej sa skladajú definície v AI
  6. Funkcie a zobrazenia: prečo je každý model v AI funkcia
  7. Logika a dôkazy: pravidlá, podľa ktorých sa v AI uvažuje
  8. Grafy a stromy: štruktúra, na ktorej stojí hľadanie aj neurónové siete
  9. Lineárna algebra pre strojové učenie: vektory, matice a prečo AI hlavne násobí
  10. Derivácie, gradient a reťazové pravidlo: ako model zistí, ktorým smerom sa učiť
  11. Gradientný zostup: ako sa model učí
  12. Čo je pravdepodobnosť: od hodu kockou ku Kolmogorovovým axiómam
  13. Podmienená pravdepodobnosť a Bayesova veta: ako zmeniť odhad, keď sa dozviete niečo nové
  14. Náhodná premenná a distribučná funkcia: jedna funkcia, ktorá o rozdelení povie všetko
  15. Funkcia hustoty a pravdepodobnostná funkcia: prečo má spojitá premenná v bode pravdepodobnosť nula
  16. Stredná hodnota, rozptyl a kovariancia: kde rozdelenie leží, aké je široké a čo s čím súvisí
  17. Prehľad pravdepodobnostných rozdelení: Bernoulliho, binomické, Poissonovo, rovnomerné, normálne a exponenciálne
  18. Zákon veľkých čísel a centrálna limitná veta: prečo sa priemery správajú tak predvídateľne
  19. Štatistika a odhady parametrov: maximálna vierohodnosť, MAP a intervaly spoľahlivosti
  20. Teória informácie: entropia, krížová entropia a KL divergencia — odkiaľ sa berú stratové funkcie
  21. Prehľadávanie stavového priestoru: BFS, DFS, UCS a A* s animáciami
  22. Hry a protivník: minimax, alfa-beta orezávanie a Monte Carlo tree search
  23. Splňovanie obmedzujúcich podmienok: backtracking, propagácia obmedzení a AC-3 na sudoku a mape krajov
  24. Logika a znalostné systémy: dopredné a spätné reťazenie, rezolúcia a expertné systémy
  25. Plánovanie: STRIPS, svet kociek, heuristiky z relaxácie a plánovanie v AI agentoch
  26. Lokálne hľadanie a simulované žíhanie: obchodný cestujúci cez krajské mestá
  27. Genetické algoritmy: populácia, kríženie, mutácia a výber na batohu na výlet
  28. Evolučné stratégie a genetické programovanie: od pravidla jednej pätiny po Keplerov zákon
  29. Optimalizácia mravčou kolóniou: ako feromónová stopa nájde krátku cestu
  30. Optimalizácia rojom častíc: zotrvačnosť, vlastná skúsenosť a skúsenosť roja
  31. Neuroevolúcia: evolúcia váh aj tvaru neurónových sietí a algoritmus NEAT
  32. Fuzzy množiny a funkcie príslušnosti: ako zapísať „trochu teplo“
  33. Fuzzy logika a pravdepodobnosť: prečo „trochu teplo“ neznamená „pravdepodobne teplo“
  34. Fuzzy logika: t-normy, implikácie a pravidlá AK–TAK
  35. Fuzzy riadenie: Mamdani a Sugeno od ventilátora po kyvadlo na vozíku
  36. Fuzzy zhlukovanie: algoritmus fuzzy c-means a body medzi zhlukmi
  37. Neuro-fuzzy systémy (ANFIS): fuzzy pravidlá, ktoré sa učia z dát
  38. Markovove reťazce: prechodová matica, stacionárne rozdelenie a PageRank
  39. Skryté Markovove modely: Viterbiho algoritmus a nepoctivé kasíno
  40. Bayesovské siete: prečo je tráva mokrá a čo z toho vyplýva pre postrekovač
  41. Kalmanov filter: ako z nepresných meraní odhadnúť, kde auto je a ako rýchlo ide
  42. Druhy strojového učenia: s učiteľom, bez učiteľa, s čiastočným učiteľom a ďalšie
  43. Prompty, kontext a RAG: ako modelu dať správne informácie
  44. Variačné autoenkodéry (VAE): nové obrázky zo spojitého latentného priestoru
  45. Generatívne adversariálne siete (GAN): falšovateľ proti detektívovi
  46. Difúzne modely: ako sa z čistého šumu stane obrázok
  47. Markovove rozhodovacie procesy: stavy, akcie, odmeny a Bellmanove rovnice
  48. Q-learning a DQN: učenie hodnoty akcií od tabuľky po neurónovú sieť
  49. Policy gradient a PPO: učenie priamo stratégie
  50. Ako funguje AI agent: jazykový model v slučke s nástrojmi
  51. Programovanie s AI agentmi: zadanie, testy a kontrola
  52. Vyhodnocovanie a bezpečnosť AI systémov: ako merať a ako strážiť

Celá osnova série Hotovo: 52 z 83 tém

Čo si odnesiete
  • 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.

Laicky povedané

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
Optimálny batoh buď i-tú vec obsahuje, alebo nie — a v oboch prípadoch je zvyšok optimálnym batohom menšej úlohy. Začína sa riadkom T[0][c] = 0.
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:

vecic = 01020304050
žiadna000000
+ čelovka02525252525
+ nôž02543434343
+ varič02543434355
+ karimatka02543434355

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).

  1. 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.
  2. 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.
  3. 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.

Laicky povedané

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ý
Oba prípady z definície v jednom vzorci: trest je nulový, kým sa batoh zmestí, a potom rastie s každým dekagramom navyše.
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):

  1. 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).
  2. 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.

Laicky povedané

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ť
Pravdepodobnosť závisí len od poradia, nie od toho, o koľko je kto lepší — turnaj preto funguje aj so zápornou zdatnosťou, ruleta nie.
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:

  1. S pravdepodobnosťou 1 − pc kríženie neprebehne a potomkovia sú kópie rodičov a a b.
  2. 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.

Laicky povedané

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.

Laicky povedané

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č 1 423 bodov rodič 2 398 bodov potomok 1 403 bodov potomok 2 418 bodov po mutácii 435 bodov
Dva najlepšie batohy počiatočnej populácie, ich potomkovia a mutácia

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.

  1. 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.
  2. Ak je t = G, skonči a vráť jedinca z Pt s najväčšou zdatnosťou.
  3. Do novej generácie Pt+1 skopíruj e najzdatnejších jedincov z Pt bez zmeny (elitizmus).
  4. 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.
  5. 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.

Laicky povedané

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:

optimum generácia 0 423 b. najlepší generácia 5 634 b. najlepší generácia 15 694 b. najlepší generácia 30 727 b. najlepší generácia 60 727 b. najlepší vec v batohu (číslo génu) jedinec (poradie podľa zdatnosti)
Populácia batohov v priebehu evolúcie; oranžovo preťažené

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.

300400500600700 0102030405060 optimum 727 generácia (poradie) zdatnosť (body úžitku)
Zdatnosť po generáciách najlepší priemer populácie najlepší bez mutácie

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:

VariantNašla optimumPriemerný úžitok
Výber + kríženie + mutácia88 zo 100726,6
Výber + mutácia (bez kríženia)70 zo 100725,0
Výber + kríženie (bez mutácie)0 zo 100596,8
Náhodné hľadanie, rovnako pokusov0 zo 100573,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

  1. rád o(H) = |{i : Hi ≠ ∗}| — počet pevných pozícií,
  2. 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.

Laicky povedané

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
Výber schému množí, kríženie a mutácia ju môžu zničiť; odčítanie oboch strát je odhad zdola, pretože rozstrihnutá schéma môže aj znova vzniknúť.
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.

Agent na vašom počítači, ovládaný z telefónu