{"id":13438276,"url":"https://github.com/willi-kappler/darwin-rs","last_synced_at":"2025-03-19T18:32:36.181Z","repository":{"id":51448811,"uuid":"48770205","full_name":"willi-kappler/darwin-rs","owner":"willi-kappler","description":"darwin-rs, evolutionary algorithms with rust","archived":false,"fork":false,"pushed_at":"2022-07-11T09:20:36.000Z","size":2803,"stargazers_count":120,"open_issues_count":7,"forks_count":16,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-28T07:10:00.848Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willi-kappler.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-29T22:39:27.000Z","updated_at":"2025-02-19T13:43:58.000Z","dependencies_parsed_at":"2022-08-21T09:10:23.088Z","dependency_job_id":null,"html_url":"https://github.com/willi-kappler/darwin-rs","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willi-kappler%2Fdarwin-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willi-kappler%2Fdarwin-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willi-kappler%2Fdarwin-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willi-kappler%2Fdarwin-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willi-kappler","download_url":"https://codeload.github.com/willi-kappler/darwin-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244483636,"owners_count":20460152,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T03:01:04.200Z","updated_at":"2025-03-19T18:32:35.768Z","avatar_url":"https://github.com/willi-kappler.png","language":"Rust","funding_links":[],"categories":["Libraries","库 Libraries","库","人工智能（Artificial Intelligence）","Machine Learning"],"sub_categories":["Artificial Intelligence","人工智能 Artificial Intelligence","人工智能","遗传算法（Genetic Algorithms）"],"readme":"[![Build Status](https://travis-ci.org/willi-kappler/darwin-rs.svg?branch=master)](https://travis-ci.org/willi-kappler/darwin-rs)\n[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n\n# darwin-rs\nThis library allows you to write evolutionary algorithms (EA) using the [Rust](https://www.rust-lang.org/) programming language.\n\nWritten by Willi Kappler, License: MIT - Version 0.4 (2017.06.26)\n\n**Documentation:** [darwin-rs](https://docs.rs/darwin-rs/0.4.0/darwin_rs/)\n\n![tsp start](tsp_start.png)\n\n![tsp end](tsp_end.png)\n\nThe example folder contains these examples:\n\n- TSP (traveling salesman problem): the classic type of problem for EA (see two pictures above).\n- Sudoku: a sudoku solver using EA.\n- Queens: solving the queens problem with EA. Although not as fast as [this one](https://github.com/reem/rust-n-queens) or [this one](https://github.com/Martin1887/oxigen/tree/master/nqueens-oxigen) ;-)\n- OCR: a simple optical character recognition example. Two strings are drawn (rendered) using a truetype font on a image buffer and then a perfect match representing the drawn text is found.\n\ndarwin-rs uses [semantic versioning](http://semver.org/)\n\n# Usage:\nAdd the following to the Cargo.toml in your project:\n\n```toml\n[dependencies]\ndarwin-rs = \"0.4\"\n```\n\nAnd this in the rust source code of your application:\n\n```rust\nextern crate darwin_rs;\n\nuse darwin_rs::{Individual, SimulationBuilder, Population, PopulationBuilder, SimError};\n```\n\nBasically you have to implement the trait ```Individual``` for your data structure:\n\n```rust\n#[derive(Debug, Clone)]\nstruct MyStruct {\n    text: String\n}\n\nimpl Individual for MyStruct {\n    fn mutate(\u0026mut self) {\n        // Mutate the struct here.\n        ...\n    }\n\n    fn calculate_fitness(\u0026mut self) -\u003e f64 {\n        // Calculate how good the data values are compared to the perfect solution\n        ...\n    }\n\n    fn reset(\u0026mut self) {\n      // Resets all the data for this individual instance.\n      // This is done to avoid getting stuck in a local minimum.\n      ...\n    }\n}\n```\n\nThese three methods are needed:\n\n**mutate(\u0026mut self)**: Mutates the content of the struct.\n\n**calculate_fitness(\u0026mut self) -\u003e f64**: This calculates the fitness value, that is how close is this individual struct instance to the perfect solution ? Lower values means better fit (== less error == smaller distance from the optimum).\n\n**reset(\u0026mut self)**: Resets all the data after a specific number of iteration (see ```reset_limit```), to avoid local minima.\n\nThere is one more method (```new_fittest_found```) but it is optional and the default implementation does nothing.\n\nIf you want to share a large data structure between all the individuals you need ```Arc```, see TSP and OCR examples.\n\nNow you have to create one or more populations that can have different properties:\n\n```rust\n\n// A helper function that creates a vector of individuals of your data structure:\nlet my_pop = make_population(100);\n\nlet population1 = PopulationBuilder::\u003cMyStruct\u003e::new()\n    .set_id(1)\n    .initial_population(\u0026my_pop)\n    .increasing_exp_mutation_rate(1.03)\n    .reset_limit_increment(100)\n    .reset_limit_start(100)\n    .reset_limit_end(1000)\n    .finalize().unwrap();\n\n\nlet population2 = PopulationBuilder::\u003cMyStruct\u003e::new()\n    .set_id(2)\n    .initial_population(\u0026my_pop)\n    .increasing_exp_mutation_rate(1.04)\n    .reset_limit_increment(200)\n    .reset_limit_start(100)\n    .reset_limit_end(2000)\n    .finalize().unwrap();\n\n\n```\n**set_id()**: Sets the population ID. This can be any positive u32 integer. Currently this is only used for internal statistics, for example: which population does have the most fittest individuals ? This may help you to set the correct parameters for your simulations.\n\n**initial_population()**: This method takes a vector of individuals. The best practice is to use a helper function, see examples.\n\n**increasing_exp_mutation_rate()**: Sets the mutation rate for each individual: Use exponential mutation rate.\n\n**reset_limit_increment()**: Increase the reset limit by this amount every time the iteration counter reaches the limit\n\n**reset_limit_start()**: The start value of the reset limit.\n\n**reset_limit_end()**: The end value of the reset limit. If this end value is reached the reset limit is reset to the start value above.\n\nAlternatively you can also put all the populations inside a vector.\n\nAfter that you have to create a new instance of the simulation and provide the settings:\n\n\n```rust\nlet my_builder = SimulationBuilder::\u003cMyStruct\u003e::new()\n    .factor(0.34)\n    .threads(2)\n    .add_population(population1)\n    .add_population(population2)\n    .finalize();\n\n    match my_builder {\n        Err(SimError::EndIterationTooLow) =\u003e println!(\"more than 10 iteratons needed\"),\n        Ok(mut my_simulation) =\u003e {\n            my_simulation.run();\n\n            println!(\"total run time: {} ms\", my_simulation.total_time_in_ms);\n            println!(\"improvement factor: {}\", my_simulation.simulation_result.improvement_factor);\n            println!(\"number of iterations: {}\", my_simulation.simulation_result.iteration_counter);\n\n            my_simulation.print_fitness();\n        }\n    }\n```\n\n\n**factor()**: Sets the termination condition: if the improvement factor is better or equal to this value, the simulation stops.\n\n**threads()**: Number of threads to use for the simulation.\n\n**add_population()**: This adds the previously created population to the simulation.\n\n**finalize()**: Finish setup and do sanity check. Returns ```Ok(Simulation)``` if there are no errors in the configuration.\n\n**add_muliple_populations()**: Allows you to add all the populations inside a vector in one method call.\n\nThen just do a match on the result of ```finalize()``` and call ```simulation.run()``` to start the simulation. After the finishing it, you can access some statistics (```total_time_in_ms```, ```improvement_factor```, ```iteration_counter```) and the populations of course:\n\n```rust\n    for population in my_simulation.habitat {\n      for wrapper in population.population {...}\n    }\n```\n\nEach individual is wrapped inside a ```Wrapper``` struct that contains additional information needed for the simulation: **fitness** and the **number of mutations**.\nSee also the example folder for full working programs.\n\n# Discussion:\n- [Reddit](https://www.reddit.com/r/rust/comments/4nnajh/darwinrs_evolutionary_algorithms_with_rust/)\n- [Rust User Forum](https://users.rust-lang.org/t/darwin-rs-evolutionary-algorithms-with-rust/6188)\n\n# Used crates:\n- [jobsteal](https://github.com/rphmeier/jobsteal): parallelization\n- [error-chain](https://github.com/brson/error-chain): easy error handling\n- [log](https://github.com/rust-lang-nursery/log): use logging mechanism instead of ```println!()```\n\n# Similar crates:\n- [genetic-files](https://github.com/vadixidav/genetic-files)\n- [RsGenetic](https://github.com/m-decoster/RsGenetic)\n- [evo-rs](https://github.com/mneumann/evo-rs)\n- [calco-rs](https://github.com/Kerosene2000/calco-rs)\n- [GenGen](https://crates.io/crates/GenGen)\n- [parasailors](https://github.com/dikaiosune/parasailors)\n- [random-wheel-rs](https://github.com/Kerosene2000/random-wheel-rs)\n- [roulette-wheel-rs](https://github.com/Kerosene2000/roulette-wheel-rs)\n- [differential-evolution-rs](https://github.com/martinus/differential-evolution-rs)\n- [evolve-sbrain](https://github.com/LeoTindall/evolve-sbrain)\n- [Nodevo](https://github.com/bgalvao/nodevo)\n- [Oxigen](https://github.com/Martin1887/oxigen)\n\nAny feedback is welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilli-kappler%2Fdarwin-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilli-kappler%2Fdarwin-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilli-kappler%2Fdarwin-rs/lists"}