---
id: wiki-2026-0508-evolutionary-algorithms
title: Evolutionary Algorithms
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [EA, GA, ES, GP, DE, CMA-ES]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
verification_status: applied
tags: [optimization, metaheuristics, evolution, search]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: Python
  framework: DEAP, pycma, scipy.optimize, EvoTorch
---

# Evolutionary Algorithms

## 매 한 줄
> **"매 Darwinian selection + variation 매 search loop 으로 abstract"**. Holland 의 GA (1975), Rechenberg 의 ES (1973), Koza 의 GP (1992) → 매 modern (2026): **CMA-ES, DE, NEAT, EvoTorch GPU population search, LLM-EA hybrids (FunSearch, Eureka)**. 매 derivative-free black-box optimization 의 dominant family.

## 매 핵심

### 매 4 main branches
- **GA (Genetic Algorithm)**: 매 binary / discrete + crossover-heavy.
- **ES (Evolution Strategy)**: 매 real-valued + self-adaptive σ; **CMA-ES** 의 modern apex.
- **GP (Genetic Programming)**: 매 program-tree representation.
- **DE (Differential Evolution)**: 매 vector difference 의 mutation; 매 simplest robust real-valued EA.

### 매 generic loop
```
init population P
evaluate(P)
while budget left:
    parents   = select(P)
    children  = vary(parents)        # crossover + mutation
    evaluate(children)
    P         = replace(P, children) # generational or steady-state
return best
```

### 매 design knobs
- **Representation**: bitstring, real-vector, permutation, tree, graph.
- **Selection**: tournament, roulette, rank, truncation, (μ+λ) vs (μ,λ).
- **Variation**: 1-point/uniform CX, Gaussian/polynomial mutation, DE/best/1/bin.
- **Diversity**: niching, fitness sharing, novelty search, MAP-Elites (QD).
- **Self-adaptation**: σ encoded in genome (ES), CMA covariance update.

## 💻 패턴

### Plain GA from scratch (OneMax)
```python
import random
N, POP, GEN, PMUT = 100, 200, 100, 1/100

def fit(ind): return sum(ind)
def tournament(P, k=3): return max(random.sample(P, k), key=fit)
def cx(a, b):
    p = random.randint(1, N-1)
    return a[:p]+b[p:], b[:p]+a[p:]
def mut(ind):
    return [1-x if random.random() < PMUT else x for x in ind]

P = [[random.randint(0,1) for _ in range(N)] for _ in range(POP)]
for _ in range(GEN):
    Q = []
    while len(Q) < POP:
        a, b = tournament(P), tournament(P)
        c, d = cx(a, b)
        Q += [mut(c), mut(d)]
    P = sorted(P+Q, key=fit, reverse=True)[:POP]
print(fit(P[0]))
```

### CMA-ES (continuous default)
```python
import cma
es = cma.CMAEvolutionStrategy([0]*10, 0.5,
        {"popsize": 30, "maxfevals": 5000, "verbose": -9})
es.optimize(lambda x: sum((xi-3)**2 for xi in x))
print(es.result.xbest)
```

### Differential Evolution (scipy)
```python
from scipy.optimize import differential_evolution
res = differential_evolution(
    lambda x: (1-x[0])**2 + 100*(x[1]-x[0]**2)**2,   # Rosenbrock
    bounds=[(-2,2),(-1,3)], strategy="best1bin",
    popsize=30, mutation=(0.5,1.0), recombination=0.7, tol=1e-8)
```

### Genetic Programming (DEAP, symbolic regression)
```python
from deap import base, creator, gp, tools, algorithms
import operator, random, math

pset = gp.PrimitiveSet("MAIN", 1)
pset.addPrimitive(operator.add, 2); pset.addPrimitive(operator.mul, 2)
pset.addPrimitive(operator.sub, 2); pset.addEphemeralConstant("c", lambda: random.uniform(-1,1))
pset.renameArguments(ARG0="x")

creator.create("Fit", base.Fitness, weights=(-1.0,))
creator.create("Ind", gp.PrimitiveTree, fitness=creator.Fit, pset=pset)
tb = base.Toolbox()
tb.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=3)
tb.register("ind",  tools.initIterate, creator.Ind, tb.expr)
tb.register("pop",  tools.initRepeat, list, tb.ind)
tb.register("compile", gp.compile, pset=pset)

points = [(x, x**3 - 2*x + 1) for x in [i/10 for i in range(-10,10)]]
def evalSR(ind):
    f = tb.compile(ind)
    return (sum((f(x)-y)**2 for x,y in points),)
tb.register("evaluate", evalSR)
tb.register("select", tools.selTournament, tournsize=3)
tb.register("mate", gp.cxOnePoint)
tb.register("mutate", gp.mutUniform, expr=tb.expr, pset=pset)

pop = tb.pop(n=300)
algorithms.eaSimple(pop, tb, 0.7, 0.2, 40, verbose=False)
```

### MAP-Elites (Quality-Diversity)
```python
import numpy as np
grid = {}
def feat(x): return (int(x[0]*10), int(x[1]*10))
def f(x): return -np.sum(x**2)
for _ in range(20_000):
    if grid: parent = grid[random.choice(list(grid))]
    else: parent = np.random.uniform(-1,1,2)
    child = parent + np.random.normal(0, 0.1, 2)
    k = feat(child)
    if k not in grid or f(child) > f(grid[k]): grid[k] = child
```

### LLM-guided EA (FunSearch-style, sketch)
```python
def llm_propose(parent_program: str) -> str:
    return claude.messages.create(
        model="claude-opus-4-7",
        max_tokens=2000,
        messages=[{"role":"user","content":
            f"Improve this program for better fitness:\n{parent_program}"}]
    ).content[0].text

pop = [seed_program]
for _ in range(200):
    parent = max(pop, key=score)
    child  = llm_propose(parent)
    if score(child) > -float("inf"): pop.append(child)
    if len(pop) > 50: pop = sorted(pop, key=score)[-50:]
```

## 매 결정 기준
| 상황 | Approach |
|---|---|
| Continuous, ≤ 100 dim, black-box | **CMA-ES** |
| Continuous, parallel, robust default | **DE** |
| Discrete / combinatorial | **GA + memetic local search** |
| Symbolic regression / program synth | **GP** |
| Need diverse archive of solutions | **MAP-Elites / Novelty Search** |
| Very expensive eval (≤ 100 calls) | Bayesian optimization (not EA) |
| Code / prompt search 2026 | **LLM-EA hybrid (FunSearch / Eureka)** |

**기본값**: 매 continuous → **CMA-ES**; 매 discrete → **memetic GA**; 매 LLM-era code search → **FunSearch-style**.

## 🔗 Graph
- 부모: [[Biological-Inspired-Algorithms]] · [[Optimization]]
- 변형: [[Genetic-Algorithm]] · [[CMA-ES]] · [[NEAT]]
- 응용: [[Neural-Architecture-Search-NAS|Neural-Architecture-Search]] · [[Hyperparameters|Hyperparameter-Optimization]]
- Adjacent: [[Reinforcement-Learning]] · [[Bayesian-Optimization]] · [[Simulated-Annealing]]

## 🤖 LLM 활용
**언제**: 매 black-box, multimodal, non-differentiable; 매 quality-diversity 가 필요; 매 program / prompt 의 search.
**언제 X**: 매 differentiable convex (gradient win), 매 evaluation < 100 calls (BO win).

## ❌ 안티패턴
- **Pure random search 의 EA 라고 부르기**: 매 selection pressure 없으면 매 EA 의 X.
- **Mutation 의 too small/large**: 매 self-adaptive (CMA / 1/5 rule) 의 사용.
- **Single elitist + small pop**: 매 premature convergence.
- **Reinventing GA names** ("Whale", "Grey Wolf", …): 매 academic noise — 매 CMA-ES / DE baseline 의 거의 항상 better.
- **Ignoring restart**: 매 IPOP/BIPOP-CMA 의 multimodal 에 critical.

## 🧪 검증 / 중복
- Verified (Holland 1975; Rechenberg 1973; Koza 1992; Storn & Price 1997 DE; Hansen 2001 CMA-ES; Mouret & Clune 2015 MAP-Elites; Romera-Paredes 2024 FunSearch).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 placeholder |
| 2026-05-10 | Manual cleanup — 4 branches + 6 patterns + LLM-EA |
