Working-man's library for genetic algorithms
Project description
Bluegenes
This library is meant to be an easy-to-use library for optimization using genetic algorithms.
Status
- Models + tests
- Optimization functions + tests
- Decent documentation
Overview
The general concept with a genetic algorithm is to evaluate a population for fitness (an arbitrary metric) and use fitness, recombination, and mutation to drive evolution toward a more optimal result. In this simple library, the genetic material is a sequence of ints, floats, or strs, and it is organized into the following hierarchy:
Gene
contains bases (list[int|float|str]
)Allele
containsGene
sChromosome
containsAllele
sGenome
containsChromosome
s
Each of these classes has a str name
attribute to identify the genetic
material. These names can be generated as random alphanumeric strs if not
supplied in the relevant instantiation calls.
There are four optimization functions available currently:
optimize_gene
- optimizes a Geneoptimize_allele
- optimizes an Alleleoptimize_chromosome
- optimizes a Chromosomeoptimize_genome
- optimizes a Genome
These optimization functions have largely similar parameters for tuning the optimization process. See the Usage section below.
For more detailed documentation, see the docs file generated automagically by autodox.
Installation
Installation is with pip.
pip install bluegenes
There are no dependencies.
Usage
There are are least three ways to use this library: using an included optimization function, using a custom optimization function, and using the genetic classes as the basis for an artificial life simulation. Below is a trivial example of how to do the first of these three.
from bluegenes import Gene, optimize_gene, set_hook
from random import randint, random
# optional functionality: set a hook to be passed every generation as it completes
logs = []
def log_generation(count: int, generation: list[tuple[float], Gene]) -> None:
logs.append((count, generation))
set_hook(log_generation)
target = 123456
def measure_fitness(gene: Gene) -> float:
"""Produces a fitness score. Passed as parameter to optimize_gene."""
return 1 / (1 + abs(sum(gene.bases) - target))
def mutate_gene(gene: Gene) -> Gene:
"""Mutates the Gene randomly. Passed as parameter to optimize_gene."""
for i in range(len(gene.bases)):
val = random()
if val <= 0.1:
gene.bases[i] = int(gene.bases[i] / randint(1, 3))
elif val <= 0.2:
gene.bases[i] = int(gene.bases[i] * randint(1, 3))
elif val <= 0.6:
gene.bases[i] += randint(0, 11)
else:
gene.bases[i] -= randint(0, 11)
return gene
count, population = optimize_gene(measure_fitness, mutate_gene)
best = population[0]
score = sum(best.bases)
print(f"{count} generations passed")
print(f"the best result had {score=} compared to {target=}")
print(best)
Creating custom fitness functions or artificial life simulations is left as an exercise to the reader.
Testing
To test, run the following:
for i in {0..10}; do python tests/test_genes.py; done
for i in {0..10}; do python tests/test_optimization.py; done
Note that the randomness may cause some tests to occasionally fail. I halved the change of a random test failure every time one was encountered, but there are by definition no guarantees of deterministic behavior when working with random numbers. In other words, the test suites should each be run a few times, and a random failure or two should be excused. I have tuned it for <1% chance of a random test failure (measured), but it will eventually happen if the tests are run enough times.
ISC License
ISC License
Copyleft (c) 2023 k98kurz
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyleft notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file bluegenes-0.0.3.tar.gz
.
File metadata
- Download URL: bluegenes-0.0.3.tar.gz
- Upload date:
- Size: 18.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 719f4eb0c949fb6f2d071e5ef226015b2d5b493bbc278679cf5010cfb9a0141b |
|
MD5 | 7b57e417dc678aa4fd8ae55fad47bb6b |
|
BLAKE2b-256 | 2dc7677de0c3d37c324bc4444c9954fc24e38f39b8d9e7cc371c3727c5686453 |
File details
Details for the file bluegenes-0.0.3-py3-none-any.whl
.
File metadata
- Download URL: bluegenes-0.0.3-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a1dc3151bc80b857c8e4ba77ef5dfc97e393969da6445a59a7de9606932a6573 |
|
MD5 | c30931425944c9bb71f5fa556ceb8341 |
|
BLAKE2b-256 | f0e39654990c03a98d052a8ea15ce80efcf62f33a91fd3218fe250d265d90d53 |