DarwinGA 1.1.0
dotnet add package DarwinGA --version 1.1.0
NuGet\Install-Package DarwinGA -Version 1.1.0
<PackageReference Include="DarwinGA" Version="1.1.0" />
<PackageVersion Include="DarwinGA" Version="1.1.0" />
<PackageReference Include="DarwinGA" />
paket add DarwinGA --version 1.1.0
#r "nuget: DarwinGA, 1.1.0"
#:package DarwinGA@1.1.0
#addin nuget:?package=DarwinGA&version=1.1.0
#tool nuget:?package=DarwinGA&version=1.1.0
𧬠DarwinGA
A High-Performance Genetic Algorithm Engine for .NET
DarwinGA is a modular, extensible genetic algorithm framework for .NET 8.
Define your problem. Let evolution find the solution.
π Key Differentiator: DarwinGA supports AI-driven initial population creation and AI-driven population crossover, enabling hybrid evolutionary + LLM optimization workflows out of the box.
Author / Contact
- Email:
gerardotous@gmail.com - LinkedIn: https://www.linkedin.com/in/gerardo-tous-vallespir-42491636/
Quick Start Β· Features Β· Operators Β· Examples Β· API Reference
β What Is DarwinGA?
DarwinGA is a genetic algorithm (GA) library that lets you solve optimization problems using the principles of natural evolution: selection, crossover, mutation, and survival of the fittest.
Instead of coding a solver, you describe:
- What a solution looks like (chromosome)
- How to evaluate it (fitness function)
- How it mutates and combines (genetic operators)
The engine evolves a population of candidate solutions across generations until it converges on the best one.
Unlike most .NET GA libraries, DarwinGA can delegate both generation-0 seeding and population-level crossover to AI providers (OpenAI-compatible), combining classic genetic operators with intelligent guidance.
π€ Why DarwinGA Is Different
Most GA frameworks focus only on traditional operators. DarwinGA adds an AI-native evolution flow:
- AI Initial Population Seeding via
PopulationCreator - AI Population Crossover via
IPopulationCrosser/AICrosser - Works with OpenAI-compatible providers (OpenAI, DeepSeek, LM Studio)
- Can be enabled independently (only seeding, only crossover, or both)
This enables faster convergence in many complex search spaces by combining exploration from GA with structured guidance from LLMs.
β¨ Features at a Glance
| Feature | DarwinGA | Other .NET GA libs |
|---|---|---|
| π― Fully generic β evolve any type | β | Partial |
| β‘ Built-in parallel evaluation & breeding | β | β / External |
| 𧬠11 mutation operators (binary) | β | 2β4 typical |
| π 8 crossover operators (binary) | β | 2β3 typical |
| π 7 selection strategies | β | 2β3 typical |
| π Built-in diversity preservation | β | β |
| π§ Age-based selection to prevent stagnation | β | β |
| π² Deterministic seed for reproducible runs | β | Partial |
| πΎ Checkpoint / Resume support | β | Rare |
| π Adaptive mutation/crossover with stagnation tracking | β | Rare |
| π§ Neuroevolution support (ActivationNetwork) | β | β |
| π Generation statistics (avg/min/max/stddev + diversity index) | β | β |
| ποΈ Island Model (multi-population + migration) | β | β |
| β»οΈ Reinsertion strategies (carry elites to next generation) | β | β |
π€ AI initial population seeding (PopulationCreator) |
β | β |
π€ AI population crossover (IPopulationCrosser) |
β | β |
| β CancellationToken support (stop runs safely) | β | β |
| π Extensible via interfaces | β | Partial |
| πͺΆ Lightweight β minimal dependencies | β | Varies |
ποΈ Modern .NET 8 with required properties |
β | Often .NET Standard / Legacy |
π¦ Installation
dotnet add package DarwinGA
Or via the NuGet Package Manager in Visual Studio:
Install-Package DarwinGA
π Quick Start
Three steps to evolve a solution:
1οΈβ£ Define Your Chromosome
Implement IGAEvolutional<T> on any class that represents a candidate solution:
using DarwinGA.Interfaces;
public class PriceSolution : IGAEvolutional<PriceSolution>
{
public double Price { get; set; }
}
2οΈβ£ Implement Mutation and Crossover
public class PriceMutation : IMutation<PriceSolution>
{
public void Apply(PriceSolution evo, double mutationProb)
{
if (MyRandom.NextDouble() < mutationProb)
evo.Price += MyRandom.NextDouble() * 2 - 1;
}
}
public class PriceCrossover : ICross<PriceSolution>
{
public PriceSolution Apply(PriceSolution a, PriceSolution b)
{
return new PriceSolution
{
Price = (a.Price + b.Price) / 2.0
};
}
}
3οΈβ£ Configure and Run
using DarwinGA;
using DarwinGA.Selections;
using DarwinGA.Terminations;
var ga = new GeneticAlgorithm<PriceSolution>
{
PopulationCreator = size => Enumerable.Range(0, size)
.Select(_ => new PriceSolution { Price = MyRandom.NextDouble() * 100 })
.ToList(),
Fitness = solution =>
{
double demand = 100 - solution.Price;
return solution.Price * demand; // maximize profit
},
Mutation = new PriceMutation(),
Cross = new PriceCrossover(),
MutationProbability = 0.05,
Selection = new TournamentSelection(tournamentSize: 5),
Termination = new GenerationNumTermination(maxGenerations: 300),
OnNewGeneration = result =>
{
Console.WriteLine($"Gen {result.GenerationNum}: Best Fitness = {result.BestFitness:F2}");
}
};
ga.Run(populationSize: 100);
That's it. The algorithm handles the rest.
π€ AI: Initial Population + Population Crossover
DarwinGA permite integrar IA en dos puntos clave del ciclo evolutivo:
- CreaciΓ³n de poblaciΓ³n inicial por IA
- Asigna
PopulationCreatorpara generar la generaciΓ³n 0 con un proveedor IA.
- Asigna
- Crossover de poblaciΓ³n por IA
- Asigna
PopulationCrosser(por ejemploAICrosser) para generar descendencia a nivel de poblaciΓ³n.
- Asigna
Ejemplo conceptual:
using DarwinGA;
using DarwinGA.AI;
using DarwinGA.Evolutionals.BinaryEvolutional;
using DarwinGA.Evolutionals.BinaryEvolutional.Crossers;
var ga = new GeneticAlgorithm<BinaryEvolutional>
{
PopulationCreator = size =>
{
// Crear poblaciΓ³n inicial (puede ser IA + fallback aleatorio)
return CreateInitialPopulationWithAI(size);
},
PopulationCrosser = new AICrosser(
aiProvider,
populationSize,
serializePopulation,
deserializePopulation,
systemMessage: "You are an expert GA crossover operator"
),
// Si usas PopulationCrosser para el cruce principal, Cross puede quedar en null
Cross = null,
Fitness = EvaluateFitness,
Mutation = mutation,
Selection = selection,
Termination = termination,
OnNewGeneration = _ => { }
};
ga.Run(populationSize);
En DarwinGA.Example, este flujo ya estΓ‘ integrado para activar de forma independiente:
- Use AI for initial population creation? (y/N)
- Use AI for crossover? (y/N)
π§° Built-in Operators
π Selection Strategies (7)
Choose how parents are picked for breeding:
| Strategy | Class | Description |
|---|---|---|
| Tournament | TournamentSelection |
Picks the best of k random contenders. Good general-purpose default. |
| Elite | EliteSelecction |
Takes the top fraction by fitness deterministically. |
| Roulette Wheel | RouletteWheelSelection |
Probability proportional to fitness value. |
| Rank | RankSelection |
Probability proportional to rank, not raw fitness. Avoids super-fit dominance. |
| Truncation | TruncationSelection |
Deterministically takes the top N%. Simple and fast. |
| Stochastic Universal Sampling | StochasticUniversalSamplingSelection |
Evenly-spaced pointers over the fitness distribution. Less bias than roulette. |
| Age-Based (decorator) | AgeBasedSelection |
Wraps any selection and penalizes individuals that survive too many generations. |
// Tournament selection keeping top 50% via 5-way tournaments
Selection = new TournamentSelection(tournamentSize: 5, selectionFraction: 0.5)
// Age-based on top of tournament (5% penalty per generation)
EnableAgeBasedSelection = true,
AgePenaltyFactor = 0.05,
Selection = new TournamentSelection(5)
𧬠Mutation Operators β Binary (11)
Control how chromosomes are randomly altered:
| Mutation | Class | Behavior |
|---|---|---|
| Random | RandomMutation |
Flips each bit independently with given probability. |
| K-Flip | KFlipMutation |
Flips exactly k random bits. |
| Block Flip | BlockFlipMutation |
Flips a contiguous block of bits. |
| Multi-Block Flip | MultiBlockFlipMutation |
Flips multiple random contiguous blocks. |
| Bit Mask | BitMaskMutation |
Applies a random bitmask to flip bits. |
| Geometric Block | GeometricBlockMutation |
Block size sampled from a geometric distribution. |
| Non-Uniform | NonUniformMutation |
Mutation intensity decreases over time. |
| Run Flip | RunFlipMutation |
Flips a run of consecutive identical bits. |
| Scramble | ScrambleMutation |
Shuffles the order of bits in a random segment. |
| Shift Rotation | ShiftRotationMutation |
Rotates (shifts) a segment of the chromosome. |
| Swap Pairs | SwapPairsMutation |
Swaps values of randomly chosen pairs of genes. |
π Crossover Operators β Binary (8)
Define how two parents produce offspring:
| Crossover | Class | Behavior |
|---|---|---|
| One-Point | OnePointCross |
Single cut point; left from parent A, right from parent B. |
| Two-Point | TwoPointCross |
Two cut points; middle segment swapped. |
| N-Point | NPointCross |
Generalized n cut points. |
| Uniform | UniformCross |
Each gene chosen from either parent with a given probability. |
| Arithmetic | ArithmeticCross |
Weighted average of parent gene values. |
| HUX (Half-Uniform) | HUXCross |
Swaps exactly half of the differing bits. |
| Partial | PartialCross |
Crosses a partial random segment. |
| Segment Swap | SegmentSwapCross |
Swaps a random contiguous segment between parents. |
π Termination Conditions (2)
Stop evolution when a condition is met:
| Condition | Class | Description |
|---|---|---|
| Generation Limit | GenerationNumTermination |
Stops after N generations. |
| Fitness Threshold | FitnessThresholdTermination |
Stops when fitness reaches a target value. |
// Stop after 500 generations
Termination = new GenerationNumTermination(500)
// Stop when fitness >= 0.98
Termination = new FitnessThresholdTermination(0.98)
β»οΈ Reinsertion Strategies (1)
Control which individuals from the current generation survive directly into the next (elitism):
| Strategy | Class | Description |
|---|---|---|
| Best | ReinsertBest<T> |
Carries the top N fittest individuals unchanged into the next generation. |
// Keep the single best individual across generations (default)
Reinsert = new ReinsertBest<MyChromosome>(count: 1)
// Keep the top 3 elites
Reinsert = new ReinsertBest<MyChromosome>(count: 3)
Reinsertion prevents the best solution found so far from being lost to random variation. When Reinsert is set, the survivors it returns are injected at the start of the next population before breeding fills the rest.
You can define custom strategies by implementing IReinsert<T>:
public interface IReinsert<T> where T : IGAEvolutional<T>
{
T[] GetSurvivors(FitnessResult[] elites);
}
π Diversity Preservation
Prevent premature convergence by penalizing similar individuals:
EnableDiversity = true,
// Define how to measure distance between two individuals
DiversityMetric = new DelegateDiversityMetric<MyChromosome>(
(a, b) => /* return a double representing distance */
),
// Penalize fitness of similar individuals (higher factor = stronger penalty)
DiversityStrategy = new SimilarityPenaltyStrategy<MyChromosome>(penaltyFactor: 0.5)
You can also implement IDiversityMetric<T> and IDiversityStrategy<T> for custom behavior.
β‘ Parallel Processing
Speed up evolution on multi-core machines:
// Evaluate fitness in parallel across the population
EnableParallelEvaluation = true,
// Breed children in parallel
EnableParallelBreeding = true,
// Optionally configure parallelism limits
ParallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 8 }
π² Reproducibility, Adaptive Rates, and Checkpoints
Use a fixed seed for deterministic runs (recommended with parallel modes disabled):
RandomSeed = 12345,
Enable adaptive mutation/crossover when fitness stagnates:
EnableAdaptiveRates = true,
// Starts increasing mutation / decreasing crossover after N stagnant generations
StagnationThreshold = 10,
AdaptiveMutationStep = 0.01,
AdaptiveCrossoverStep = 0.02,
AdaptiveMutationMin = 0.001,
AdaptiveMutationMax = 0.5,
AdaptiveCrossoverMin = 0.2,
AdaptiveCrossoverMax = 1.0,
During OnNewGeneration, each GenerationResult<T> now includes:
MutationProbabilityCrossoverProbabilityStagnationGenerations
Checkpoint and resume a run:
var ga = new GeneticAlgorithm<MyChromosome>
{
// ... required setup ...
};
ga.Run(populationSize: 100);
// Save in-memory snapshot (population + generation + adaptive state)
var checkpoint = ga.CreateCheckpoint();
// Later, continue from the same checkpoint
ga.Run(checkpoint);
For deep-copy checkpoints, provide a clone function:
CloneElement = x => /* return a deep copy of x */
π§ Neuroevolution Support
DarwinGA includes built-in support for evolving neural networks via ActivationNetworkEvolutional:
using DarwinGA.Evolutionals.ActivationNetworkEvolutional;
var ga = new GeneticAlgorithm<ActivationNetworkEvolutional>
{
NewItem = () => new ActivationNetworkEvolutional(
neuronsCount: new[] { 5, 3, 1 },
inputsCount: 4
),
Fitness = individual =>
{
// Evaluate the neural network on your dataset
double[] output = individual.NeuralNetwork.Compute(inputData);
return CalculateAccuracy(output, expected);
},
Mutation = new ActivationNetworkMutation(),
Cross = new ActivationNetworkCrossover(),
Selection = new TournamentSelection(5),
Termination = new GenerationNumTermination(1000),
OnNewGeneration = r =>
Console.WriteLine($"Gen {r.GenerationNum}: {r.BestFitness:F4}")
};
ga.Run(populationSize: 50);
Evolve neural network topologies and weights without backpropagation β ideal for reinforcement learning, game AI, and control systems.
π Full Example
The 0/1 Knapsack problem: choose a subset of items to maximize total value without exceeding a weight capacity.
using DarwinGA;
using DarwinGA.Diversity;
using DarwinGA.Evolutionals.BinaryEvolutional;
using DarwinGA.Evolutionals.BinaryEvolutional.Crossers;
using DarwinGA.Evolutionals.BinaryEvolutional.Mutations;
using DarwinGA.Selections;
using DarwinGA.Terminations;
var items = new (int weight, double value)[]
{
(12, 60), (7, 34), (11, 55), (8, 40),
(9, 42), (6, 30), (13, 70), (5, 25)
};
int capacity = 30;
var ga = new GeneticAlgorithm<BinaryEvolutional>()
{
PopulationCreator = size =>
{
var population = new List<BinaryEvolutional>(size);
for (int p = 0; p < size; p++)
{
var chr = new BinaryEvolutional(items.Length);
for (int i = 0; i < items.Length; i++)
chr.SetGen(i, MyRandom.NextDouble() < 0.5);
population.Add(chr);
}
return population;
},
Fitness = individual =>
{
int w = 0;
double v = 0;
for (int i = 0; i < individual.Size; i++)
{
if (!individual.GetGen(i)) continue;
w += items[i].weight;
v += items[i].value;
}
if (w <= capacity) return v;
int extra = w - capacity;
return v - (extra * extra * 5.0); // penalty
},
MutationProbability = 0.10,
Mutation = new KFlipMutation(2),
Cross = new UniformCross(0.5),
Selection = new TournamentSelection(8),
Termination = new FitnessThresholdTermination(0.98),
EnableParallelEvaluation = true,
EnableDiversity = true,
DiversityMetric = new DelegateDiversityMetric<BinaryEvolutional>((a, b) =>
{
int diff = 0;
for (int i = 0; i < a.Size; i++)
if (a.GetGen(i) != b.GetGen(i)) diff++;
return diff;
}),
DiversityStrategy = new SimilarityPenaltyStrategy<BinaryEvolutional>(penaltyFactor: 0.6),
OnNewGeneration = result =>
{
Console.WriteLine(
$"Gen {result.GenerationNum,-4} | Best: {result.BestFitness:F2} | Avg: {result.AverageFitness:F2} | Div: {result.DiversityIndex:F2}");
}
};
ga.Run(populationSize: 120);
π API Reference
GeneticAlgorithm<T> β Main Engine
| Property | Type | Description |
|---|---|---|
PopulationCreator |
Func<int, List<T>> |
Creates the full initial population (can be random, heuristic, or AI-generated). Required. |
Fitness |
Func<T, double> |
Evaluates how good a solution is. Higher = better. Required. |
Mutation |
IMutation<T> |
Mutation operator. Required. |
Cross |
ICross<T>? |
Pairwise crossover operator. Required unless PopulationCrosser is configured. |
PopulationCrosser |
IPopulationCrosser<T>? |
Optional population-level crossover strategy (ideal for AI-guided crossover). |
Selection |
ISelection |
Parent selection strategy. Required. |
Termination |
ITermination |
When to stop evolving. Required. |
OnNewGeneration |
Action<GenerationResult<T>> |
Callback invoked after each generation. Required. |
Reinsert |
IReinsert<T>? |
Reinsertion strategy. Survivors are carried unchanged into the next generation. Optional. |
MutationProbability |
double |
Probability of mutating each child. Default: 0.01. |
CrossoverProbability |
double |
Probability of applying crossover when creating a child. Default: 1.0. |
RandomSeed |
int? |
Fixed seed for reproducible runs. |
CloneElement |
Func<T, T>? |
Optional clone function for deep-copy checkpoints and non-crossover fallback. |
EnableParallelEvaluation |
bool |
Evaluate fitness in parallel. Default: false. |
EnableParallelBreeding |
bool |
Breed children in parallel. Default: false. |
ParallelOptions |
ParallelOptions |
Configure parallelism (e.g. max threads). |
EnableDiversity |
bool |
Enable diversity preservation. Default: false. |
DiversityMetric |
IDiversityMetric<T>? |
Distance function between individuals. |
DiversityStrategy |
IDiversityStrategy<T>? |
Strategy to adjust fitness based on diversity. |
EnableAgeBasedSelection |
bool |
Penalize long-lived individuals. Default: false. |
AgePenaltyFactor |
double |
Fitness penalty per generation of age. Default: 0.05. |
EnableAdaptiveRates |
bool |
Enable adaptive mutation/crossover. Default: false. |
StagnationThreshold |
int |
Stagnant generations before adaptive pressure is applied. Default: 10. |
AdaptiveMutationStep |
double |
Step used to increase/decrease mutation probability. |
AdaptiveCrossoverStep |
double |
Step used to increase/decrease crossover probability. |
AdaptiveMutationMin/Max |
double |
Mutation bounds while adapting. |
AdaptiveCrossoverMin/Max |
double |
Crossover bounds while adapting. |
LastCheckpoint |
GeneticAlgorithmCheckpoint<T>? |
Last available in-memory checkpoint snapshot. |
Main Methods
| Method | Description |
|---|---|
Run(int populationSize) |
Starts a new evolution run. |
Run(int populationSize, CancellationToken) |
Starts a new evolution run with cancellation support. |
Run(GeneticAlgorithmCheckpoint<T> checkpoint) |
Resumes from a checkpoint. |
Run(GeneticAlgorithmCheckpoint<T> checkpoint, CancellationToken) |
Resumes from a checkpoint with cancellation support. |
CreateCheckpoint() |
Returns a snapshot of the latest resumable state. |
Key Interfaces
| Interface | Purpose |
|---|---|
IGAEvolutional<T> |
Marker for any evolvable type (your chromosome). |
IMutation<T> |
void Apply(T evo, double mutationProb) β mutate an individual. |
ICross<T> |
T Apply(T a, T b) β produce a child from two parents. |
IPopulationCrosser<T> |
List<T> CrossPopulation(List<T> parents) β generate offspring from the selected parent population. |
ISelection |
IEnumerable<FitnessResult> Select(...) β choose parents from the population. |
ITermination |
bool ShouldTerminate(GenerationResultBase result) β stop condition. |
IDiversityMetric<T> |
double Distance(T a, T b) β measure distance between individuals. |
IDiversityStrategy<T> |
Adjust fitness scores to reward diversity. |
IReinsert<T> |
T[] GetSurvivors(FitnessResult[] elites) β select individuals to carry unchanged into the next generation. |
π§ How to Think in Evolutionary Terms
Instead of asking:
β "How do I solve this problem?"
Ask:
β "What does a solution look like?" β Define your chromosome
β "How do I measure if it's good?" β Write a fitness function
β "How can I slightly modify it?" β Choose mutation & crossover operators
The algorithm handles the rest.
π‘ Tips for Good Results
| β Do | β Avoid |
|---|---|
| Design a meaningful fitness function | Fitness too flat β no evolutionary pressure |
| Use a representation that can evolve smoothly | Mutation too aggressive β chaotic search |
| Enable diversity for complex landscapes | No diversity β premature convergence |
| Tune mutation probability (start ~0.01β0.10) | Overfitting to a single test case |
| Try different selection strategies | Using only elitism (loses diversity) |
π₯ Use Case Ideas
DarwinGA can optimize any problem you can encode as a chromosome:
| Domain | Example |
|---|---|
| π° Pricing | Find the price that maximizes profit |
| π¦ Logistics | Optimize warehouse placement or bin packing |
| π Routing | Evolve delivery routes (TSP variants) |
| π§ Neuroevolution | Evolve neural network weights for game AI |
| π― Strategy | Optimize game strategies or decision trees |
| π Feature Selection | Select the best subset of features for ML models |
| ποΈ Scheduling | Job-shop scheduling, resource allocation |
| π§ Parameter Tuning | Hyperparameter optimization for any system |
π€ Contributing
Contributions are welcome! Feel free to open issues or submit pull requests.
π Repository: https://github.com/G3r4rd00/DarwinGA
π« Contact
- Email:
gerardotous@gmail.com - LinkedIn: https://www.linkedin.com/in/gerardo-tous-vallespir-42491636/
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
π License
This project is licensed under the MIT License.
<div align="center">
Made with 𧬠by Gerardo Tous
If DarwinGA helped your project, consider giving it a β on GitHub!
</div>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Accord.Neuro (>= 3.8.0)
- Accord.Statistics (>= 3.8.0)
- DeepSeek.NET (>= 1.2.0)
- OpenAI (>= 2.10.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Island model (Ring/Random), generation statistics (avg/min/max/stddev + diversity index), CancellationToken support, and improved examples & tests.