//Создать клон хромососы public Chromosome makeClone() { Chromosome clone = new Chromosome(countGen, rnd); for (int i = 0; i < countGen; i++) { clone.gens[i] = gens[i]; } clone.fitness = fitness; return clone; }
//Инициализируем public override void init() { for (int i = 0; i < _countChromosome; i++) { if (_typeSolution == staticConst.INTEGER_RESULT) { _arrayChromosomes[i] = new Chromosome(_countGenChromosome, _rnd).initIntRandom(5); } else { _arrayChromosomes[i] = new Chromosome(_countGenChromosome, _rnd).initRandom(); } calculateFitness(_arrayChromosomes[i]); } }
//Сменить поколение public override void nextGeneration() { //Создаем новый массив Chromosome[] childChromosomes = new Chromosome[_countChromosome]; Chromosome[] parentChromosomes = new Chromosome[_countChromosome]; Chromosome[] childrens; int parent1; int parent2; //Выбираем родителей for (int i = 0; i < _countChromosome; i++) { //Турнирный выбор parentChromosomes[i] = tournament(10); } int count = _countChromosome / 2; //Дети for (int i = 0; i < count; i++) { parent1 = _rnd.Next(_countChromosome - 1); parent2 = _rnd.Next(_countChromosome - 1); childrens = makeLinearCross(parentChromosomes[parent1], parentChromosomes[parent2]); childChromosomes[i * 2] = childrens[0]; if((i*2 + 1) <= _countChromosome) childChromosomes[i*2 + 1] = childrens[1] ; //Мутация в pM процентах double num = _rnd.NextDouble(); if (num <= _сhanceMutation) makeMutation(childChromosomes[i]); calculateFitness(childChromosomes[i]); } //Меняем поколение _arrayChromosomes = childChromosomes; }
//Скрещивание private Chromosome makeCross(Chromosome Chr1, Chromosome Chr2) { Chromosome children = new Chromosome(_countGenChromosome, _rnd); for (int i = 0; i < _countGenChromosome; i++) { if (_rnd.NextDouble() <= _сhanceMutation) { children.gens[i] = Chr2.gens[i]; } else { children.gens[i] = Chr1.gens[i]; } } return children; }
//Вывод лучшей хромосомы public ContainerResult bestChromosome() { ContainerResult result = new ContainerResult(); Chromosome bestChromosome = new Chromosome(_countGenChromosome, _rnd); for (int i = 0; i < _countChromosome; i++) { if (_arrayChromosomes[i].fitness > bestChromosome.fitness) { bestChromosome = _arrayChromosomes[i]; } } calculateFitness(bestChromosome, true); result.vector = new List<double>(); for (int i = 0; i < _countGenChromosome; i++) { result.vector.Add(bestChromosome.gens[i]); } result.fitness = bestChromosome.fitness; result.realResult = calculateTargetFunction(bestChromosome); double sign = (_containerFunction.cursor == staticConst.SIGNMIN) ? -1 : 1; result.realResult = result.realResult * sign; result.realRestrict = new List<double>(); foreach (MatrixItem item in _containerFunction.matrix) { result.realRestrict.Add(calculateRestrictFunction(item, bestChromosome)); } return result; }
//Мутация private void makeMutation(Chromosome Chr1) { for (int i = 0; i < _countGenChromosome; i++) { UInt64 x = BitConverter.ToUInt64(BitConverter.GetBytes(Chr1.gens[i]), 0); UInt64 mask = 1; mask <<= _rnd.Next(63); x ^= mask; Chr1.gens[i] = BitConverter.ToDouble(BitConverter.GetBytes(x), 0); } }
//Скрещивание private Chromosome makeCross(Chromosome Chr1, Chromosome Chr2) { Chromosome children = new Chromosome(_countGenChromosome, _rnd); for (int i = 0; i < _countGenChromosome; i++) { children.gens[i] = Cross(Chr1.gens[i], Chr2.gens[i]) ; if (_typeSolution == staticConst.INTEGER_RESULT) { children.gens[i] = Math.Round(children.gens[i], 0); } } return children; }
//Фитнесс функция protected void calculateFitness(Chromosome Chr, bool write) { double M; double straf = 0; double result = 0; result = calculateTargetFunction(Chr); foreach (MatrixItem item in _containerFunction.matrix) { M = 0; M = calculateRestrictFunction(item, Chr); //ТРИ СИТУАЦИИ if (item.Sign == staticConst.SIGNEQUALLY) { double delta = (M - item.restriction); straf += straf + result * (delta / item.restriction); } else if (item.Sign == staticConst.SIGNLESSEQUALLY) { if (M > item.restriction) { straf += straf + result * (M / item.restriction); } } else if (item.Sign == staticConst.SIGNMOREQUALLY) { if (M < item.restriction) { straf += straf + result * (item.restriction / M); } } } Chr.fitness = result - straf; }
protected void calculateFitness(Chromosome Chr) { calculateFitness(Chr, false); }
//Целевая функция protected double calculateTargetFunction(Chromosome Chr) { double result = 0; double sign = (_containerFunction.cursor == staticConst.SIGNMIN) ? -1 : 1; for (int i = 0; i < _countGenChromosome; i++) { result += sign * _containerFunction.fitness[i] * Chr.gens[i]; } return result; }
//Вычисления значения ограничения protected double calculateRestrictFunction(MatrixItem item, Chromosome Chr) { double value = 0; for (int i = 0; i < _countGenChromosome; i++) { value += item.items[i] * Chr.gens[i]; } return value; }
//Скрещивание private Chromosome[] makeLinearCross(Chromosome Chr1, Chromosome Chr2) { Chromosome[] childrens = new Chromosome[3] ; childrens[0] = new Chromosome(_countGenChromosome, _rnd); childrens[1] = new Chromosome(_countGenChromosome, _rnd); childrens[2] = new Chromosome(_countGenChromosome, _rnd); for (int i = 0; i < _countGenChromosome; i++ ) { childrens[0].gens[i] = (Chr1.gens[i] + Chr2.gens[i]) / 2; childrens[1].gens[i] = (3 * Chr1.gens[i] + Chr2.gens[i]) / 2; childrens[2].gens[i] = (-Chr1.gens[i] + 3 * Chr2.gens[i]) / 2; if (childrens[0].gens[i] <= 0) childrens[0].gens[i] = 0; if (childrens[1].gens[i] <= 0) childrens[1].gens[i] = 0; if (childrens[2].gens[i] <= 0) childrens[2].gens[i] = 0; if (_typeSolution == staticConst.INTEGER_RESULT) { childrens[0].gens[i] = Math.Round(childrens[0].gens[i], 0); childrens[1].gens[i] = Math.Round(childrens[1].gens[i], 0); childrens[2].gens[i] = Math.Round(childrens[2].gens[i], 0); } } calculateFitness(childrens[0]); calculateFitness(childrens[1]); calculateFitness(childrens[2]); childrens = sort(childrens); return childrens; }
/* * Cортировка хромосом по фитнесс функции */ private Chromosome[] sort(Chromosome[] massive) { int len = massive.Length ; for (int i = 0; i < len - 1; i++) { int max = i; for (int j = i + 1; j < len; j++) { if (massive[j].fitness > massive[max].fitness) max = j; } if (max != i) { Chromosome container = massive[i]; massive[i] = massive[max]; massive[max] = container; } } return massive; }
//Мутация private void makeMutation(Chromosome Chr1) { int num1 = _rnd.Next(_countChromosome - 1); int num2 = _rnd.Next(_countChromosome - 1); double delta = 0; for (int i = 0; i < _countGenChromosome; i++) { delta = _valueMutation * (_arrayChromosomes[num1].gens[i] - _arrayChromosomes[num2].gens[i]); if (_typeSolution == staticConst.INTEGER_RESULT) { delta = Math.Round(delta, 0); } Chr1.gens[i] = Chr1.gens[i] + delta; if (Chr1.gens[i] <= 0) Chr1.gens[i] = 0; } }
//Скрещивание private Chromosome[] makeArifmeticCross(Chromosome Chr1, Chromosome Chr2) { Chromosome[] childrens = new Chromosome[2]; childrens[0] = new Chromosome(_countGenChromosome, _rnd); childrens[1] = new Chromosome(_countGenChromosome, _rnd); for (int i = 0; i < _countGenChromosome; i++) { childrens[0].gens[i] = _B * Chr1.gens[i] + (1 - _B) * Chr2.gens[i]; childrens[1].gens[i] = _B * Chr2.gens[i] + (1 - _B) * Chr1.gens[i]; ; if (childrens[0].gens[i] <= 0) childrens[0].gens[i] = 0; if (childrens[1].gens[i] <= 0) childrens[1].gens[i] = 0; if (_typeSolution == staticConst.INTEGER_RESULT) { childrens[0].gens[i] = Math.Round(childrens[0].gens[i], 0); childrens[1].gens[i] = Math.Round(childrens[1].gens[i], 0); } } calculateFitness(childrens[0]); calculateFitness(childrens[1]); return childrens; }