SkillAgentSearch skills...

OpenGeneticAlgorithm.NET

An extensible .NET genetic algorithm library for optimization and artificial intelligence - Evolutionary computation and complex problem solving made simple

Install / Use

/learn @asarnaout/OpenGeneticAlgorithm.NET

README

OpenGA.Net logo

🧬 OpenGeneticAlgorithm.NET

License: MIT .NET NuGet Downloads

The most intuitive, powerful, and extensible genetic algorithm framework for .NET

OpenGA.Net is a high-performance, type-safe genetic algorithm library that makes evolutionary computation accessible to everyone. Whether you're solving complex optimization problems, researching machine learning, or just getting started with genetic algorithms, OpenGA.Net provides the tools you need with an elegant, fluent API.


🚀 Quick Start

Installation

dotnet add package OpenGA.Net

Your First Genetic Algorithm

A Chromosome in OpenGA.Net represents a potential solution to your optimization problem. It contains genes (the solution components) and defines how to evaluate, modify, and repair solutions.

Step 1: Create your chromosome by inheriting from the Chromosome<T> abstract class, the example below demonstrates how a Chromosome representing a potential solution to the traveling salesman problem could look like:

using OpenGA.Net;

// A chromosome for the Traveling Salesman Problem. Each chromosome represents a route through cities (genes = city sequence)
public class TspChromosome(IList<int> cities, double[,] distanceMatrix) : Chromosome<int>(cities)
{
    // Calculate how "good" this route is (shorter distance = higher fitness)
    public override async Task<double> CalculateFitnessAsync()
    {
        double totalDistance = CalculateTotalDistance();
        
        return 1.0 / (1.0 + totalDistance);
    }
    
    // Randomly swap two cities in the route
    public override async Task MutateAsync(Random random)
    {
        int index1 = random.Next(Genes.Count);
        int index2 = random.Next(Genes.Count);
        (Genes[index1], Genes[index2]) = (Genes[index2], Genes[index1]);
    }
    
    public override async Task<Chromosome<int>> DeepCopyAsync()
    {
        return new TspChromosome(new List<int>(Genes), distanceMatrix);
    }
    
    public override async Task GeneticRepairAsync()
    {
        // Ensure each city appears exactly once (fix any duplicates)
    }
}

Step 2: Create your initial population:

// Generate initial population of random routes. The initial population represents a set of random solutions to the optimization problem.
var initialPopulation = new TspChromosome[100];
for (int i = 0; i < 100; i++)
{
    var cities = Enumerable.Range(0, numberOfCities).OrderBy(x => _random.Next()).ToList();
    initialPopulation[i] = new TspChromosome(cities, _distanceMatrix);
}

Step 3: Configure and run your genetic algorithm:

// Configure and run your genetic algorithm
var bestSolution = await OpenGARunner<int>
    .Initialize(initialPopulation)
    .RunToCompletionAsync();

// Get your optimized result
Console.WriteLine($"Best route: {string.Join(" → ", bestSolution.Genes)}");

That's it! 🎉 You just solved an optimization problem with a few lines of code.


🏗️ Architecture Overview

OpenGA.Net is built around four core concepts that work together seamlessly:

🧬 Chromosomes

Your solution candidates. Strongly typed and extensible. Each Chromosome<T> subclass defines how a solution is represented and evaluated. Implement:

  • CalculateFitnessAsync() — return a higher-is-better score for the current Genes
  • MutateAsync() — randomly perturb Genes to explore the search space
  • DeepCopyAsync() — produce a full copy used during crossover
  • GeneticRepairAsync() (optional) — fix invalid states after crossover/mutation

Tip: See the TSP chromosome in the Quick Start above for a concrete example. The pattern is the same for any problem: choose a gene representation, define a fitness function, add a simple mutation, and optionally repair to enforce constraints.

🎯 Parent Selection Strategies

Choose the chromosomes that will participate in mating/crossover:

| Strategy | When to Use | Problem Characteristics | Population Size | Fitness Landscape | |----------|-------------|------------------------|-----------------|-------------------| | Tournament (Default) | Default choice for most problems | Balanced exploration/exploitation needed | Any size | Noisy or multimodal landscapes | | Elitist | Need guaranteed convergence | High-quality solutions must be preserved | Medium to large (50+) | Clear fitness hierarchy | | Roulette Wheel | Fitness-proportionate diversity | Wide fitness range, avoid premature convergence | Large (100+) | Smooth, unimodal landscapes | | Boltzmann | Dynamic selection pressure | Need cooling schedule control | Medium to large | Complex, deceptive landscapes | | Rank Selection | Prevent fitness scaling issues | Similar fitness values across population | Any size | Flat or highly scaled fitness | | Random | Maximum diversity exploration | Early stages or highly exploratory search | Any size | Unknown or chaotic landscapes |

🧬 Crossover Strategies

Create offspring by combining parent chromosomes:

| Strategy | When to Use | Gene Representation | Problem Type | Preservation Needs | |----------|-------------|-------------------|--------------|-------------------| | One-Point (Default) | Fast, simple problems | Order doesn't matter critically | Optimization with independent variables | Preserve some gene clusters | | K-Point | Moderate complexity balance | Mixed dependencies between genes | Multi-dimensional optimization | Control disruption level | | Uniform | Maximum genetic diversity | Independent genes | Exploratory search, avoid local optima | No specific gene clustering | | Custom | Domain-specific requirements | Complex constraints or structures | Specialized problem domains | Domain-specific validation |

🔄 Survivor Selection Strategies

Manage population evolution over generations:

| Strategy | When to Use | Convergence Speed | Population Diversity | Resource Constraints | |----------|-------------|-------------------|---------------------|---------------------| | Elitist (Default) | Most optimization problems | Fast convergence | Moderate diversity loss | Low computational overhead | | Generational | Exploration-heavy search | Slower, thorough exploration | High diversity maintained | Higher memory usage | | Tournament | Balanced performance | Moderate convergence | Good diversity balance | Moderate computational cost | | Age-based | Long-running evolutionary systems | Very slow, stable | Excellent long-term diversity | Requires age tracking | | Boltzmann | Temperature-controlled evolution | Adaptive convergence | Dynamic diversity control | Higher computational complexity | | Random Elimination | Maintain population diversity | Slowest convergence | Maximum diversity | Minimal computational overhead |

🏁 Termination Strategies

Control when the genetic algorithm stops evolving:

| Strategy | When to Use | Stopping Condition | Best For | Predictability | |----------|-------------|-------------------|----------|----------------| | Maximum Epochs (Default) | Known iteration limits | Fixed number of generations | Time-constrained scenarios | Highly predictable runtime | | Maximum Duration | Real-time applications | Maximum execution duration | Production systems | Predictable time bounds | | Target Standard Deviation | Diversity monitoring | Low population diversity | Avoiding premature convergence | Adaptive stopping | | Target Fitness | Goal-oriented optimization | Specific fitness threshold reached | Known optimal solution value | Adaptive based on performance |

💡 Strategy Selection Examples

// High-performance optimization (fast convergence needed)
.ParentSelection(c => c.RegisterSingle(s => s.Tournament()))
.Crossover(c => c.RegisterSingle(s => s.OnePointCrossover()))
.SurvivorSelection(r => r.RegisterSingle(s => s.Elitist()))
.Termination(t => t.MaximumEpochs(100))

// Exploratory search (avoiding local optima)
.ParentSelection(c => c.RegisterSingle(s => s.Tournament()))
.Crossover(c => c.RegisterSingle(s => s.UniformCrossover()))
.SurvivorSelection(r => r.RegisterSingle(s => s.Generational()))
.Termination(t => t.TargetStandardDeviation(stdDev: 0.001))

// Production system (time-constrained)
.ParentSelection(c => c.RegisterSingle(s => s.Tournament()))
.Crossover(c => c.RegisterSingle(s => s.OnePointCrossover()))
.SurvivorSelection(r => r.RegisterSingle(s => s.Elitist()))
.Termination(t => t.MaximumDuration(TimeSpan.FromMinutes(5)))

// Quality-focused research (target fitness termination)
.ParentSelection(c => c.RegisterSingle(s => s.RouletteWheel()))
.Crossover(c => c.RegisterSingle(s => s.KPointCrossover(3)))
.SurvivorSelection(r => r.RegisterSingle(s => s.Elitist(0.2f)))
.Termination(t => t.TargetFitness(0.95).TargetStandardDeviation(stdDev: 0.001, window: 10))

🎯 Use Cases

🏭 Optimization Problems

  • Scheduling: Job shop, vehicle routing, resource allocation
  • Engineering Design: Antenna design, circuit optimization, structural engineering
  • Financial: Portfolio optimization, trading strategies, risk management

🧠 Machine Learning

  • Neural Architecture Search: Automatically design neural networks
  • Hyperparameter Tuning: Optimize ML model parameters
  • Feature Selection: Find optimal feature subsets

🎮 Game Development

  • AI Behavior: Evolve intelligent game agents
  • Level Generation: Create procedural game c
View on GitHub
GitHub Stars52
CategoryDevelopment
Updated1mo ago
Forks1

Languages

C#

Security Score

100/100

Audited on Feb 14, 2026

No findings