1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! Co-evolutionary algorithms.
//!
//! Two populations evolve **simultaneously**, and each individual's fitness
//! depends on the *other* population. Two regimes ship in v1:
//!
//! - **Competitive** ([`CompetitiveCoEA`]) — populations are adversaries
//! (predator vs. prey, Hillis 1990). Each is scored by how well it does
//! against the other; the dynamic is an arms race.
//! - **Cooperative** ([`CooperativeCoEA`], CCGA — Potter & De Jong 1994) — a
//! high-dimensional problem is decomposed across populations whose
//! individuals combine (via *representatives*) into a full candidate.
//!
//! # Why not [`Strategy`](crate::strategy::Strategy)?
//!
//! [`Strategy::tell`](crate::strategy::Strategy::tell) accepts a single
//! fitness vector, but co-evolutionary fitness is inherently paired — each
//! population receives a vector computed relative to the other. Rather than
//! distort that contract, co-evolution gets its own [`CoEvolutionaryAlgorithm`]
//! trait and a dedicated [`CoEvolutionaryHarness`] that adapts to the existing
//! `rlevo-core::evaluation::BenchEnv` surface, exactly as
//! [`EvolutionaryHarness`](crate::strategy::EvolutionaryHarness) does. Both
//! co-evolutionary algorithms are built from ordinary inner
//! [`Strategy`](crate::strategy::Strategy) instances, so every phase-1/2/3a/3b
//! algorithm composes in unchanged.
//!
//! # Pathology mitigation
//!
//! Competitive co-evolution is prone to **cycling**; [`HallOfFameFitness`]
//! wraps any [`CoupledFitness`] to anchor scores against an archive of past
//! champions (Rosin & Belew 1997). It composes at construction — algorithms
//! are hall-of-fame-agnostic.
//!
//! # Coupling shape
//!
//! [`CoupledFitness`] takes a slice of populations and is N-population-ready;
//! v1 algorithms always pass exactly two. The harness exposes
//! `min(best_a, best_b)` (canonical maximise) as the benchmark reward (the
//! weaker population — lower canonical fitness — is the binding constraint).
//!
//! # References
//!
//! - Hillis (1990), *Co-evolving parasites improve simulated evolution as an
//! optimization procedure.*
//! - Potter & De Jong (1994), *A cooperative coevolutionary approach to
//! function optimization* (CCGA).
//! - Rosin & Belew (1997), *New methods for competitive coevolution* (hall of
//! fame).
//! - Ficici (2004), *Solution concepts in coevolutionary algorithms* (cycling
//! / intransitive dominance).
pub use ;
pub use ;
pub use CoupledFitness;
pub use ;
pub use ;
use Debug;
use Backend;
use Rng;
/// A co-evolutionary algorithm driving two populations under simultaneous
/// updates.
///
/// The analogue of [`Strategy`](crate::strategy::Strategy) for the coupled
/// case: [`init`](Self::init) builds the joint state and [`step`](Self::step)
/// advances one simultaneous-update generation (both populations `ask` → one
/// [`CoupledFitness`] evaluation → both `tell`). Implementors hold their inner
/// strategies and a [`CoupledFitness`] by value and carry no PRNG state — all
/// randomness flows through the explicit `rng` argument, per the crate's
/// host-RNG convention.
///
/// v1 ships [`CompetitiveCoEA`] and [`CooperativeCoEA`]; Stackelberg
/// (alternating) turn order is deferred.
/// Joined state carrying both sub-strategy states plus per-population
/// best/mean trackers.
///
/// Generic over the two inner strategy *state* types (`StA`, `StB`) rather
/// than the strategies themselves, so it derives [`Clone`]/[`Debug`] without
/// spurious bounds on the strategy types. Used by [`CompetitiveCoEA`];
/// [`CooperativeCoEA`] wraps it in [`CooperativeState`] to add
/// representative archives.