An implementation of Genetic Programming in Rust. This one pertains to symbolic regression. This is supposed to become a flexible library and a better implementation of the work of my thesis (which slides are found here)
OK, but what in the world is Genetic Programming?
It's an evolutionary supervised machine learning algorithm. It evolves a population of programs (in this case, a mathematical function) that best maps inputs to outputs.
- to get an overall view of how it works, click here.
Can I get this running out of the box?
Yes you can. I included the yacht dataset so that there is some data to run on. Credited to the UCI repository:
- Lichman, M. (2013). UCI Machine Learning Repository [http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, School of Information and Computer Science.
How to get this running?
After installing Rust on your machine, clone this repo,
cd into it and run the commands. Something like:
git clone https://github.com/bgalvao/nodevo.git cd nodevo cargo build --release cargo run
How to play around?
This describes the currently available functionality, so it's just a preview. In the
main.rs go to
Genetic Programming (GP) (standard)
let ds = Data::new("yacht"); let mut gp = GP::new_gp(ds) .set_pop_size(150) .set_pool_size(5) .set_xo_rate(0.8); gp.init_new_pop(); gp.evolve(100);
Geometric Semantic Genetic Programming (GSGP)
let ds = Data::new("yacht"); let mut gsgp = GP::new_gsgp(ds) .set_pop_size(150) .set_pool_size(5) .set_xo_rate(0.0); gsgp.init_new_pop(); gsgp.evolve(100);
new_gsgp() will initialize, according to the following defaults:
pool_size: 3: how many individuals one is drawing at random from the population for selection for the variation phase.
xo_rate: 0.9: rate of crossover. Rate of mutation is implicitly
1 - xo_rate, and only one type of variation takes place. If you're doing Geometric Semantic GP (i.e.
new_gsgp()) you're recommended to keep this as low as
Parallel and Distributed Genetic Programming
This is a Genetic Programming system that distributes computation over subpopulations. For now only with standard Genetic Programming, and with time, hybrid systems shall be supported as soon as reconstruction of GSGP
Individuals is implemented. First declare the
GP subpopulations that you want to be included:
let ds = Data::new("yacht"); let gp1 = GP::new_gp(ds.clone()) .set_pop_size(50) .set_pool_size(5) .set_xo_rate(0.8); let gp2 = GP::new_gp(ds) .set_pop_size(100) .set_pool_size(5) .set_xo_rate(0.8);
Finally declare a new
Mgp (multi-gp) that takes in the declared subpopulations:
let mut mgp = Mgp::new().add_subpop(gp1) .add_subpop(gp2); mgp.init(); mgp.evolve_in_parallel(3, 30); // evolves two `GP` subpopulations in parallel for 3 turns of 30 generations.
Notes from the author
I just started out programming in Rust and the best way to learn a new programming language is to implement something in it. Since I am mostly acquainted with Genetic Programming and am researching in it, I thought this would be the best way to learn it. That being said, this is a work in progress - with time and knowledge the code will be optimized. Thanks to the community.
The top priorities are opened in the Issues section. However, given that the author has some goals related to his thesis, it is worth pointing out his plan and expectable features here.