-
Notifications
You must be signed in to change notification settings - Fork 0
Expose remaining unbound Python APIs for evaluation and benchmarking #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2ca6bec
ddc9422
c16ea63
0fc092c
0fe9876
ecc89b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,7 +18,7 @@ For features not yet exposed in the Python bindings, an explicit note is include | |||||||
| | 3 | [Chromosome Representations](#3-chromosome-representations) | ✅ | ✅ (all genome types) | | ||||||||
| | 4 | [Crossover Operators](#4-crossover-operators) | ✅ | ⚠️ 2 factory operators exposed | | ||||||||
| | 5 | [Mutation Operators](#5-mutation-operators) | ✅ | ⚠️ 2 factory operators exposed | | ||||||||
| | 6 | [Selection Operators](#6-selection-operators) | ✅ | ❌ not exposed | | ||||||||
| | 6 | [Selection Operators](#6-selection-operators) | ✅ | ⚠️ helper functions exposed | | ||||||||
| | 7 | [Core GA Run and Results](#7-core-ga-run-and-results) | ✅ | ✅ | | ||||||||
| | 8 | [High-Level Optimizer API](#8-high-level-optimizer-api) | ✅ | ✅ | | ||||||||
| | 9 | [Multi-Objective: NSGA-II](#9-multi-objective-nsga-ii) | ✅ | ✅ (objective-space utils) | | ||||||||
|
|
@@ -31,13 +31,13 @@ For features not yet exposed in the Python bindings, an explicit note is include | |||||||
| | 16 | [Adaptive Operators](#16-adaptive-operators) | ✅ | ✅ | | ||||||||
| | 17 | [Hybrid Optimization](#17-hybrid-optimization) | ✅ | ✅ | | ||||||||
| | 18 | [Constraint Handling](#18-constraint-handling) | ✅ | ✅ | | ||||||||
| | 19 | [Parallel and Distributed Evaluation](#19-parallel-and-distributed-evaluation) | ✅ | ❌ not exposed | | ||||||||
| | 19 | [Parallel and Distributed Evaluation](#19-parallel-and-distributed-evaluation) | ✅ | ✅ (`ParallelEvaluator`, `LocalDistributedExecutor`, `Optimizer.with_threads`) | | ||||||||
| | 20 | [Co-Evolution](#20-co-evolution) | ✅ | ✅ | | ||||||||
| | 21 | [Checkpointing](#21-checkpointing) | ✅ | ✅ | | ||||||||
| | 22 | [Experiment Tracking](#22-experiment-tracking) | ✅ | ✅ | | ||||||||
| | 23 | [Visualization and CSV Export](#23-visualization-and-csv-export) | ✅ | ✅ | | ||||||||
| | 24 | [Plugin Architecture](#24-plugin-architecture) | ✅ | ❌ not exposed | | ||||||||
| | 25 | [Benchmark Suite](#25-benchmark-suite) | ✅ | ❌ not exposed | | ||||||||
| | 25 | [Benchmark Suite](#25-benchmark-suite) | ✅ | ✅ (`BenchmarkConfig`, `GABenchmark`) | | ||||||||
| | 26 | [C API](#26-c-api) | ✅ | N/A (C only) | | ||||||||
| | 27 | [Reproducibility Controls](#27-reproducibility-controls) | ✅ | ✅ | | ||||||||
|
|
||||||||
|
|
@@ -545,10 +545,36 @@ auto& ranked = rs.select(population); | |||||||
|
|
||||||||
| ### 6.2 Python | ||||||||
|
|
||||||||
| > **Not available in Python bindings yet.** | ||||||||
| > Selection operators are not individually exposed to Python. | ||||||||
| > The `ga.GeneticAlgorithm` uses an internal tournament-style selection | ||||||||
| > that cannot be swapped from Python currently. | ||||||||
| Selection strategy classes are still C++-only, but Python now exposes helper | ||||||||
| functions that run the same selection logic over a fitness list and return the | ||||||||
| selected indices: | ||||||||
|
|
||||||||
| - `ga.selection_tournament_indices(fitness, tournament_size=3)` (returns one index) | ||||||||
| - `ga.selection_roulette_indices(fitness, count)` | ||||||||
| - `ga.selection_rank_indices(fitness, count)` | ||||||||
| - `ga.selection_sus_indices(fitness, count)` *(stochastic universal sampling)* | ||||||||
| - `ga.selection_elitism_indices(fitness, elite_count)` | ||||||||
|
|
||||||||
| ```python | ||||||||
| import ga | ||||||||
|
|
||||||||
| fitness = [0.1, 0.8, 0.4, 1.2, 0.6] | ||||||||
|
|
||||||||
| tournament_winner = ga.selection_tournament_indices(fitness, tournament_size=3) | ||||||||
| roulette_picks = ga.selection_roulette_indices(fitness, count=3) | ||||||||
| rank_picks = ga.selection_rank_indices(fitness, count=3) | ||||||||
| sus_picks = ga.selection_sus_indices(fitness, count=3) | ||||||||
| elite_picks = ga.selection_elitism_indices(fitness, elite_count=2) | ||||||||
|
|
||||||||
| print("Tournament winner index:", tournament_winner) | ||||||||
| print("Roulette indices:", roulette_picks) | ||||||||
| print("Rank indices:", rank_picks) | ||||||||
| print("SUS indices:", sus_picks) | ||||||||
| print("Elite indices:", elite_picks) # tends to include the best-fitness entries | ||||||||
| ``` | ||||||||
|
|
||||||||
| > `ga.GeneticAlgorithm` still uses its internal selection pipeline. These helpers | ||||||||
| > are for analysis/custom Python loops where you need direct index selection. | ||||||||
|
|
||||||||
| --- | ||||||||
|
|
||||||||
|
|
@@ -1513,11 +1539,40 @@ int main() { | |||||||
|
|
||||||||
| ### Python | ||||||||
|
|
||||||||
| > **Not available in Python bindings yet.** | ||||||||
| > Parallel and distributed evaluators are implemented in | ||||||||
| > `include/ga/evaluation/` (C++ only). | ||||||||
| > As a workaround, Python's `concurrent.futures` can parallelize fitness calls | ||||||||
| > externally and pass results to a Python-level custom fitness function. | ||||||||
| Python exposes thread-parallel evaluators directly: | ||||||||
|
|
||||||||
| - `ga.ParallelEvaluator(fitness, threads=...)` | ||||||||
| - `ga.LocalDistributedExecutor(evaluator, workers=...)` | ||||||||
| - plus optimizer-level threading via `ga.Optimizer.with_threads(...)` | ||||||||
|
|
||||||||
|
||||||||
| > **Note:** These evaluators invoke a Python callback while holding the GIL, so a pure-Python `fitness` function will not execute CPU-bound work concurrently across threads. For real CPU parallelism, use native code that releases the GIL (e.g. NumPy, Cython), or a process-based executor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The guide says
selection_tournament_indices(...)“returns one index”, but the Python API actually returns a list containing one index (consistent with the other*_indiceshelpers). Please clarify in the documentation (e.g., “returns a list of length 1”) or adjust the API to return anint.