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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
//! Genome category trait and its zero-sized marker types.
//!
//! [`GenomeKind`] tags genome representations at the type level so operators
//! can specialize on the element semantics (real-valued, binary, integer,
//! or tree). Strategies take a marker type as a const generic to pick the
//! right operator set.
//!
//! The markers themselves carry no data — they exist purely to discriminate
//! trait impls.
use Debug;
use ;
/// Shape-erased genome kind.
///
/// `GenomeKind` is a zero-sized marker that strategies parameterize on to
/// pick operators. Concrete kinds (`Real`, `Binary`, `Integer`, `Tree`,
/// `Permutation`) live below; new kinds can be added by implementing this
/// trait on a fresh marker type.
///
/// Genome width is a runtime property (`Population::genome_dim`), not a
/// type-level one: every shipping kind is either runtime-dimensioned
/// (`Real`/`Binary`/`Integer`) or variable-length (`Tree`/`Permutation`). A
/// structurally-fixed-width kind could add a compile-time length constant when
/// one is introduced — an associated const with a default is a non-breaking
/// addition.
/// Real-valued genome (each gene is an `f32`).
///
/// Populations are stored as `Tensor<B, 2>` of shape `(pop_size, dim)`.
/// All classical ES variants, real-coded GA, EP, and DE use this kind.
;
/// Binary genome (each gene is a bit, stored as `i32` 0/1 on device).
///
/// Populations are stored as `Tensor<B, 2, Int>` of shape
/// `(pop_size, dim)`. Binary-coded GA uses this kind.
;
/// Integer-valued genome (each gene is a non-negative integer index).
///
/// Populations are stored as `Tensor<B, 2, Int>` of shape
/// `(pop_size, dim)`. Cartesian GP (node indices), discrete parameter
/// search, and other problems where genes are bounded integer values use
/// this kind. For ordered-sequence problems (TSP, QAP) use [`Permutation`]
/// instead.
;
/// Tree-based genome (variable-length AST, stored host-side).
///
/// Reserved for classical Koza-style GP in a future release. Tree
/// genomes cannot be batched on a GPU and therefore have no tensor
/// representation in this crate. The associated `Element` type is `i32`
/// as a placeholder (structural node IDs); the actual in-memory
/// representation will be defined when this kind is fully implemented.
;
/// Permutation genome (each row is a permutation of `0..n_nodes`).
///
/// Rectangular and device-resident: populations are stored as
/// `Tensor<B, 2, Int>` of shape `(pop_size, n_nodes)`, so this kind
/// implements [`TensorGenome`] and `Population<B, Permutation>` type-checks.
/// The permutation invariant (every row is a bijection of `0..n_nodes`) is
/// **not** enforced at construction — [`new_permutation`] validates only
/// shape, matching how `Binary`/`Integer` leave element values unchecked.
///
/// Used by Ant Colony Optimization over combinatorial domains (TSP, QAP, …);
/// only a stubbed consumer ships in this release — the operators are planned
/// for a future release.
///
/// [`new_permutation`]: crate::population::Population::new_permutation
;
/// Genome kinds with a rectangular, device-resident tensor representation.
///
/// This is the subset of [`GenomeKind`]s that a
/// [`Population`](crate::population::Population) can store on-device. The
/// associated [`Tensor`](TensorGenome::Tensor) type names *which* tensor flavour
/// backs the kind, tying the storage type to the marker at compile time: `Real`
/// maps to `Tensor<B, 2>`; `Binary`, `Integer`, and `Permutation` map to
/// `Tensor<B, 2, Int>`.
///
/// Because the storage type is chosen by the trait impl, `Population<B, K>` needs
/// only one field and no run-time tag — the wrong-tensor-for-this-kind state is
/// simply unrepresentable. Variable-length kinds such as [`Tree`] have no
/// rectangular form and deliberately do not implement this trait, so
/// `Population<B, Tree>` is not a valid type.