- •Реализация персептрона:
- •2.1. Точка входа в программу Program.Cs
- •2.2. Входные данные InputData.Cs
- •2.3. Реализация персептрона по методу Хебба Perceptron.Cs
- •2.4 Вывод информации OutputInformation.Cs
- •4. Вывод информации – OutputInformation.Cs
- •Описание
- •1. Точка входа – Program.Cs
- •2. Входные данные – InputData.Cs
- •3. Реализация персептрона – Perceptron.Cs
- •Взаимосвязь скриптов
- •Реализация генетического алгоритма:
- •1) Скрипт Program.Cs
- •2) Скрипт Population.Cs
- •3) Скрипт Individual.Cs
- •4) Скрипт Gen.Cs
- •5) Скрипт EvolutionManager.Cs
- •6) Скрипт Chromosome.Cs
- •Описание
- •Взаимосвязь между скриптами
- •Нейроэволюционный алгоритм:
- •1) Скрипт Program.Cs
- •2) Скрипт gaEvolutionManager
- •3) Скрипт TrainingSample.Cs
- •4) Скрипт OutputInformation.Cs
- •5) Скрипт InputData.Cs
- •6) Скрипт gaPerceptronIndividual.Cs
- •Описание
- •Общая схема работы и взаимосвязь модулей
- •Тестирование и демонстрация:
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);
}
}
}
