Использование шанса для генерации чисел - C#
Формулировка задачи:
Есть одна статья пытаюсь реализовать данный алгоритм на C#, вся проблема возникает когда надо выбрать пары. Дайте пример и если можно прокомментируйте что в нём происходит.
Решение задачи: «Использование шанса для генерации чисел»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication152 { class Program { static void Main(string[] args) { var res = new Solver().Solve(c => Math.Abs(1*c[0] + 2*c[1] + 3*c[2] + 4*c[3] - 30)); Console.WriteLine(res); Console.ReadLine(); } } class Solver { public Chromosome Solve(Func<Chromosome, int> fitness) { //создаем популяцию var pop = new Population(10, fitness, 4); //пока не найдено решение... do { //суммарная подходящесть var sum = pop.Sum(c => c.Likehood); //создем потомков var newPop = new Population(); for (int i = 0; i < pop.Count; i++) { var chr = new Chromosome(fitness, pop.GetRandom(sum), pop.GetRandom(sum)); if(chr.Fitness == 0)//нашли решение return chr; newPop.Add(chr);//добавляем в популяцию } //заменяем популяцию pop = newPop; } while (true); } } class Population: List<Chromosome> { private static Random rnd = new Random(1); public Population(int chromosomesCount, Func<Chromosome, int> fitness, int koeffCount) { for (int i = 0; i < chromosomesCount; i++) Add(new Chromosome(fitness, koeffCount)); } public Population() { } public Chromosome GetRandom(float sumLikehood) { //находим сулчайную хромосому пропорционально значениям Likehood var r = rnd.NextDouble() * sumLikehood; foreach(var chr in this) { r -= chr.Likehood; if (r <= float.Epsilon) return chr; } return this[Count - 1]; } } class Chromosome : List<int> { public static int MinKoeff = 1; public static int MaxKoeff = 30; private static Random rnd = new Random(1); public float Likehood { get { return 1f / (1 + Fitness); } } public int Fitness { get; private set; } public Chromosome(Func<Chromosome, int> fitness, int koeffCount) { for (int i = 0; i < koeffCount; i++) Add(MinKoeff + rnd.Next(MaxKoeff - MinKoeff + 1)); Fitness = fitness(this); } public Chromosome(Func<Chromosome, int> fitness, Chromosome parent1, Chromosome parent2) { for (int i = 0; i < parent1.Count; i++) { //берем ген отца или матери var k = rnd.Next(0, 2) == 0 ? parent1[i] : parent2[i]; //добавляем мутацию k += rnd.Next(3) - 1; //соблюдаем границы if (k < MinKoeff) k = MinKoeff; if (k > MaxKoeff) k = MaxKoeff; // Add(k); } Fitness = fitness(this); } public override string ToString() { return string.Join(" ", this); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д