for (int i = 0; i < resultW_temp.Length; i++)
{
for (int j = 0; j < resultW_temp[0].Length; j++)
{
if (resultW[0][i][j] != resultW_temp[1][i][j])
{
str2[i] = false;
break;
}
}
}
if (!str1[rnd1])//если случайные строки не равны
{
for (int j = 0; j < resultW_temp[0].Length; j++)
{
resultW[0][rnd1][j] = resultW_temp[1][rnd1][j];
resultW[1][rnd1][j] = resultW_temp[0][rnd1][j];
}
}
else
{
//выбираем первую не равную пару строк
for (int i = 0; i < resultW_temp.Length; i++)
{
if (!str1[i])
{
for (int j = 0; j < resultW_temp[0].Length; j++)
{
resultW[0][i][j] = resultW_temp[1][i][j];
resultW[1][i][j] = resultW_temp[0][i][j];
}
break;
}
else//если таких пар не найдено то меняем случайные строки
{
for (int j = 0; j < resultW_temp[0].Length; j++)
{
resultW[0][rnd1][j] = rnd.NextDouble() * 0.1;
resultW[1][rnd1][j] = rnd.NextDouble() * 0.1;
}
}
}
}
if (s > 500)
s = 0;
else
s++;
return resultW;
}
static SandY neuro(double[][] X, double[][] W)// типа нейрон
{
SandY result;
double alfa = 1;// коэфицент сигмоидности
result.S = 0;// результирующая сумма
for (int i = 0; i < X.Length; i++)
{
for (int j = 0; j < X[i].Length; j++)
{
result.S += X[i][j] * W[i][j];// комбинаторим
}
}
result.Y = 1 / (1 + Math.Exp(alfa * result.S));// функция активизации
return result;
}
static void Main(string[] args)
{
double[][] input_x0 = new double[5][];
double[][] input_x1 = new double[5][];
double[][][] weight = new double[2][][];// веса для двух нейрон
for (int i = 0; i < 5; i++)
{
input_x0[i] = new double[5];
input_x1[i] = new double[5];
}
int seed = 0;
for (int n = 0; n < 2; n++)//заполняем веса случайными значениями от 0,0 до 1,0
{
weight[n] = new double[5][];
for (int i = 0; i < 5; i++)
{
weight[n][i] = new double[5];
for (int j = 0; j < 5; j++)
{
weight[n][i][j] = new Random(seed).NextDouble()*0.1;
seed++;
}
}
}
//тестовая матрица для 0
input_x0[0][0] = 0;
input_x0[0][1] = 1;
input_x0[0][2] = 1;
input_x0[0][3] = 1;
input_x0[0][4] = 0;
input_x0[1][0] = 1;
input_x0[1][1] = 0;
input_x0[1][2] = 0;
input_x0[1][3] = 0;
input_x0[1][4] = 1;
input_x0[2][0] = 1;
input_x0[2][1] = 0;
input_x0[2][2] = 0;
input_x0[2][3] = 0;
input_x0[2][4] = 1;
input_x0[3][0] = 1;
input_x0[3][1] = 0;
input_x0[3][2] = 0;
input_x0[3][3] = 0;
input_x0[3][4] = 1;
input_x0[4][0] = 0;
input_x0[4][1] = 1;
input_x0[4][2] = 1;
input_x0[4][3] = 1;
input_x0[4][4] = 0;
//тестовая матрица для 1
input_x1[0][0] = 0;
input_x1[0][1] = 0;
input_x1[0][2] = 1;
input_x1[0][3] = 0;
input_x1[0][4] = 0;
input_x1[1][0] = 0;
input_x1[1][1] = 1;
input_x1[1][2] = 1;
input_x1[1][3] = 0;
input_x1[1][4] = 0;
input_x1[2][0] = 0;
input_x1[2][1] = 0;
input_x1[2][2] = 1;
input_x1[2][3] = 0;
input_x1[2][4] = 0;
input_x1[3][0] = 0;
input_x1[3][1] = 0;
input_x1[3][2] = 1;
input_x1[3][3] = 0;
input_x1[3][4] = 0;
input_x1[4][0] = 0;
input_x1[4][1] = 0;
input_x1[4][2] = 1;
input_x1[4][3] = 0;
input_x1[4][4] = 0;
double nu = 0.01;//скорость обучения,которая на самом деле никакая ни скорость а шаг изменения веса
SandY [] neuro_data = new SandY[2];
double[] y = new double[2];// результат
double[] d0 = new double[2];// идеальные значения для 0
double[] d1 = new double[2];//идеальные значения для 1
d0[0] = 1.0;
d0[1] = 0.0;
d1[0] = 0.0;
d1[1] = 1.0;
int step = 0;
double[] delta = new double[2];
/*
Console.WriteLine("=============================================");
Console.WriteLine("по алгоритму обратного распространения ошибки");
Console.WriteLine("=============================================");
/////////////////////////////////////////////////
//по алгоритму обратного распространения ошибки//
/////////////////////////////////////////////////
while(step <=1000000)
{
step++;
for (int neuron = 0; neuron < 2; neuron ++ )// всего два нейрона
{
neuro_data[neuron] = neuro(input_x0, weight[neuron]);
Console.Write(" Нейрон : {0} Y={1} S={2}\n\n", neuron, neuro_data[neuron].Y, neuro_data[neuron].S);
}
if (Math.Abs(neuro_data[0].Y - neuro_data[1].Y) >= 0.9)
break;
for (int neuron = 0; neuron < 2; neuron++)
{
delta[neuron] = (d0[neuron] - neuro_data[neuron].Y) * neuro_data[neuron].Y * (1 - neuro_data[neuron].Y);
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
weight[neuron][i][j] = weight[neuron][i][j] - nu * delta[neuron] * input_x0[i][j];
}
}
}
}
if (neuro_data[0].Y > neuro_data[1].Y)
Console.WriteLine(" Результат 0");
else
Console.WriteLine(" Результат 1");
*/
//////////////////////////////
//по генетическому алгоритму//
//////////////////////////////
Console.WriteLine("=============================================");
Console.WriteLine("=========по генетическому алгоритму==========");
Console.WriteLine("=============================================");
//целевая функция - это функция ошибки нейрона E(w) = 1/2*(y-d)^2
// где y - реальное значение ф-ции активизации для нейрона, d - идеальное значенние
int kolPopul = 8;
double[][][][] weightGA = new double[2][][][];// матрицы весов для 2- х нейронов
for (int n = 0; n < 2; n++)
{
weightGA[n] = new double[kolPopul][][];// матрицы весов для 4- х особей каждого нейрона
seed = 0;
for (int o = 0; o < kolPopul; o++)//заполняем веса случайными значениями от 0,0 до 0,1
{
weightGA[n][o] = new double[5][];
for (int i = 0; i < 5; i++)
{
weightGA[n][o][i] = new double[5];
for (int j = 0; j < 5; j++)
{
//Console.WriteLine(new Random(seed).NextDouble()*0.1);
weightGA[n][o][i][j] = new Random(seed).NextDouble() * 0.1;
seed++;
}
}
}
}
double[][] F = new double[2][]; // массив для хранения значений целевой функции для 4-х поколеий для двух нейронов
for (int n = 0; n < 2; n++)
{
F[n] = new double[kolPopul];
}
double[][] F_temp = new double[2][]; // массив для хранения значений целевой функции для расширенной популяции для двух нейронов
for (int n = 0; n < 2; n++)
{
F_temp[n] = new double[kolPopul + kolPopul];
}
double[][] F_potomki = new double[2][]; // массив для хранения значений целевой функции для потомков для двух нейронов
for (int n = 0; n < 2; n++)
{
F_potomki[n] = new double[kolPopul];
}
int k = 0;
SandY[] neuro_dataGA = new SandY[2];
while (k < 10)//количество поколений
{
Console.WriteLine("============== Поколение {0} =================", k);
k++;
for (int neuron = 0; neuron < 2; neuron++)
{
Console.WriteLine("======== Нейрон {0} ========", neuron);
for (int n_osob = 0; n_osob < kolPopul; n_osob++)// вычисляем значение целевой функции для каждой особи
{
neuro_dataGA[neuron] = neuro(input_x0, weightGA[neuron][n_osob]);
F[neuron][n_osob] = (0.5*(neuro_dataGA[neuron].Y - d0[neuron]) * (neuro_dataGA[neuron].Y - d0[neuron]));// целевая ф - я
Console.WriteLine(F[neuron][n_osob]);
}
//выбираем 4 пары особей для скрещивания
int[] bestParent = new int[4]; //четыре родителя
bestParent = NMinIndexesValue(4, F[neuron]);//находим четырех лучших родителей
Console.WriteLine("Особи для размножения");
Console.WriteLine(F[neuron][bestParent[0]]);
Console.WriteLine(F[neuron][bestParent[1]]);
Console.WriteLine(F[neuron][bestParent[2]]);
Console.WriteLine(F[neuron][bestParent[3]]);
Console.WriteLine("####################");
double[][][][] potomki = new double[4][][][];
for (int num = 0; num < 4; num++)
{
potomki[num] = new double[2][][];
}
//скрещиваем как-бы случайным образом родителей и плодим потомков
int vm = ver.Next(1, 4);
potomki[0] = Screshivanie(weightGA[neuron][bestParent[0]], weightGA[neuron][bestParent[vm]]);
vm = ver.Next(0, 3);
potomki[1] = Screshivanie(weightGA[neuron][bestParent[3]], weightGA[neuron][bestParent[vm]]);
vm = ver.Next(0, 4);
potomki[2] = Screshivanie(weightGA[neuron][bestParent[1]], weightGA[neuron][bestParent[vm]]);
vm = ver.Next(0, 4);
potomki[3] = Screshivanie(weightGA[neuron][bestParent[2]], weightGA[neuron][bestParent[vm]]);
vm = ver.Next(0,7);//определяет для кого из потомков случайным образом сработает мутация
if (vm == 0)
{
mutation(potomki[0][0]);
}
if (vm == 1)
{
mutation(potomki[0][1]);
}
if (vm == 2)
{
mutation(potomki[1][0]);
}
if (vm == 3)
{
mutation(potomki[1][1]);
}
if (vm == 4)
{
mutation(potomki[2][0]);
}
if (vm == 5)
{
mutation(potomki[2][1]);
}
if (vm == 6)
{
mutation(potomki[3][0]);
}
if (vm == 7)
{
mutation(potomki[3][1]);
}
Console.WriteLine(" Целевая ф - я потомков ");
double[][][] temp_weight = new double[kolPopul + kolPopul][][];
int nomer = 0;
for (int num = 0; num < 4; num++)//переписываем веса потомков в один массив
{
for (int n = 0; n < 2; n++)
{
temp_weight[nomer] = potomki[num][n];
double temp_y = neuro(input_x0, potomki[num][n]).Y;
F_potomki[neuron][nomer] = (0.5*(temp_y - d0[neuron]) * (temp_y - d0[neuron]));// целевая ф - я
Console.WriteLine(F_potomki[neuron][nomer]);
nomer++;
}
}
for (int num = 0; num < kolPopul; num++)// добавляем к массиву веса родителей
{
temp_weight[num + kolPopul] = weightGA[neuron][num];
}
Console.WriteLine("Целевая ф-я расширенной популяции");
for (int n_osob = 0; n_osob < kolPopul + kolPopul; n_osob++)//вычисляем значение целевой функции для каждой особи
{
double temp_y = neuro(input_x0, temp_weight[n_osob]).Y;
F_temp[neuron][n_osob] = (0.5*(temp_y - d0[neuron]) * (temp_y - d0[neuron]));// целевая ф - я
}
//Удаляем 4 особи с самым большим значением целевой функции
//на след. итерацию переходят 4 особи с наименьшими значениями целевой ф-ции
int[] minimum = new int[kolPopul];
minimum = NMinIndexesValue(8, F_temp[neuron]);
for (int n = 0; n < kolPopul; n++)//копируем данные из промежуточного массива в исходный
{
weightGA[neuron][n] = temp_weight[minimum[n]];
}
}
}
Console.ReadKey();
}
}
}