TinyverseGP is a community project and we warmly welcome contributions of every kind โ from new GP representations and problem domains to bug fixes, experiments, and documentation.
TinyverseGP is still in its early stages โ every contribution matters. Below are the most impactful areas to get involved in.
Push GP, Stack GP, Gene Expression Programming, Semantic GP, โฆ
Time-series forecasting, combinatorial optimisation, multi-objective problems, โฆ
Crossover, mutation, and selection operators that plug into the existing framework.
Replicate published results, add datasets, or run systematic comparisons.
Unit tests, integration tests, and regression tests to improve reliability.
Docstrings, tutorials, Jupyter notebooks, or improvements to this website.
Open a GitHub issue with a minimal reproducer, or directly submit a fix.
Start a discussion on GitHub or Discord โ we love hearing about new use cases.
# Fork on GitHub first, then:
git clone https://github.com/<your-username>/TinyverseGP.git
cd TinyverseGP
git remote add upstream https://github.com/GPBench/TinyverseGP.git
python3.10 -m venv env
source env/bin/activate # Windows: env\Scripts\activate
pip install -e .[dev]
git checkout -b feature/my-awesome-contribution
# ... make your changes ...
# Run the existing examples to verify nothing is broken
python3 -m examples.symbolic_regression.test_cgp_sr
python3 -m examples.symbolic_regression.test_tgp_sr
# Push and open a Pull Request on GitHub
git push origin feature/my-awesome-contribution
All GP representations live in src/gp/ and inherit from
GPModel defined in src/gp/tinyverse.py.
Follow these steps to add a new one.
Name your file tiny_<X>gp.py where <X> is the
first letter(s) of the representation (e.g., tiny_pgp.py for Push GP).
Place it in src/gp/.
Create dataclasses that inherit from GPConfig and
GPHyperparameters respectively. Add any representation-specific fields.
from dataclasses import dataclass
from src.gp.tinyverse import GPConfig, GPHyperparameters
@dataclass(kw_only=True)
class MyGPConfig(GPConfig):
# add representation-specific config fields here
my_param: int = 10
@dataclass(kw_only=True)
class MyGPHyperparameters(GPHyperparameters):
# add representation-specific hyperparameters here
my_hp: float = 0.1
GPModel subclass
Create a class named Tiny<X>GP (e.g., TinyPGP) that
inherits from GPModel and implements all abstract methods:
| Method | Description |
|---|---|
init_population() |
Initialise the population of individuals. |
evaluate_individual(genome, problem) |
Compute and return the fitness of a single genome. |
pipeline(problem) |
Execute one evolutionary generation (selection โ breeding โ evaluation). |
selection() |
Select an individual from the population (e.g., tournament). |
predict(genome, observation) |
Execute a genome on a single input observation and return the output. |
expression(genome) |
Return a human-readable representation of the evolved program. |
is_valid(genome) |
Return True if the genome is a valid program. |
eval_complexity(genome) |
Return a scalar measure of the genome's complexity. |
src/gp/tiny_cgp.py or src/gp/tiny_tgp.py for
concrete reference implementations.
Add at least one runnable example in examples/symbolic_regression/ (or
another domain) that demonstrates your representation. Update the table in
README.md.
Collaborators.md
Add your name and affiliation to Collaborators.md with a short
description of your contribution. This is required before your PR can be merged.
Problem domains live in src/benchmark/. The interface is defined in
src/gp/problem.py through the abstract Problem class.
Problem subclass
Open src/gp/problem.py and add a new class that inherits from
Problem. The class must implement three methods:
from src.gp.problem import Problem
class MyProblem(Problem):
def is_ideal(self, fitness) -> bool:
"""Return True when the optimal fitness has been reached."""
return fitness == 0.0
def is_better(self, fitness1, fitness2) -> bool:
"""Return True if fitness1 is strictly better than fitness2."""
return fitness1 < fitness2
def evaluate(self, genome, gp_model) -> float:
"""Compute the fitness of genome using gp_model.predict(โฆ)."""
total_error = 0.0
for x, y_true in self.data:
y_pred = gp_model.predict(genome, x)
total_error += abs(y_pred - y_true)
return total_error
Add your benchmark instances in src/benchmark/<domain>/.
If you are wrapping an existing benchmark suite, create a thin interface file
(see srbench.py or lsbench.py for examples).
Provide at least one example per representation in
examples/<domain>/ and list them in README.md.
git fetch upstream
git rebase upstream/main
Add TinyPGP representation,
Fix mutation operator bug in CGP, โฆ).
main branch of
GPBench/TinyverseGP. Fill in the PR template, describing what the
change does and how you tested it.
Collaborators.md in the same PR โ
this is required before your contribution can be merged.
tinyverse.py.
# This file is part of TinyverseGP | https://github.com/GPBench/TinyverseGP
# License: GPL-3.0-or-later
The project uses pytest. Tests live in the
tests/ directory. Before submitting a PR, run the full test suite:
pytest tests/
If you are adding a new representation or feature, please add corresponding tests
in tests/. At minimum:
predict() and expression()
methods return correct types.The best places to ask questions, share ideas, or get feedback before starting a large contribution: