You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+13-15Lines changed: 13 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,14 +16,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
16
-**Configurable node gene distance** via `compatibility_include_node_genes` in `[DefaultGenome]`. Default True (current behavior). Set to False for canonical NEAT distance formula. (NEAT paper compliance)
17
17
-**Configurable enabled-state penalty** via `compatibility_enable_penalty` in `[DefaultGenome]`. Default 1.0 (current behavior). Set to 0.0 for canonical NEAT distance formula. (NEAT paper compliance)
18
18
-**Canonical spawn allocation** via `spawn_method = proportional` in `[DefaultReproduction]`. Default `smoothed` (current behavior). (NEAT paper compliance)
19
-
20
-
### Changed
21
-
-**Distance function now matches genes by innovation number**, consistent with crossover behavior. Previously used tuple keys (endpoint pairs). This affects speciation when the same connection endpoints receive different innovation numbers in different generations (uncommon but possible). (NEAT paper compliance)
22
-
-**Dangling nodes are now pruned** after `mutate_delete_node` and `mutate_delete_connection`. Hidden nodes that become disconnected from all outputs are automatically removed along with their connections. This reduces structural bloat in long evolution runs.
23
-
24
-
### Fixed
25
-
-**75% disable rule** now matches the NEAT paper specification (Stanley & Miikkulainen, 2002, p. 111). Previously, the rule was applied after random attribute inheritance, producing an effective ~87.5% disable rate. Now correctly produces 75%. This may affect evolution dynamics in existing configurations.
26
-
27
19
-**GPU-accelerated evaluation** for CTRNN and Izhikevich spiking networks via optional CuPy dependency
28
20
-`GPUCTRNNEvaluator` and `GPUIZNNEvaluator` in `neat.gpu.evaluator`
29
21
- Batch-evaluates entire populations on GPU using padded tensor operations
@@ -32,9 +24,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
32
24
- Requires sum aggregation; other aggregation functions raise `ValueError`
33
25
-`import neat` never loads CuPy; all GPU imports are lazy
34
26
- Benchmark script in `benchmarks/gpu_benchmark.py`
35
-
-See `GPU_DESIGN_NOTES.md` for design rationale
27
+
-GPU comparison examples in `examples/signal-tracking-gpu/` and `examples/spike-timing-gpu/`
36
28
37
29
### Changed
30
+
-**Distance function now matches genes by innovation number**, consistent with crossover behavior. Previously used tuple keys (endpoint pairs). This affects speciation when the same connection endpoints receive different innovation numbers in different generations (uncommon but possible). (NEAT paper compliance)
31
+
-**Dangling nodes are now pruned** after `mutate_delete_node` and `mutate_delete_connection`. Hidden nodes that become disconnected from all outputs are automatically removed along with their connections. This reduces structural bloat in long evolution runs.
38
32
-**CTRNN integration method** changed from forward Euler to exponential Euler (ETD1)
39
33
- Integrates the linear decay term `-y/tau` exactly
40
34
- Unconditionally stable regardless of `dt/tau` ratio (forward Euler required `dt < 2*tau`)
@@ -43,6 +37,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
43
37
to the same continuous solution as `dt` decreases
44
38
- The `time_constant_min_value` constraint is relaxed: values well below the integration
45
39
timestep are now safe
40
+
-**Checkpoint timing moved from `end_generation` to `post_evaluate`**. Checkpoints now save the evaluated population (with fitness values) rather than the unevaluated post-reproduction population. Restoring a checkpoint no longer re-runs the last generation's fitness evaluation. Checkpoint file `N` now means "generation N has been evaluated." Old 5-tuple checkpoint files are still loadable for backward compatibility.
41
+
-**Reporter species output moved from `end_generation` to `post_evaluate`**. The `StdOutReporter` species detail table now appears alongside fitness statistics for the same generation, eliminating the previous mismatch where species sizes from the next generation were printed under the current generation's banner.
42
+
43
+
### Fixed
44
+
-**`fitness_criterion = min` now works correctly**. Previously, only the termination check honored this setting. Best-genome tracking, stagnation detection, elite selection, crossover parent selection, spawn allocation, and statistics reporting all hardcoded "higher is better." All fitness comparisons now use direction-aware methods on the `Config` object (`is_better_fitness`, `meets_threshold`, `worst_fitness`).
45
+
-**75% disable rule** now matches the NEAT paper specification (Stanley & Miikkulainen, 2002, p. 111). Previously, the rule was applied after random attribute inheritance, producing an effective ~87.5% disable rate. Now correctly produces 75%. This may affect evolution dynamics in existing configurations.
46
+
-**Two double-buffer bugs in CTRNN advance method** fixed. Incorrect buffer swapping could cause state corruption during multi-step CTRNN evaluation.
47
+
-**Aggregation validation** for builtins and callables fixed.
46
48
47
49
48
50
## [1.1.0] - 2025-12-05
@@ -91,11 +93,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
91
93
92
94
### Fixed
93
95
-**Add-node mutation bias behavior**: Newly inserted nodes created by `mutate_add_node` now start with zero bias so that splitting a connection is as neutral as possible with respect to the original signal flow. This makes the structural mutation less disruptive while preserving the existing weight-preserving semantics (incoming weight 1.0, outgoing weight equal to the original connection).
94
-
-**Checkpoint Generation Semantics**: Clarified and corrected how checkpoint generation numbers are labeled and interpreted.
95
-
- A checkpoint file named `neat-checkpoint-N` now always contains the population, species state, and RNG state needed to begin evaluating **generation `N`**.
96
-
- Previously, checkpoints were labeled with the index of the generation that had just been evaluated, while storing the *next* generation's population; this could make restored runs appear to "repeat" the previous generation.
97
-
- The NEAT evolution loop and genetic algorithm behavior are unchanged; this is a bookkeeping fix that aligns checkpoint behavior with user expectations and the original NEAT paper's generational model.
98
-
- New and updated tests in `tests/test_checkpoint.py` and `tests/test_population.py` enforce the invariant that checkpoint `N` resumes at the start of generation `N`.
96
+
-**Checkpoint Generation Semantics**: Clarified and corrected how checkpoint generation numbers are labeled and interpreted. (Note: checkpoint timing was further improved in v2.1 to save after evaluation rather than after reproduction, eliminating wasted work on restore.)
99
97
-**Population Size Drift**: Fixed small mismatches between actual population size and configured `pop_size`
100
98
-`DefaultReproduction.reproduce()` now strictly enforces `len(population) == config.pop_size` for every non-extinction generation
101
99
- New `_adjust_spawn_exact` helper adjusts per-species spawn counts after `compute_spawn()` to correct rounding/clamping drift
@@ -131,7 +129,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
131
129
- New `InnovationTracker` class in `neat/innovation.py`
132
130
- Comprehensive unit tests in `tests/test_innovation.py` (19 tests)
133
131
- Integration tests in `tests/test_innovation_integration.py` (6 tests)
134
-
- Innovation tracking documentation in `INNOVATION_TRACKING_IMPLEMENTATION.md`
132
+
- Innovation tracking documentation in `docs/innovation_numbers.rst`
135
133
136
134
### Changed
137
135
-**BREAKING**: `DefaultConnectionGene.__init__()` now requires mandatory `innovation` parameter
Copy file name to clipboardExpand all lines: docs/config_file.rst
+31Lines changed: 31 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -624,6 +624,37 @@ required for your particular implementation.
624
624
The probability that :term:`mutation` will replace the response multiplier of a node with a newly :py:meth:`chosen <attributes.FloatAttribute.init_value>`
625
625
random value (as if it were a new node).
626
626
627
+
.. index:: time_constant
628
+
629
+
* *time_constant_init_mean*
630
+
The mean of the normal/gaussian distribution used to select time constant values for new nodes.
631
+
**Default: 1.0.** Only relevant for CTRNN networks; for feedforward and discrete-time recurrent
632
+
networks this attribute is unused.
633
+
634
+
* *time_constant_init_stdev*
635
+
The standard deviation of the distribution used to select time constant values for new nodes.
636
+
**Default: 0.0** (all new nodes start with the mean value).
637
+
638
+
* *time_constant_max_value*
639
+
The maximum allowed time constant value. **Default: 10.0.**
640
+
641
+
* *time_constant_min_value*
642
+
The minimum allowed time constant value. **Default: 0.01.**
643
+
644
+
* *time_constant_mutate_power*
645
+
The standard deviation of the zero-centered normal/gaussian distribution from which a time constant
646
+
mutation value is drawn. **Default: 0.0** (no mutation).
647
+
648
+
* *time_constant_mutate_rate*
649
+
The probability that mutation will change the time constant of a node by adding a random value.
650
+
**Default: 0.0** (no mutation).
651
+
652
+
* *time_constant_replace_rate*
653
+
The probability that mutation will replace the time constant of a node with a newly chosen random
Copy file name to clipboardExpand all lines: docs/customization.rst
+1-6Lines changed: 1 addition & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -76,13 +76,8 @@ New genome types
76
76
To use a different genome type, you can create a custom class whose interface matches that of
77
77
`DefaultGenome` and pass this as the ``genome_type`` argument to the `Config` constructor. The minimum genome type interface is documented here: :ref:`genome-interface-label`.
# innovation_tracker is saved as part of config.genome_config
257
+
257
258
# Loading
258
259
population = neat.Checkpointer.restore_checkpoint('checkpoint-file')
259
260
# innovation_tracker automatically reconnected to genome_config
@@ -263,7 +264,8 @@ The global counter state is preserved, so innovation numbers continue from where
263
264
Implementation Details
264
265
~~~~~~~~~~~~~~~~~~~~~~
265
266
266
-
For complete implementation details, see ``INNOVATION_TRACKING_IMPLEMENTATION.md`` in the `source repository <https://github.com/CodeReclaimers/neat-python/blob/master/INNOVATION_TRACKING_IMPLEMENTATION.md>`_.
267
+
For complete implementation details, see the ``InnovationTracker`` class in ``neat/innovation.py``
268
+
in the `source repository <https://github.com/CodeReclaimers/neat-python/blob/master/neat/innovation.py>`_.
0 commit comments