Скачиваний:
0
Добавлен:
26.10.2025
Размер:
67 Кб
Скачать
☆

3) Скрипт TrainingSample.Cs

namespace PerceptronSymbolsHybrid

{

public class TrainingSample

{

public int[] Input; // одномерный массив длины 25 (5x5)

public string Label; // метка символа

public TrainingSample(int[] input, string label)

{

Input = input;

Label = label;

}

}

}

4) Скрипт OutputInformation.Cs

using System;

using System.Collections.Generic;

namespace PerceptronSymbolsHybrid

{

public static class OutputInformation

{

public static void PrintWeights(string symbol, List<double> weights)

{

Console.WriteLine($"Весовая матрица для символа {symbol}:");

for (int i = 0; i < 5; i++)

{

for (int j = 0; j < 5; j++)

{

Console.Write($"{weights[i * 5 + j],8:F3}");

}

Console.WriteLine();

}

}

public static void PrintTestResult(int[] inputMatrix, string recognizedSymbol, Dictionary<string, GAPerceptronIndividual> models)

{

Console.WriteLine("\nМатрица ввода:");

PrintMatrix(inputMatrix);

if (recognizedSymbol != "None" && models.ContainsKey(recognizedSymbol))

{

Console.WriteLine($"\nВесовая матрица для символа {recognizedSymbol}:");

PrintWeights(recognizedSymbol, models[recognizedSymbol].Weights);

}

else

{

Console.WriteLine("\nНи один персептрон не сработал (распознавание не выполнено).");

}

Console.WriteLine($"\nРаспознанный символ: {recognizedSymbol}");

Console.WriteLine(new string('-', 40));

}

private static void PrintMatrix(int[] matrix)

{

for (int i = 0; i < 5; i++)

{

for (int j = 0; j < 5; j++)

{

Console.Write(matrix[i * 5 + j] + " ");

}

Console.WriteLine();

}

}

}

}

5) Скрипт GAPerceptronIndividual.cs

using System;

using System.Collections.Generic;

using System.Linq;

namespace PerceptronSymbolsHybrid

{

public class GAPerceptronIndividual

{

public List<double> Weights { get; private set; }

public double XMin { get; private set; }

public double XMax { get; private set; }

public string TargetSymbol { get; private set; }

public double Fitness { get; private set; } // процент ошибок

private List<TrainingSample> trainingSet;

public GAPerceptronIndividual(List<double> genes, double xmin, double xmax, string targetSymbol, List<TrainingSample> trainingSet)

{

XMin = xmin;

XMax = xmax;

Weights = genes.Select(g => Math.Max(xmin, Math.Min(g, xmax))).ToList();

TargetSymbol = targetSymbol;

this.trainingSet = trainingSet;

EvaluateFitness();

}

// Функция активации: если сумма произведений >= 0, то 1, иначе 0

public static int Predict(List<double> weights, int[] input)

{

double sum = 0;

for (int i = 0; i < weights.Count; i++)

sum += weights[i] * input[i];

return sum >= 0 ? 1 : 0;

}

public void EvaluateFitness()

{

int errorCount = 0;

foreach (var sample in trainingSet)

{

int expected = (sample.Label == TargetSymbol) ? 1 : 0;

int output = Predict(Weights, sample.Input);

if (output != expected)

errorCount++;

}

Fitness = (double)errorCount / trainingSet.Count * 100.0;

}

// Мутация: изменение случайного веса

public void Mutation(double mutationProbability, Random rnd)

{

int index = rnd.Next(Weights.Count);

if (rnd.NextDouble() < mutationProbability)

{

double lowerDelta = XMin / 5.0;

double upperDelta = XMax / 5.0;

double delta = lowerDelta + rnd.NextDouble() * (upperDelta - lowerDelta);

double newVal = Weights[index] + delta;

newVal = Math.Max(XMin, Math.Min(newVal, XMax));

Weights[index] = newVal;

EvaluateFitness();

}

}

// Оператор кроссинговера BLX‑a‑b

public static (GAPerceptronIndividual, GAPerceptronIndividual) BLXabCrossover(

GAPerceptronIndividual parent1,

GAPerceptronIndividual parent2,

double a, double b,

double xmin, double xmax,

Random rnd)

{

if (parent1.Weights.Count != parent2.Weights.Count)

throw new Exception("Размерность хромосом должна совпадать.");

int n = parent1.Weights.Count;

List<double> child1Genes = new List<double>();

List<double> child2Genes = new List<double>();

for (int i = 0; i < n; i++)

{

double x = parent1.Weights[i];

double y = parent2.Weights[i];

double d = Math.Abs(x - y);

double lower, upper;

if (x <= y)

{

lower = x - a * d;

upper = y + b * d;

}

else

{

lower = y - b * d;

upper = x + a * d;

}

double gene1 = lower + rnd.NextDouble() * (upper - lower);

double gene2 = lower + rnd.NextDouble() * (upper - lower);

gene1 = Math.Max(xmin, Math.Min(gene1, xmax));

gene2 = Math.Max(xmin, Math.Min(gene2, xmax));

child1Genes.Add(gene1);

child2Genes.Add(gene2);

}

GAPerceptronIndividual child1 = new GAPerceptronIndividual(child1Genes, xmin, xmax, parent1.TargetSymbol, parent1.trainingSet);

GAPerceptronIndividual child2 = new GAPerceptronIndividual(child2Genes, xmin, xmax, parent1.TargetSymbol, parent1.trainingSet);

return (child1, child2);

}

}

}