Skip to content

Commit e490940

Browse files
committed
reduce grid by factor 10, to allow for Discrete to be more visible in
effect in examples/visualize_evolve_mutation_types and examples/visualize_permutate_mutation_types
1 parent 5e3622a commit e490940

6 files changed

Lines changed: 43 additions & 36 deletions

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ within a single numeric type `T`.
140140

141141
The library supports various mutation strategies that affect how the genetic
142142
algorithm explores the search space. Random leads to the best results overall.
143-
Random is the default and is supported by all Genotypes.
143+
Random is the default and is supported by all Genotypes.
144144

145145
But for numeric genotypes (RangeGenotype and MultiRangeGenotype) there are
146146
several alternatives. These might converge faster, but are all more sensitive to
@@ -163,9 +163,12 @@ Run the example with `cargo run --example visualize_evolve_mutation_types --rele
163163

164164
### Permutate Strategy
165165

166-
For exhaustive search in smaller spaces, the Permutate strategy can
167-
systematically explore continues genotypes (RangeGenotype and
168-
MultiRangeGenotype) using Step, StepScaled, and Discrete mutation types:
166+
For exhaustive search in smaller spaces, all genotypes have their own
167+
permutation implementation, which systematically explore all value combinations.
168+
169+
But for numeric/continues genotypes (RangeGenotype and MultiRangeGenotype)
170+
permutation is only possible using Step, StepScaled, and Discrete mutation
171+
types (as it needs additional restrictions be become countable):
169172

170173
![Permutate Mutation Types Patterns](examples/visualize_permutate_mutation_types.png)
171174

-27 KB
Loading

examples/visualize_evolve_mutation_types.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use plotters::prelude::*;
33
use std::sync::{Arc, Mutex};
44

55
const SEED_POINT: [f32; 2] = [0.0, 0.0];
6-
const TARGET_POINT: [f32; 2] = [66.666, 77.777];
6+
const TARGET_POINT: [f32; 2] = [6.6666, 7.7777];
77

88
/// Fitness function targeting the point in 2D space
99
#[derive(Clone, Debug)]
@@ -121,13 +121,13 @@ fn run_evolution(
121121
mutation_type_name: String,
122122
max_stale_generations: usize,
123123
) -> ExplorationReporter {
124-
let fitness = TargetPointFitness::new(TARGET_POINT, 0.001);
124+
let fitness = TargetPointFitness::new(TARGET_POINT, 0.0001);
125125
let reporter = ExplorationReporter::new();
126126

127127
// Create genotype with 2 genes for 2D visualization
128128
let genotype = RangeGenotype::<f32>::builder()
129129
.with_genes_size(2)
130-
.with_allele_range(0.0..=100.0)
130+
.with_allele_range(0.0..=10.0)
131131
.with_mutation_type(mutation_type)
132132
.with_seed_genes_list(vec![SEED_POINT.to_vec()]) // Start from origin
133133
.build()
@@ -182,7 +182,7 @@ fn generate_plot(
182182
.margin(10)
183183
.x_label_area_size(30)
184184
.y_label_area_size(30)
185-
.build_cartesian_2d(0f32..100f32, 0f32..100f32)?;
185+
.build_cartesian_2d(0f32..10f32, 0f32..10f32)?;
186186

187187
chart.configure_mesh().draw()?;
188188

@@ -271,7 +271,7 @@ fn main() {
271271
println!("=== Visualizing Evolve Mutation Types in 2D Search Space ===\n");
272272
println!("Starting point: {:?}", SEED_POINT);
273273
println!("Target point: {:?}", TARGET_POINT);
274-
println!("Search space: [0.0, 100.0] x [0.0, 100.0]\n");
274+
println!("Search space: [0.0, 10.0] x [0.0, 10.0]\n");
275275

276276
let mut reporters = Vec::new();
277277

@@ -281,13 +281,13 @@ fn main() {
281281
reporters.push(("Random".to_string(), reporter));
282282

283283
// Range mutation - fixed bandwidth
284-
println!("Running Range(10.0) mutation...");
285-
let reporter = run_evolution(MutationType::Range(10.0), "Range(10.0)".to_string(), 20);
286-
reporters.push(("Range(±10)".to_string(), reporter));
284+
println!("Running Range(1.0) mutation...");
285+
let reporter = run_evolution(MutationType::Range(1.0), "Range(1.0)".to_string(), 20);
286+
reporters.push(("Range(±1.0)".to_string(), reporter));
287287

288288
// RangeScaled mutation - dropping by 1/5th each scale
289289
println!("Running RangeScaled mutation...");
290-
let ranges = vec![100.0, 100.0, 100.0, 90.0, 30.0, 1.0];
290+
let ranges = vec![10.0, 10.0, 10.0, 9.0, 3.0, 0.1];
291291
let reporter = run_evolution(
292292
MutationType::RangeScaled(ranges.clone()),
293293
format!("RangeScaled({:?})", ranges),
@@ -296,13 +296,13 @@ fn main() {
296296
reporters.push(("RangeScaled (slow starting sigmoid)".to_string(), reporter));
297297

298298
// Step mutation - fixed step
299-
println!("Running Step(1.0) mutation...");
300-
let reporter = run_evolution(MutationType::Step(1.0), "Step(1.0)".to_string(), 20);
301-
reporters.push(("Step(±1)".to_string(), reporter));
299+
println!("Running Step(0.3) mutation...");
300+
let reporter = run_evolution(MutationType::Step(0.3), "Step(0.3)".to_string(), 20);
301+
reporters.push(("Step(±0.3)".to_string(), reporter));
302302

303303
// StepScaled mutation - halving each scale
304304
println!("Running StepScaled mutation...");
305-
let steps = vec![50.0, 25.0, 12.5, 6.25, 3.125, 1.5625];
305+
let steps = vec![5.00, 2.50, 1.25, 0.625, 0.3125, 0.15625];
306306
let reporter = run_evolution(
307307
MutationType::StepScaled(steps.clone()),
308308
format!("StepScaled({:?})", steps),
@@ -314,7 +314,7 @@ fn main() {
314314
println!("Running Discrete mutation...");
315315
let reporter = run_evolution(MutationType::Discrete, "Discrete".to_string(), 50);
316316
reporters.push((
317-
"Discrete (floored integers, map to categories)".to_string(),
317+
"Discrete (integers, map to categories)".to_string(),
318318
reporter,
319319
));
320320

-294 KB
Loading

examples/visualize_permutate_mutation_types.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use genetic_algorithm::strategy::permutate::prelude::*;
22
use plotters::prelude::*;
33
use std::sync::{Arc, Mutex};
44

5-
const TARGET_POINT: [f32; 2] = [66.666, 77.777];
5+
const TARGET_POINT: [f32; 2] = [6.6666, 7.7777];
66

77
/// Fitness function targeting the point in 2D space
88
#[derive(Clone, Debug)]
@@ -88,14 +88,14 @@ fn run_permutation(
8888
mutation_type: MutationType<f32>,
8989
mutation_type_name: String,
9090
) -> PermutationReporter {
91-
let fitness = TargetPointFitness::new(TARGET_POINT, 0.001);
91+
let fitness = TargetPointFitness::new(TARGET_POINT, 0.0001);
9292
let reporter = PermutationReporter::new();
9393

9494
// Create genotype with 2 genes for 2D visualization
9595
// Using integer type for discrete steps
9696
let genotype = RangeGenotype::<f32>::builder()
9797
.with_genes_size(2)
98-
.with_allele_range(0.0..=100.0)
98+
.with_allele_range(0.0..=10.0)
9999
.with_mutation_type(mutation_type)
100100
// No seed - let permutation explore the entire space
101101
.build()
@@ -143,7 +143,7 @@ fn generate_plot(
143143
.margin(10)
144144
.x_label_area_size(30)
145145
.y_label_area_size(30)
146-
.build_cartesian_2d(0f32..100f32, 0f32..100f32)?;
146+
.build_cartesian_2d(0f32..10f32, 0f32..10f32)?;
147147

148148
chart.configure_mesh().draw()?;
149149

@@ -220,32 +220,34 @@ fn generate_plot(
220220
fn main() {
221221
println!("=== Visualizing Permutation Mutation Types in 2D Search Space ===\n");
222222
println!("Target point: {:?}", TARGET_POINT);
223-
println!("Search space: [0, 100] x [0, 100] (integer grid)\n");
224-
println!("Note: Permutation systematically explores the entire space as defined by the mutation type.\n");
223+
println!("Search space: [0.0, 10.0] x [0.0, 10.0]\n");
225224

226225
let mut reporters = Vec::new();
227226

228227
// Step mutation - fixed step
229228
// With step=5, this will explore a 20x20 grid (every 5th point)
230-
println!("Running Step(5) mutation with permutation...");
231-
let reporter = run_permutation(MutationType::Step(5.0), "Step(5.0)".to_string());
232-
reporters.push(("Step(±5) Full Grid Exploration".to_string(), reporter));
229+
println!("Running Step(0.3) mutation...");
230+
let reporter = run_permutation(MutationType::Step(0.3), "Step(0.3)".to_string());
231+
reporters.push(("Step(±0.3, full exploration)".to_string(), reporter));
233232

234233
// StepScaled mutation - halving each scale
235234
// This will first explore with large steps, then refine around the best
236-
println!("Running StepScaled mutation with permutation...");
237-
let steps = vec![50.0, 25.0, 12.5, 6.25, 3.125, 1.5625];
235+
println!("Running StepScaled mutation...");
236+
let steps = vec![5.00, 2.50, 1.25, 0.625, 0.3125, 0.15625];
238237
let reporter = run_permutation(
239238
MutationType::StepScaled(steps.clone()),
240239
format!("StepScaled({:?})", steps),
241240
);
242-
reporters.push(("StepScaled Nested Grids".to_string(), reporter));
241+
reporters.push(("StepScaled (nested halving grids)".to_string(), reporter));
243242

244243
// Discrete mutation - like ListGenotype for categories
245244
// This explores a sampled subset of the space
246-
println!("Running Discrete mutation with permutation (limited range for feasibility)...");
245+
println!("Running Discrete mutation...");
247246
let reporter = run_permutation(MutationType::Discrete, "Discrete".to_string());
248-
reporters.push(("Discrete Full Exploration".to_string(), reporter));
247+
reporters.push((
248+
"Discrete (full exploration of integers)".to_string(),
249+
reporter,
250+
));
249251

250252
// Generate visualization
251253
println!("\nGenerating visualization...");
@@ -259,4 +261,3 @@ fn main() {
259261
println!("- Discrete: Jumps to any discrete value in the range");
260262
println!("Color gradient: Blue (early) → Green (late) generations");
261263
}
262-

src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,12 @@
143143
//!
144144
//! ### Permutate Strategy (and HillClimb)
145145
//!
146-
//! For exhaustive search in smaller spaces, the Permutate strategy can
147-
//! systematically explore continues genotypes (RangeGenotype and
148-
//! MultiRangeGenotype) using Step, StepScaled, and Discrete mutation types:
146+
//! For exhaustive search in smaller spaces, all genotypes have their own
147+
//! permutation implementation, which systematically explore all value combinations.
148+
//!
149+
//! But for numeric/continues genotypes (RangeGenotype and MultiRangeGenotype)
150+
//! permutation is only possible using Step, StepScaled, and Discrete mutation
151+
//! types (as it needs additional restrictions be become countable):
149152
//!
150153
//! - **Step**: Systematically explores grid points at fixed intervals
151154
//! - **StepScaled**: Hierarchical search that refines around promising regions

0 commit comments

Comments
 (0)