Skip to content

romanbulgac/TSP

Repository files navigation

TspLab - Solver Profesional pentru Problema Comis-Voiajorului 🧬

.NET 8 ASP.NET Core Blazor WebAssembly Clean Architecture License: MIT

O soluție de nivel enterprise pentru Problema Comis-Voiajorului (TSP) construită cu Clean Architecture, ASP.NET Core 8 și Blazor WebAssembly. Proiectul implementează un motor genetic configurabil cu vizualizare în timp real și benchmarking avansat pentru performanță.

TspLab Demo Interfața principală TspLab cu vizualizare în timp real a algoritmului genetic


📋 Cuprins


🎯 Prezentare Generală

TspLab este o platformă avansată pentru rezolvarea Problemei Comis-Voiajorului (Traveling Salesman Problem), dezvoltată folosind tehnologii moderne .NET și principiile Clean Architecture. Aplicația oferă multiple algoritmi de optimizare, de la euristici simple la metaeuristici complexe, cu accent pe algoritmii genetici configurabili.

🎯 Obiective Principale

  • Performanță: Algoritmi optimizați pentru instanțe TSP mari
  • Flexibilitate: Operatori genetici interschimbabili și configurabili
  • Scalabilitate: Arhitectură modulară pentru extensibilitate
  • Experiență Utilizator: Interfață modernă cu vizualizare în timp real
  • Interoperabilitate: API REST și SignalR pentru integrare externă

🏆 Avantaje Competitive

  • Clean Architecture cu 6 straturi distincte
  • Dependency Injection nativ pentru configurabilitate
  • Pattern Strategy pentru algoritmi interschimbabili
  • SignalR pentru comunicare în timp real
  • Parallel Processing pentru evaluarea fitness
  • BenchmarkDotNet pentru măsurători precise de performanță

🖼️ Capturi de Ecran

Interfața Principală de Rezolvare

Solver Interface Configurarea parametrilor algoritmului genetic și vizualizarea în timp real

Dashboard de Benchmarking

Benchmark Dashboard Comparația performanței între diferiți algoritmi și configurații

Vizualizarea Evolutiei Algoritmului

Algorithm Evolution Graficul convergentei și evoluția distanței în timp real

API Documentation (Swagger)

API Documentation Documentația interactivă a API-ului REST


🚀 Funcționalități

🧬 Algoritmi de Optimizare

Metaeuristici

  • Algoritm Genetic (GA) - Motor principal cu operatori configurabili
  • Optimizare cu Colonii de Furnici (ACO) - Inspirat din comportamentul furnicilor
  • Recoacere Simulată (SA) - Algoritm de căutare stochastică

Euristici

  • Nearest Neighbor - Greedy cu complexitate O(n²)
  • 2-Opt - Optimizare locală pentru îmbunătățirea tururilor
  • Random Search - Baseline pentru comparație

🔧 Operatori Genetici

Crossover (Încrucișare)

  • Order Crossover (OX) - Păstrează ordinea relativă
  • Partially Mapped Crossover (PMX) - Mapare parțială între părinți
  • Cycle Crossover (CX) - Menține structura ciclică
  • Edge Recombination Crossover (ERX) - Păstrează conectivitatea

Mutație

  • Swap Mutation - Schimbă două orașe aleatorii
  • Inversion Mutation - Inversează o secvență de orașe
  • 2-Opt Mutation - Optimizare locală prin restructurare

🎨 Interfață Utilizator

  • Blazor WebAssembly pentru execuție client-side
  • Tailwind CSS pentru design modern și responsiv
  • Chart.js pentru vizualizări interactive
  • Bootstrap Icons pentru iconografie consistentă

⚡ Caracteristici Tehnice

  • ASP.NET Core 8 cu Minimal APIs
  • SignalR pentru streaming în timp real
  • Parallel Processing multi-threaded
  • Suport pentru anulare gracefully
  • Health Checks pentru monitoring
  • Containerizare Docker multi-stage

🏗️ Arhitectura Sistemului

TspLab implementează Clean Architecture cu 6 straturi distincte pentru separarea responsabilităților și menținerea unui cod curat și testabil.

TspLab/
├── 📁 TspLab.Domain/          # Entități și interfețe de domeniu
├── 📁 TspLab.Application/     # Logică de business și servicii
├── 📁 TspLab.Infrastructure/  # Implementări concrete ale algoritmilor
├── 📁 TspLab.WebApi/         # REST API și SignalR hubs
├── 📁 TspLab.Web/            # Frontend Blazor WebAssembly
└── 📁 TspLab.Tests/          # Teste unitare și benchmarking

🎯 Straturi Clean Architecture

1. Domain Layer (Stratul Domeniului)

  • Entități: City, Tour - modelele centrale ale domeniului
  • Interfețe: ITspSolver, ICrossover, IMutation - contracte pentru algoritmi
  • Value Objects: GeneticAlgorithmConfig, GeneticAlgorithmResult
  • Principiu: Fără dependențe externe, doar logica pură de business

2. Application Layer (Stratul Aplicației)

  • Servicii: GeneticEngine, TspSolverService, StrategyResolver
  • Use Cases: Orchestrează operațiunile complexe
  • DTOs: Modele pentru transferul datelor între straturi
  • Principiu: Coordonează domeniile, definește workflow-urile

3. Infrastructure Layer (Stratul Infrastructurii)

  • Algoritmi: Implementări concrete ale ICrossover, IMutation
  • Persistență: Servicii pentru salvarea rezultatelor
  • Comunicare: Integrări externe și API-uri
  • Principiu: Implementează interfețele din domeniului

4. WebApi Layer (Stratul API-ului)

  • Controllers: TspController - endpoint-uri REST
  • Hubs: TspHub - comunicare SignalR în timp real
  • Middleware: Validare, autentificare, error handling
  • Principiu: Expune funcționalitatea prin HTTP și WebSockets

5. Web Layer (Stratul UI)

  • Pagini: Home.razor, Solver.razor, Benchmark.razor
  • Componente: Componente Blazor reutilizabile
  • Servicii Client: TspApiService, SignalRService
  • Principiu: Interfața utilizator și experiența UX

6. Tests Layer (Stratul Testelor)

  • Unit Tests: Testarea individuală a componentelor
  • Integration Tests: Testarea interacțiunilor între straturi
  • Benchmarks: Măsurători de performanță cu BenchmarkDotNet
  • Principiu: Asigurarea calității și performanței

🔄 Fluxul de Date

graph TB
    A[Blazor UI] --> B[WebApi Controller]
    B --> C[Application Service]
    C --> D[Domain Entity]
    C --> E[Infrastructure Algorithm]
    E --> F[SignalR Hub]
    F --> A
Loading

🤖 Algoritmi Implementați

🧬 Algoritm Genetic (GA) - Principalul Motor

Implementarea algoritmului genetic folosește Pattern Strategy pentru operatorii configurabili:

public class GeneticEngine
{
    // Configurație flexibilă pentru parametrii algoritmului
    public async Task<GeneticAlgorithmResult> SolveAsync(
        City[] cities,
        GeneticAlgorithmConfig config,
        CancellationToken cancellationToken = default)
    
    // Suport pentru pause/resume în timp real
    public void Pause() => _pauseRequested = true;
    public void Resume() => _pauseRequested = false;
}

Caracteristici Avansate:

  • Elitism: Păstrarea celor mai buni indivizi
  • Tournament Selection: Selecție prin turneu configurabil
  • Parallel Fitness Evaluation: Evaluare multi-threaded
  • Dynamic Parameters: Ajustarea parametrilor în timpul execuției

🐜 Ant Colony Optimization (ACO)

Algoritm inspirat din comportamentul coloniilor de furnici:

public class AntColonyOptimizationSolver : ITspSolver
{
    // Parametrii specifici ACO
    private double _alpha = 1.0;    // Importanța feromonilor
    private double _beta = 2.0;     // Importanța heuristicii
    private double _rho = 0.5;      // Rata de evaporare
    private double _q = 100.0;      // Constanta pentru actualizarea feromonilor
}

🌡️ Simulated Annealing (SA)

Algoritm de recoacere simulată pentru optimizare globală:

public class SimulatedAnnealingSolver : ITspSolver
{
    // Funcția de răcire exponențială
    private double CoolingFunction(double temperature, int iteration)
    {
        return temperature * Math.Pow(0.95, iteration);
    }
}

🎯 Algoritmi Euristici

Nearest Neighbor - O(n²)

  • Construire greedy pornind de la orașul selectat
  • Rapid, dar cu soluții suboptimale
  • Ideal pentru inițializarea populației

2-Opt - Optimizare Locală

  • Îmbunătățirea unei soluții prin rearanging
  • Elimină încrucișările din tour
  • Folosit și ca operator de mutație

💻 Instrucțiuni de Rulare

📋 Prerequisite

Asigură-te că ai instalate următoarele componente:

  • .NET 8.0 SDK (obligatoriu)
  • Node.js 20+ (pentru Tailwind CSS)
  • Git (pentru clonarea repository-ului)
  • Docker (opțional, pentru containerizare)
  • IDE recomandat: Visual Studio 2022, VS Code sau JetBrains Rider

🔧 Dezvoltare Locală

1. Clonează Repository-ul

git clone https://github.com/yourusername/tsp-lab.git
cd tsp-lab

2. Restaurează Dependențele

# Restaurare pachete .NET
dotnet restore

# Instalare dependențe frontend (dacă este cazul)
cd TspLab.Web
npm install
cd ..

3. Construiește Soluția

# Build în modul development
dotnet build

# Build pentru producție
dotnet build --configuration Release

4. Rulează API-ul Backend

cd TspLab.WebApi
dotnet run

# API disponibil la: https://localhost:7001
# Swagger UI: https://localhost:7001/swagger

5. Rulează Frontend-ul Blazor

# În alt terminal
cd TspLab.Web
dotnet run

# WebAssembly app disponibilă la: https://localhost:7002

6. Accesează Aplicația

  • API Backend: https://localhost:7001
  • Swagger Documentation: https://localhost:7001/swagger
  • Blazor WebAssembly: https://localhost:7002
  • SignalR Hub: wss://localhost:7001/tsp-hub

🚀 Rulare Rapidă cu Docker

Opțiunea 1: Docker Compose (Recomandat)

# Construiește și rulează toate serviciile
docker-compose up --build

# În background
docker-compose up -d --build

# Aplicația va fi disponibilă la: http://localhost:8080

Opțiunea 2: Docker Manual

# Construiește imaginea
docker build -t tsp-lab:latest .

# Rulează containerul
docker run -p 8080:8080 tsp-lab:latest

🧪 Rularea Testelor

Teste Unitare

# Toate testele
dotnet test

# Doar un proiect specific
dotnet test TspLab.Tests

# Cu acoperire de cod
dotnet test --collect:"XPlat Code Coverage"

Benchmarking Performanță

cd TspLab.Tests
dotnet run --configuration Release --framework net8.0 -- --filter "*Benchmark*"

# Rezultate în: TspLab.Tests/BenchmarkDotNet.Artifacts/

🔍 Verificarea Stării Aplicației

Health Checks

# Verifică starea API-ului
curl https://localhost:7001/health

# Răspuns așteptat: "Healthy"

Logs și Monitoring

# Verifică logs în timpul dezvoltării
dotnet run --verbosity normal

# Pentru production, configurează logging în appsettings.json

🌐 Utilizare API

TspLab expune o REST API completă și SignalR hubs pentru comunicare în timp real.

🔗 REST API Endpoints

📍 Gestionarea Orașelor

Generează orașe aleatorii:

POST /api/cities/generate
Content-Type: application/json

{
  "count": 50,
  "minX": 0,
  "maxX": 100,
  "minY": 0,
  "maxY": 100,
  "seed": 42
}

Răspuns:

{
  "cities": [
    { "id": 1, "name": "City_1", "x": 25.4, "y": 67.8 },
    { "id": 2, "name": "City_2", "x": 42.1, "y": 33.7 }
  ],
  "count": 50
}

🧬 Rezolvarea TSP

Pornește algoritmul genetic:

POST /api/solve
Content-Type: application/json

{
  "cities": [
    { "id": 1, "name": "City_1", "x": 0, "y": 0 },
    { "id": 2, "name": "City_2", "x": 10, "y": 10 }
  ],
  "config": {
    "populationSize": 100,
    "maxGenerations": 1000,
    "eliteSize": 20,
    "mutationRate": 0.01,
    "crossoverRate": 0.8,
    "tournamentSize": 5,
    "crossoverType": "OrderCrossover",
    "mutationType": "SwapMutation"
  }
}

Răspuns:

{
  "sessionId": "guid-session-id",
  "status": "started",
  "message": "Genetic algorithm started successfully"
}

⚙️ Configurarea Strategiilor

Obține strategiile disponibile:

GET /api/strategies

Răspuns:

{
  "crossoverStrategies": [
    "OrderCrossover",
    "PartiallyMappedCrossover", 
    "CycleCrossover",
    "EdgeRecombinationCrossover"
  ],
  "mutationStrategies": [
    "SwapMutation",
    "InversionMutation", 
    "TwoOptMutation"
  ]
}

🏥 Health Checks

Verifică starea aplicației:

GET /health

Răspuns:

{
  "status": "Healthy",
  "totalDuration": "00:00:00.0123456",
  "entries": {
    "database": {
      "status": "Healthy"
    },
    "signalr": {
      "status": "Healthy"
    }
  }
}

📡 SignalR Real-time Communication

🔌 Conectarea la Hub

JavaScript Client:

const connection = new signalR.HubConnectionBuilder()
    .withUrl('/tsp-hub')
    .build();

// Pornește conexiunea
await connection.start();
console.log('Conectat la TspHub');

C# Client:

var connection = new HubConnectionBuilder()
    .WithUrl("https://localhost:7001/tsp-hub")
    .Build();

await connection.StartAsync();

📊 Primirea Actualizărilor în Timp Real

Abonează-te la rezultatele algoritmului genetic:

connection.on('GeneticAlgorithmUpdate', (update) => {
    console.log(`Generația ${update.generation}: Distanța cea mai bună = ${update.bestDistance}`);
    
    // Actualizează UI
    updateChart(update.generation, update.bestDistance);
    updateTourVisualization(update.bestTour);
});

Model de date pentru actualizări:

{
  "sessionId": "guid-session-id",
  "generation": 150,
  "bestDistance": 847.23,
  "averageDistance": 923.45,
  "bestTour": [1, 3, 7, 2, 5, 8, 4, 6, 1],
  "executionTime": "00:02:15.123",
  "isCompleted": false
}

🎛️ Controlul Execuției

Pause/Resume algoritm:

// Pauză algoritm
await connection.invoke('PauseAlgorithm', sessionId);

// Continuă algoritm
await connection.invoke('ResumeAlgorithm', sessionId);

// Oprește algoritm
await connection.invoke('StopAlgorithm', sessionId);

📈 Evenimente de Status

Monitorizează statusul algoritmului:

connection.on('AlgorithmStatus', (status) => {
    switch(status.state) {
        case 'Started':
            console.log('Algoritm pornit');
            break;
        case 'Paused':
            console.log('Algoritm în pauză');
            break;
        case 'Completed':
            console.log('Algoritm completat');
            displayFinalResults(status.result);
            break;
        case 'Error':
            console.error('Eroare:', status.error);
            break;
    }
});

🛠️ Exemple de Integrare

Python Client

import requests
import asyncio
import signalr

# REST API call
response = requests.post('https://localhost:7001/api/cities/generate', 
                        json={'count': 30})
cities = response.json()['cities']

# SignalR connection
async def main():
    connection = signalr.HubConnectionBuilder()\
        .with_url("https://localhost:7001/tsp-hub")\
        .build()
    
    connection.on("GeneticAlgorithmUpdate", lambda data: print(f"Gen {data['generation']}: {data['bestDistance']}"))
    
    await connection.start()
    await connection.send("JoinSession", session_id)

cURL Examples

# Generează orașe
curl -X POST https://localhost:7001/api/cities/generate \
  -H "Content-Type: application/json" \
  -d '{"count": 25, "seed": 123}'

# Verifică strategiile
curl https://localhost:7001/api/strategies

# Health check
curl https://localhost:7001/health

🧬 Strategii Genetice

TspLab implementează o gamă largă de operatori genetici folosind Pattern Strategy pentru flexibilitate maximă. Fiecare operator poate fi configurat independent și combinat pentru a experimenta cu diferite abordări evolutive.

🔀 Operatori de Crossover (Încrucișare)

1. Order Crossover (OX) - Recomandat General

Păstrează ordinea relativă a orașelor dintr-un părinte:

public class OrderCrossover : ICrossover
{
    public Tour[] Cross(Tour parent1, Tour parent2)
    {
        // Selectează o subsecvență din parent1
        // Completează cu orașe din parent2 în ordine
        // Păstrează ordinea relativă
    }
}

Avantaje:

  • Păstrează ordinea relativă din primul părinte
  • Funcționează bine pentru majoritatea instanțelor TSP
  • Complexitate temporală: O(n)

Când să folosești: Probleme TSP generale, populații diverse

2. Partially Mapped Crossover (PMX) - Pentru Instanțe Mari

Mapează parțial între doi părinți pentru a păstra informația structurală:

public class PartiallyMappedCrossover : ICrossover
{
    // Creează o mapare între două segmente ale părinților
    // Aplică maparea pentru a evita duplicatele
    // Ideal pentru instanțe mari cu structură complexă
}

Avantaje:

  • Păstrează mai multă informație structurală
  • Eficient pentru instanțe mari (1000+ orașe)
  • Reduce fragmentarea soluțiilor

Când să folosești: TSP cu multe orașe, când ordinea locală e importantă

3. Cycle Crossover (CX) - Pentru TSP Simetric

Menține structura ciclică specifică problemelor TSP:

public class CycleCrossover : ICrossover
{
    // Identifică ciclurile în reprezentarea TSP
    // Alternează ciclurile între părinți
    // Optimizat pentru TSP simetric
}

Avantaje:

  • Perfect pentru TSP simetric
  • Păstrează proprietățile ciclice
  • Minimizează disrupția structurală

Când să folosești: TSP simetric, când structura e critică

4. Edge Recombination Crossover (ERX) - Avansat

Păstrează conectivitatea (muchiile) din ambii părinți:

public class EdgeRecombinationCrossover : ICrossover
{
    // Construiește tabela de muchii din ambii părinți
    // Reconstruiește turul păstrând cât mai multe muchii
    // Cel mai sofisticat operator implementat
}

Avantaje:

  • Păstrează cel mai mult din structura părinților
  • Ideal pentru soluții de înaltă calitate
  • Minimizează pierderea informației

Când să folosești: Când ai nevoie de calitate maximă, faza finală de optimizare

🔀 Operatori de Mutație

1. Swap Mutation - Simplu și Eficient

Schimbă două orașe aleatorii din tour:

public class SwapMutation : IMutation
{
    public Tour Mutate(Tour tour, double mutationRate)
    {
        if (Random.NextDouble() < mutationRate)
        {
            // Selectează două poziții aleatorii
            // Schimbă orașele de pe acele poziții
        }
        return tour;
    }
}

Caracteristici:

  • Simplu de implementat și înțeles
  • Schimbări mici, ideal pentru fine-tuning
  • Complexitate O(1)

Parameterizare: Rata de mutație: 0.01-0.05

2. Inversion Mutation - Pentru Diversificare

Inversează o secvență de orașe pentru diversificare:

public class InversionMutation : IMutation
{
    // Selectează două puncte în tour
    // Inversează secvența dintre ele
    // Poate produce schimbări mari în structură
}

Caracteristici:

  • Schimbări structurale mai mari
  • Bun pentru evitarea optimelor locale
  • Complexitate O(k) unde k = lungimea secvenței

Parameterizare: Rata de mutație: 0.1-0.3 pentru explorare

3. Two-Opt Mutation - Optimizare Locală

Aplică optimizarea 2-Opt ca mutație:

public class TwoOptMutation : IMutation
{
    // Elimină două muchii din tour
    // Reconectează pentru a elimina încrucișările
    // Combină mutația cu optimizarea locală
}

Caracteristici:

  • Îmbunătățește calitatea soluției
  • Elimină încrucișările evidente
  • Poate fi costisitor computațional

Parameterizare: Rata de mutație: 0.05-0.1, folosește cu moderație

⚙️ Configurarea Strategiilor

Configurație prin Dependency Injection

// În Program.cs sau Startup.cs
services.AddScoped<ICrossover, OrderCrossover>();
services.AddScoped<IMutation, SwapMutation>();

// Sau prin Strategy Resolver
services.AddSingleton<StrategyResolver>();

Configurare Dinamică prin API

{
  "geneticConfig": {
    "populationSize": 100,
    "maxGenerations": 1000,
    "crossoverType": "OrderCrossover",
    "mutationType": "SwapMutation",
    "crossoverRate": 0.8,
    "mutationRate": 0.02,
    "eliteSize": 15,
    "tournamentSize": 5
  }
}

📊 Matricea Combinațiilor Recomandate

Tip Problemă Crossover Recomandat Mutație Recomandată Populație Generații
TSP Mic (< 50 orașe) Order Crossover Swap Mutation 50-100 500-1000
TSP Mediu (50-200) PMX sau OX Inversion Mutation 100-200 1000-2000
TSP Mare (200+ orașe) PMX 2-Opt + Swap 200-500 2000+
TSP Simetric Cycle Crossover Swap Mutation 100-200 1000-1500
Optimizare Finală ERX 2-Opt Mutation 50-100 500-1000

🎯 Ghid de Tuning a Parametrilor

Pentru Explorare (Diversificare)

{
  "mutationRate": 0.1,
  "crossoverRate": 0.6,
  "eliteSize": 5,
  "tournamentSize": 3,
  "strategy": "InversionMutation + PMX"
}

Pentru Exploatare (Rafinare)

{
  "mutationRate": 0.01,
  "crossoverRate": 0.9,
  "eliteSize": 20,
  "tournamentSize": 7,
  "strategy": "SwapMutation + ERX"
}

Configurare Adaptivă

public class AdaptiveParameterStrategy
{
    public void AdjustParameters(int generation, double convergenceRate)
    {
        if (convergenceRate < 0.01) // Stagnare
        {
            // Crește rata de mutație pentru diversificare
            MutationRate = Math.Min(0.1, MutationRate * 1.5);
        }
        else if (convergenceRate > 0.05) // Convergență rapidă
        {
            // Scade rata de mutație pentru rafinare
            MutationRate = Math.Max(0.005, MutationRate * 0.8);
        }
    }
}

📈 Benchmarking

TspLab folosește BenchmarkDotNet pentru măsurători precise de performanță și comparații obiective între algoritmi.

🏆 Rezultate Benchmark Standard

Instanțe Mici (50 orașe)

Algoritm Timp Mediu Distanța Minimă Distanța Medie Convergență
Genetic Algorithm 1.25s 8.43 9.12 500 gen
Ant Colony Optimization 2.34s 8.67 9.45 100 iter
Simulated Annealing 0.89s 9.23 10.11 1000 iter
Nearest Neighbor 0.012s 12.67 12.67 1 pass
2-Opt 0.156s 10.34 10.34 local opt
Random 0.002s 23.45 24.12 baseline

Instanțe Medii (200 orașe)

Algoritm Timp Mediu Distanța Minimă Distanța Medie Scalabilitate
Genetic Algorithm 8.7s 15.67 17.23 Excelentă
Ant Colony Optimization 15.2s 16.12 18.45 Bună
Simulated Annealing 6.3s 17.89 19.67 Bună
Nearest Neighbor 0.18s 28.45 28.45 Excelentă
2-Opt 2.4s 22.12 22.12 Moderată

Instanțe Mari (500+ orașe)

Algoritm Timp Mediu Calitatea Soluției Memorie (MB) Paralelizare
Genetic Algorithm 45.2s 95% din optimum 125 Da (4-8 core)
Ant Colony Optimization 78.9s 92% din optimum 89 Parțial
Simulated Annealing 34.1s 88% din optimum 45 Nu

🧪 Rularea Benchmark-urilor

Benchmark-uri Complete

cd TspLab.Tests
dotnet run --configuration Release --framework net8.0 -- --filter "*Benchmark*"

Benchmark-uri Specifice

# Doar algoritmi genetici
dotnet run --configuration Release -- --filter "*GeneticBenchmark*"

# Doar operatori crossover
dotnet run --configuration Release -- --filter "*CrossoverBenchmark*"

# Doar comparații algoritmi
dotnet run --configuration Release -- --filter "*AlgorithmComparison*"

Rezultate Detaliate

# Export în format HTML
dotnet run --configuration Release -- --exporters html

# Export în format JSON
dotnet run --configuration Release -- --exporters json

# Rezultate în: TspLab.Tests/BenchmarkDotNet.Artifacts/

📊 Benchmark-uri Personalizate

Configurarea Benchmark-urilor

[Config(typeof(Config))]
public class CustomTspBenchmark
{
    private class Config : ManualConfig
    {
        public Config()
        {
            AddJob(Job.Default.WithRuntime(CoreRuntime.Core80));
            AddExporter(HtmlExporter.Default);
            AddDiagnoser(MemoryDiagnoser.Default);
            AddValidator(ExecutionValidator.FailOnError);
        }
    }

    [Params(50, 100, 200, 500)]
    public int CityCount { get; set; }

    [Benchmark]
    public GeneticAlgorithmResult GeneticAlgorithm()
    {
        // Implementarea benchmark-ului
    }
}

Măsurători de Performanță

[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net80)]
public class OperatorPerformanceBenchmark
{
    [Benchmark]
    [Arguments(100, "OrderCrossover")]
    [Arguments(100, "PartiallyMappedCrossover")]
    [Arguments(100, "CycleCrossover")]
    public void CrossoverPerformance(int tourSize, string crossoverType)
    {
        // Testează performanța operatorilor de crossover
    }
}

📈 Analiză Statistică

Distribuția Rezultatelor

# Generează rapoarte statistice detaliate
dotnet run --configuration Release -- \
  --statisticalTest MannWhitney \
  --filter "*StatisticalBenchmark*"

Teste de Semnificativitate

[SimpleJob(launchCount: 1, warmupCount: 3, targetCount: 10)]
public class StatisticalSignificanceBenchmark
{
    [Benchmark(Baseline = true)]
    public double GeneticAlgorithmBaseline() => RunGA();

    [Benchmark]
    public double GeneticAlgorithmOptimized() => RunOptimizedGA();
}

🎯 Optimizarea Performanței

Identificarea Bottleneck-urilor

# Profile cu dotTrace sau PerfView
dotnet run --configuration Release -- --profiler ETW

Recomandări de Optimizare

Pentru Instanțe Mici (< 100 orașe):

  • Folosește populații mici (50-100)
  • Privilege operatori simpli (OX + Swap)
  • Activează paralelizarea pentru fitness

Pentru Instanțe Mari (500+ orașe):

  • Populații mari (200-500)
  • Operatori sofisticați (PMX + 2-Opt)
  • Memory pooling pentru evitarea GC
  • Optimizare SIMD pentru calcule de distanță

Monitoring în Producție

public class PerformanceMetrics
{
    private static readonly Counter AlgorithmExecutions = 
        Metrics.CreateCounter("tsp_algorithm_executions_total");
        
    private static readonly Histogram ExecutionDuration = 
        Metrics.CreateHistogram("tsp_execution_duration_seconds");
}

📋 Raport de Benchmark Tip

BenchmarkDotNet=v0.13.8, OS=macOS Sonoma 14.0
Intel Core i9-9980HK CPU 2.40GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=8.0.0

|              Method |  CityCount |      Mean |     Error |    StdDev |    Median |  Gen0 |  Gen1 | Allocated |
|-------------------- |----------- |----------:|----------:|----------:|----------:|------:|------:|----------:|
|    GeneticAlgorithm |         50 |  1.247 s  |  0.0456 s |  0.0387 s |  1.234 s  |  125MB|   45MB|     178MB |
| AntColonyOptimization|         50 |  2.341 s  |  0.0823 s |  0.0729 s |  2.298 s  |   89MB|   23MB|     134MB |
|   SimulatedAnnealing |         50 |  0.891 s  |  0.0234 s |  0.0198 s |  0.887 s  |   45MB|   12MB|      67MB |
|     NearestNeighbor |         50 | 12.34 ms  |  0.245 ms |  0.217 ms | 12.28 ms  |    2MB|    0MB|       3MB |

🐳 Docker & Kubernetes

TspLab este optimizat pentru deployment în containere și orchestrare Kubernetes pentru scalabilitate enterprise.

🐳 Containerizare cu Docker

Multi-Stage Dockerfile

# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src

# Copy csproj files și restore dependencies
COPY ["TspLab.WebApi/TspLab.WebApi.csproj", "TspLab.WebApi/"]
COPY ["TspLab.Web/TspLab.Web.csproj", "TspLab.Web/"]
COPY ["TspLab.Application/TspLab.Application.csproj", "TspLab.Application/"]
COPY ["TspLab.Domain/TspLab.Domain.csproj", "TspLab.Domain/"]
COPY ["TspLab.Infrastructure/TspLab.Infrastructure.csproj", "TspLab.Infrastructure/"]

RUN dotnet restore "TspLab.WebApi/TspLab.WebApi.csproj"

# Copy source code și build
COPY . .
WORKDIR "/src/TspLab.WebApi"
RUN dotnet build "TspLab.WebApi.csproj" -c Release -o /app/build

# Publish stage
FROM build AS publish
RUN dotnet publish "TspLab.WebApi.csproj" -c Release -o /app/publish /p:UseAppHost=false

# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app

# Security: Create non-root user
RUN groupadd -r tsplab && useradd --no-log-init -r -g tsplab tsplab

# Copy published app
COPY --from=publish /app/publish .

# Set ownership
RUN chown -R tsplab:tsplab /app
USER tsplab

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

EXPOSE 8080
ENTRYPOINT ["dotnet", "TspLab.WebApi.dll"]

Docker Compose pentru Dezvoltare

version: '3.8'

services:
  tsp-api:
    build: 
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      - Logging__LogLevel__Default=Information
    volumes:
      - ./logs:/app/logs
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # Redis pentru caching (opțional)
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data

  # Prometheus pentru monitoring (opțional)
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml

volumes:
  redis_data:

Comenzi Docker Utile

# Build imagine
docker build -t tsp-lab:latest .

# Run container local
docker run -d -p 8080:8080 --name tsp-lab tsp-lab:latest

# Logs în timp real
docker logs -f tsp-lab

# Debug în container
docker exec -it tsp-lab /bin/bash

# Cleanup
docker stop tsp-lab && docker rm tsp-lab

☸️ Deployment Kubernetes

Namespace și ConfigMap

apiVersion: v1
kind: Namespace
metadata:
  name: tsp-lab
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tsp-config
  namespace: tsp-lab
data:
  ASPNETCORE_ENVIRONMENT: "Production"
  Logging__LogLevel__Default: "Warning"
  Logging__LogLevel__Microsoft.AspNetCore: "Warning"

Deployment Principal

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tsp-lab-api
  namespace: tsp-lab
  labels:
    app: tsp-lab-api
    version: v1.0
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: tsp-lab-api
  template:
    metadata:
      labels:
        app: tsp-lab-api
        version: v1.0
    spec:
      containers:
      - name: tsp-lab-api
        image: ghcr.io/yourusername/tsp-lab:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: ASPNETCORE_URLS
          value: "http://+:8080"
        envFrom:
        - configMapRef:
            name: tsp-config
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        securityContext:
          allowPrivilegeEscalation: false
          runAsNonRoot: true
          runAsUser: 1000
          capabilities:
            drop:
            - ALL

Service și Ingress

apiVersion: v1
kind: Service
metadata:
  name: tsp-lab-service
  namespace: tsp-lab
spec:
  selector:
    app: tsp-lab-api
  ports:
  - name: http
    port: 80
    targetPort: 8080
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tsp-lab-ingress
  namespace: tsp-lab
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/websocket-services: tsp-lab-service
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
spec:
  tls:
  - hosts:
    - tsp-lab.yourdomain.com
    secretName: tsp-lab-tls
  rules:
  - host: tsp-lab.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tsp-lab-service
            port:
              number: 80

HorizontalPodAutoscaler (HPA)

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: tsp-lab-hpa
  namespace: tsp-lab
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: tsp-lab-api
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Comenzi Kubernetes Utile

# Deploy toate resursele
kubectl apply -f k8s/

# Verifică status
kubectl get pods -n tsp-lab
kubectl get services -n tsp-lab
kubectl get ingress -n tsp-lab

# Logs și debugging
kubectl logs -f deployment/tsp-lab-api -n tsp-lab
kubectl describe pod <pod-name> -n tsp-lab

# Port forwarding pentru testing local
kubectl port-forward service/tsp-lab-service 8080:80 -n tsp-lab

# Scaling manual
kubectl scale deployment tsp-lab-api --replicas=5 -n tsp-lab

# Rolling update
kubectl set image deployment/tsp-lab-api tsp-lab-api=ghcr.io/yourusername/tsp-lab:v1.1 -n tsp-lab

🏗️ CI/CD Pipeline

GitHub Actions Workflow

name: Build and Deploy

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: 8.0.x
    
    - name: Restore dependencies
      run: dotnet restore
    
    - name: Build
      run: dotnet build --no-restore
    
    - name: Test
      run: dotnet test --no-build --verbosity normal

  build-and-push:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
    - uses: actions/checkout@v4
    
    - name: Build and push Docker image
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: ghcr.io/${{ github.repository }}:latest

  deploy:
    needs: build-and-push
    runs-on: ubuntu-latest
    environment: production
    steps:
    - name: Deploy to Kubernetes
      run: |
        kubectl set image deployment/tsp-lab-api \
          tsp-lab-api=ghcr.io/${{ github.repository }}:latest \
          -n tsp-lab

📊 Monitoring și Observabilitate

Prometheus Metrics

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
    - job_name: 'tsp-lab'
      static_configs:
      - targets: ['tsp-lab-service:80']
      metrics_path: /metrics

Grafana Dashboard

{
  "dashboard": {
    "title": "TspLab Performance",
    "panels": [
      {
        "title": "Algorithm Execution Time",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(tsp_execution_duration_seconds[5m])"
          }
        ]
      }
    ]
  }
}

🔧 Dezvoltare

📁 Structura Detaliată a Proiectului

TspLab/
├── 📁 TspLab.Domain/                    # Stratul Domeniului
│   ├── 📁 Entities/
│   │   ├── City.cs                      # Entitatea oraș cu coordonate
│   │   └── Tour.cs                      # Reprezentarea unui tur
│   ├── 📁 Interfaces/
│   │   ├── ICrossover.cs               # Interfața pentru operatori crossover
│   │   ├── IMutation.cs                # Interfața pentru operatori mutație
│   │   ├── ITspSolver.cs               # Interfața comună pentru algoritmi TSP
│   │   └── IFitnessFunction.cs         # Interfața pentru funcții fitness
│   └── 📁 Models/
│       ├── GeneticAlgorithmConfig.cs   # Configurația algoritmului genetic
│       └── GeneticAlgorithmResult.cs   # Rezultatele algoritmului genetic
│
├── 📁 TspLab.Application/               # Stratul Aplicației
│   ├── 📁 Services/
│   │   ├── GeneticEngine.cs            # Motorul principal al AG
│   │   ├── TspSolverService.cs         # Serviciu high-level pentru rezolvare
│   │   ├── StrategyResolver.cs         # Resolver pentru strategii prin DI
│   │   └── AntColonyService.cs         # Serviciu pentru algoritm ACO
│   ├── 📁 Solvers/
│   │   └── GeneticAlgorithmSolver.cs   # Wrapper AG pentru ITspSolver
│   ├── 📁 Heuristics/
│   │   ├── NearestNeighborSolver.cs    # Algoritm Nearest Neighbor
│   │   ├── TwoOptSolver.cs             # Algoritm 2-Opt
│   │   └── SimulatedAnnealingSolver.cs # Algoritm Simulated Annealing
│   └── 📁 Metaheuristics/
│       └── AntColonyOptimizationSolver.cs # Algoritm ACO
│
├── 📁 TspLab.Infrastructure/            # Stratul Infrastructurii
│   ├── 📁 Crossover/
│   │   ├── OrderCrossover.cs           # Order Crossover (OX)
│   │   ├── PartiallyMappedCrossover.cs # Partially Mapped Crossover (PMX)
│   │   ├── CycleCrossover.cs           # Cycle Crossover (CX)
│   │   └── EdgeRecombinationCrossover.cs # Edge Recombination Crossover
│   ├── 📁 Mutation/
│   │   ├── SwapMutation.cs             # Mutația prin schimbare
│   │   ├── InversionMutation.cs        # Mutația prin inversare
│   │   └── TwoOptMutation.cs           # Mutația 2-Opt
│   └── 📁 Fitness/
│       └── DistanceFitnessFunction.cs  # Funcția fitness bazată pe distanță
│
├── 📁 TspLab.WebApi/                   # Stratul API-ului
│   ├── Program.cs                      # Configurația serverului API
│   ├── 📁 Controllers/
│   │   └── TspController.cs            # Controller REST pentru TSP
│   ├── 📁 Hubs/
│   │   └── TspHub.cs                   # SignalR hub pentru comunicare real-time
│   └── 📁 Models/
│       ├── SolveRequest.cs             # Model pentru cereri de rezolvare
│       └── SolveResponse.cs            # Model pentru răspunsuri
│
├── 📁 TspLab.Web/                      # Stratul UI Blazor
│   ├── Program.cs                      # Configurația client Blazor
│   ├── 📁 Pages/
│   │   ├── Home.razor                  # Pagina principală
│   │   ├── Solver.razor                # Pagina de rezolvare TSP
│   │   └── Benchmark.razor             # Pagina de benchmarking
│   ├── 📁 Components/
│   │   ├── TspVisualization.razor      # Componenta de vizualizare
│   │   └── ParameterConfiguration.razor # Componenta configurare parametri
│   ├── 📁 Services/
│   │   ├── TspApiService.cs            # Client pentru API REST
│   │   └── SignalRService.cs           # Client pentru SignalR
│   └── 📁 wwwroot/
│       ├── index.html
│       ├── 📁 js/
│       │   └── tsp-visualization.js    # JavaScript pentru vizualizare
│       └── 📁 css/
│           └── app.css                 # Stiluri personalizate
│
└── 📁 TspLab.Tests/                    # Stratul Testelor
    ├── 📁 Unit/
    │   ├── TourTests.cs                # Teste pentru entitatea Tour
    │   ├── CrossoverTests.cs           # Teste pentru operatori crossover
    │   ├── MutationTests.cs            # Teste pentru operatori mutație
    │   └── GeneticEngineTests.cs       # Teste pentru motorul genetic
    ├── 📁 Integration/
    │   ├── ApiIntegrationTests.cs      # Teste de integrare API
    │   └── SignalRIntegrationTests.cs  # Teste SignalR
    └── 📁 Benchmarks/
        ├── AlgorithmBenchmarks.cs      # Benchmark-uri algoritmi
        └── PerformanceTests.cs         # Teste de performanță

🛠️ Adăugarea de Noi Operatori

1. Crearea unui Operator Crossover Nou

// TspLab.Infrastructure/Crossover/MyCustomCrossover.cs
public class MyCustomCrossover : ICrossover
{
    public Tour[] Cross(Tour parent1, Tour parent2)
    {
        // Implementează logica personalizată de crossover
        var offspring1 = new Tour();
        var offspring2 = new Tour();
        
        // Algoritmul tău aici...
        
        return new[] { offspring1, offspring2 };
    }
}

2. Înregistrarea în DI Container

// TspLab.WebApi/Program.cs sau ServiceCollectionExtensions.cs
services.AddScoped<ICrossover, MyCustomCrossover>();

// Pentru rezolvarea dinamică
services.AddKeyedScoped<ICrossover, MyCustomCrossover>("MyCustomCrossover");

3. Actualizarea Strategy Resolver

// TspLab.Application/Services/StrategyResolver.cs
public ICrossover GetCrossoverStrategy(string strategyName)
{
    return strategyName switch
    {
        "OrderCrossover" => _serviceProvider.GetRequiredService<OrderCrossover>(),
        "MyCustomCrossover" => _serviceProvider.GetRequiredService<MyCustomCrossover>(),
        // ... alte strategii
        _ => throw new ArgumentException($"Unknown crossover strategy: {strategyName}")
    };
}

4. Teste Unitare

// TspLab.Tests/Unit/MyCustomCrossoverTests.cs
[TestClass]
public class MyCustomCrossoverTests
{
    [TestMethod]
    public void Cross_ValidParents_ReturnsValidOffspring()
    {
        // Arrange
        var crossover = new MyCustomCrossover();
        var parent1 = new Tour(new[] { 1, 2, 3, 4, 5 });
        var parent2 = new Tour(new[] { 5, 4, 3, 2, 1 });

        // Act
        var offspring = crossover.Cross(parent1, parent2);

        // Assert
        Assert.AreEqual(2, offspring.Length);
        Assert.IsTrue(offspring[0].IsValid());
        Assert.IsTrue(offspring[1].IsValid());
    }
}

🎨 Personalizarea UI-ului

Componente Blazor Personalizate

@* TspLab.Web/Components/CustomVisualization.razor *@
@using TspLab.Domain.Entities

<div class="visualization-container">
    <canvas id="tsp-canvas" width="800" height="600"></canvas>
    
    @if (CurrentTour != null)
    {
        <div class="tour-info">
            <p>Distanța curentă: @CurrentTour.TotalDistance.ToString("F2")</p>
            <p>Numărul de orașe: @CurrentTour.Cities.Count</p>
        </div>
    }
</div>

@code {
    [Parameter] public Tour? CurrentTour { get; set; }
    [Parameter] public EventCallback<Tour> OnTourUpdated { get; set; }
    
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("initializeTspCanvas", "tsp-canvas");
        }
    }
}

Integrarea cu JavaScript

// TspLab.Web/wwwroot/js/custom-visualization.js
window.initializeTspCanvas = (canvasId) => {
    const canvas = document.getElementById(canvasId);
    const ctx = canvas.getContext('2d');
    
    // Logica de vizualizare personalizată
    window.tspCanvas = {
        canvas: canvas,
        context: ctx,
        updateTour: (tour) => {
            // Redessine turul
        }
    };
};

🔧 Configurări Avansate

Appsettings pentru Diferite Medii

// appsettings.Development.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "TspLab": "Debug"
    }
  },
  "GeneticAlgorithm": {
    "DefaultPopulationSize": 50,
    "DefaultMaxGenerations": 500,
    "ParallelProcessing": true
  },
  "SignalR": {
    "UpdateInterval": 100
  }
}
// appsettings.Production.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft.AspNetCore": "Error"
    }
  },
  "GeneticAlgorithm": {
    "DefaultPopulationSize": 200,
    "DefaultMaxGenerations": 2000,
    "ParallelProcessing": true,
    "CacheSize": 10000
  }
}

Dependency Injection Avansat

// TspLab.WebApi/Extensions/ServiceCollectionExtensions.cs
public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddTspLabServices(this IServiceCollection services, IConfiguration configuration)
    {
        // Configurează serviciile de bază
        services.Configure<GeneticAlgorithmOptions>(
            configuration.GetSection("GeneticAlgorithm"));

        // Înregistrează operatorii genetici
        services.AddCrossoverOperators();
        services.AddMutationOperators();
        services.AddSolvers();

        // Configurează caching
        services.AddMemoryCache();
        services.AddScoped<IDistanceCache, MemoryDistanceCache>();

        return services;
    }

    private static IServiceCollection AddCrossoverOperators(this IServiceCollection services)
    {
        services.AddKeyedScoped<ICrossover, OrderCrossover>("OrderCrossover");
        services.AddKeyedScoped<ICrossover, PartiallyMappedCrossover>("PartiallyMappedCrossover");
        services.AddKeyedScoped<ICrossover, CycleCrossover>("CycleCrossover");
        services.AddKeyedScoped<ICrossover, EdgeRecombinationCrossover>("EdgeRecombinationCrossover");
        
        return services;
    }
}

🧪 Strategii de Testare

Teste de Performanță

[TestClass]
public class PerformanceTests
{
    [TestMethod]
    [DataRow(50)]
    [DataRow(100)]
    [DataRow(200)]
    public void GeneticAlgorithm_PerformanceTest(int cityCount)
    {
        // Arrange
        var cities = GenerateRandomCities(cityCount);
        var config = new GeneticAlgorithmConfig
        {
            PopulationSize = 100,
            MaxGenerations = 500
        };

        var stopwatch = Stopwatch.StartNew();
        
        // Act
        var result = _geneticEngine.Solve(cities, config);
        
        stopwatch.Stop();

        // Assert
        Assert.IsTrue(stopwatch.ElapsedMilliseconds < GetExpectedTime(cityCount));
        Assert.IsTrue(result.BestDistance < GetExpectedDistance(cityCount));
    }
}

Teste de Integrare SignalR

[TestClass]
public class SignalRIntegrationTests
{
    [TestMethod]
    public async Task TspHub_SendsUpdatesCorrectly()
    {
        // Arrange
        using var host = CreateTestHost();
        var connection = CreateHubConnection(host);
        
        var updates = new List<GeneticAlgorithmUpdate>();
        connection.On<GeneticAlgorithmUpdate>("GeneticAlgorithmUpdate", update => 
        {
            updates.Add(update);
        });

        await connection.StartAsync();

        // Act
        await connection.InvokeAsync("StartSolving", cities, config);
        await Task.Delay(2000); // Așteaptă actualizări

        // Assert
        Assert.IsTrue(updates.Count > 0);
        Assert.IsTrue(updates.Any(u => u.Generation > 0));
    }
}

🤝 Contribuții

Contribuțiile sunt foarte apreciate! TspLab este un proiect open-source care beneficiază de input-ul comunității.

🚀 Cum să Contribui

1. Fork Repository-ul

# Fork pe GitHub, apoi clonează local
git clone https://github.com/yourusername/tsp-lab.git
cd tsp-lab

# Adaugă upstream pentru sincronizare
git remote add upstream https://github.com/originalowner/tsp-lab.git

2. Creează o Ramură pentru Feature

# Pornește de la main actualizat
git checkout main
git pull upstream main

# Creează ramura pentru feature-ul tău
git checkout -b feature/amazing-new-algorithm

3. Implementează Schimbările

# Fă modificările necesare
# Adaugă teste pentru funcționalitatea nouă
# Rulează testele existente pentru a asigura că nu strici nimic

dotnet test

4. Commit și Push

# Staging și commit cu mesaj descriptiv
git add .
git commit -m "feat: Add new crossover operator - Position Based Crossover (PBX)

- Implement PBX algorithm for genetic algorithm
- Add unit tests with 95% coverage
- Update documentation with performance benchmarks
- Register operator in DI container"

# Push pe fork-ul tău
git push origin feature/amazing-new-algorithm

5. Creează Pull Request

  • Mergi pe GitHub și creează PR din ramura ta către main
  • Completează template-ul de PR cu detalii despre schimbări
  • Așteaptă review și feedback

📋 Ghid de Contribuție

🎯 Tipuri de Contribuții Apreciate

🔬 Algoritmi Noi:

  • Operatori genetici inovativi (crossover, mutație, selecție)
  • Algoritmi metaeuristici (Particle Swarm, Tabu Search, etc.)
  • Optimizări pentru algoritmi existenți

🎨 Îmbunătățiri UI/UX:

  • Componente Blazor interactive
  • Vizualizări 3D sau animații avansate
  • Dashboard-uri pentru monitoring

⚡ Optimizări de Performanță:

  • Paralelizare avansată
  • Optimizări SIMD
  • Cache strategies

📚 Documentație:

  • Tutoriale pas-cu-pas
  • Explicații teoretice ale algoritmilor
  • Exemple de integrare

🧪 Teste și Quality Assurance:

  • Teste unitare pentru acoperire 100%
  • Teste de performanță
  • Teste de stress

📝 Standarde de Cod

Convenții de Naming:

// Clase: PascalCase
public class GeneticAlgorithmSolver { }

// Metode: PascalCase
public async Task<Tour> SolveAsync() { }

// Variabile: camelCase
var bestTour = result.BestTour;

// Constante: PascalCase
public const int DefaultPopulationSize = 100;

// Interfețe: I + PascalCase
public interface ICrossoverOperator { }

Documentație XML:

/// <summary>
/// Implementează algoritmul Order Crossover (OX) pentru problema TSP.
/// </summary>
/// <param name="parent1">Primul părinte pentru crossover</param>
/// <param name="parent2">Al doilea părinte pentru crossover</param>
/// <returns>Array cu doi urmași rezultați din crossover</returns>
/// <exception cref="ArgumentNullException">Aruncat când unul din părinți este null</exception>
public Tour[] Cross(Tour parent1, Tour parent2)
{
    // Implementarea...
}

Principii SOLID:

  • Single Responsibility: O clasă = o responsabilitate
  • Open/Closed: Deschis pentru extensie, închis pentru modificare
  • Liskov Substitution: Subtipurile să poată înlocui tipurile de bază
  • Interface Segregation: Interfețe mici și specifice
  • Dependency Inversion: Depinde de abstracții, nu de concretizări

🧪 Cerințe pentru Teste

Acoperire Minimă:

  • Algoriti noi: 90% acoperire de cod
  • Operatori genetici: 95% acoperire
  • API controllers: 85% acoperire
  • Servicii business: 90% acoperire

Tipuri de Teste Cerute:

[TestClass]
public class NewAlgorithmTests
{
    [TestMethod] // Test pozitiv basic
    public void Algorithm_ValidInput_ReturnsValidSolution() { }

    [TestMethod] // Test cazuri limită
    [DataRow(1)]
    [DataRow(2)]
    public void Algorithm_EdgeCases_HandlesCorrectly(int cityCount) { }

    [TestMethod] // Test error handling
    [ExpectedException(typeof(ArgumentException))]
    public void Algorithm_InvalidInput_ThrowsException() { }

    [TestMethod] // Test performanță
    public void Algorithm_LargeInput_CompletesInReasonableTime() { }
}

📊 Benchmark Requirements

Pentru algoritmi noi, include benchmark-uri:

[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net80)]
public class NewAlgorithmBenchmark
{
    [Params(50, 100, 200, 500)]
    public int CityCount { get; set; }

    [Benchmark(Baseline = true)]
    public double ExistingAlgorithm() => RunExisting();

    [Benchmark]
    public double NewAlgorithm() => RunNew();
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors