Смекни!
smekni.com

Генетический алгоритм 3 (стр. 6 из 6)

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}&bsol;n&bsol;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();

}

}

}