Реализация алгоритма на C#:
Класс Person
public class Person { ////// Кол-во генов /// int n; /// /// Массив генов /// public int[] g; /// /// Конструкторы /// public Person() { this.n = 0; this.g = new int[this.n]; } public Person(int n) { this.n = n; this.g = new int[n]; /* for (int i = 0; i < n; i++) this.g[i] = rn.Next(2);*/ } public Person(int[] a) { this.n = a.Length; this.g = a; } public Person(Person g) { this.n = g.n; this.g = g.g; } /// /// Количество генов /// public int Length { get { return this.n; } } /// /// Преобразует в строку /// /// [x1, x2, ..., xn] public override string ToString() { int sym = 0; string s = "["; for (int i = 0; i < this.n; i++) { s += this.g[i] + ", "; sym += this.g[i]; } s = s.Substring(0, s.Length - 2); s += "] ("+sym+")"; return s; } ////// Меняем случайный ген /// public void Re() { Random rn = new Random(); int k = (int)rn.Next(this.n); //Console.WriteLine(k); if (this.g[k] == 0) this.g[k] = 1; else this.g[k] = 0; } /// /// Сумма генов /// public int SumI { get { int s = 0; foreach (int c in this.g) s += c; return s; } } public static Person operator +(Person g1, Person g2) { if (g1.n == g2.n) { Random rn = new Random(); int k = rn.Next(g1.n); Console.WriteLine("Скрещивание по к=" + k); Person newg = new Person(g1.n); for (int i = 0; i < g1.n; i++) if (i < k) newg.g[i] = g1.g[i]; else newg.g[i] = g2.g[i]; return newg; } else throw new IndexOutOfRangeException("Ошибка! Не совпадение размерностей генов особей!"); } //Индексатор, позволяющий по индексу 0 обращаться к полю first, по индексу 1 – к полю second, //при других значениях индекса выдается сообщение об ошибке. /// /// Обращение к гену по индексу /// /// индекс /// элемент массива public int this[int i] { get { if (i >= 0 && i < this.n) return this.g[i]; else throw new IndexOutOfRangeException("Ошибка! Выход за границы массива!"); } set { if (i >= 0 && i < this.n) this.g[i] = value; else throw new IndexOutOfRangeException("Ошибка! Выход за границы массива!"); } } }
Создадим форму и добавим несколько элементов:
Код кнопки:
public void button1_Click(object sender, EventArgs e) { richTextBox1.Text = ""; DateTime dt = DateTime.Now; int n = int.Parse(textBoxPerson.Text); int m = int.Parse(textBoxСhromosome.Text); int i = 0, j = 0; int k = 0; Listperson = new List (); for (i = 0; i < n; i++) person.Add(new Person(m)); richTextBox1.Text += "Сгенерируем Особи...\n"; //ГЕНЕРИРОВАНИЕ Random rn2 = new Random(); for (i = 0; i < person.Count; i++) for (j = 0; j < person[i].g.Length; j++) person[i][j] = rn2.Next(2); //Вывод int max = 0; int l = 0;//число совпадений int age = 1; while (l != 2 && age < 500) { labelgGeneration.Text = age.ToString(); labelgGeneration.Update(); richTextBox1.Text += "\n=== " + age + " поколение ===\n"; max = Max(person); labelBest.Text = max.ToString(); labelBest.Update(); richTextBox1.Text += "Максимум =" + max + "\n"; Print(person, richTextBox1); richTextBox1.Text += "Cкрещиваем особей:\n"; List person_child = new List (); for (i = 0; i < person.Count - 1; i += 2) { k = rn.Next(1, m - 1); person_child.Add(new Person(m)); person_child.Add(new Person(m)); for (j = 0; j < m; j++) if (j <= k) { person_child[i][j] = person[i][j]; person_child[i + 1][j] = person[i + 1][j]; } else { person_child[i][j] = person[i + 1][j]; person_child[i + 1][j] = person[i][j]; } } Print(person_child, richTextBox1); richTextBox1.Text += "Мутирвание особей(родителей):\n"; List person_myt = new List (); for (i = 0; i < n / 2; i++) { person_myt.Add(new Person(m)); for (j = 0; j < m; j++) person_myt[i][j] = person[i][j]; person_myt[i].Re(); } Print(person_myt, richTextBox1); //Сортируем List temp = new List (); for (i = 0; i < person.Count; i++) temp.Add(new Person(person[i].g)); for (i = 0; i < person_child.Count; i++) temp.Add(new Person(person_child[i].g)); for (i = 0; i < person_myt.Count; i++) temp.Add(new Person(person_myt[i].g)); richTextBox1.Text += "Собираем всех в один массив\n"; Print(temp, richTextBox1); temp = Sort(temp); richTextBox1.Text += "Сортируем массив\n"; Print(temp, richTextBox1); temp.RemoveRange(n, temp.Count - (n)); richTextBox1.Text += "Оставляем " + n + " лучших\n"; Print(temp, richTextBox1); //richTextBox1.Text += "Претендент:\n"; //Print(temp, richTextBox1); int max2 = Max(temp); // richTextBox1.Text += "Максимум =" + max2 + "\n"; person = (List )temp; age++; if (max2 < max) { l = -1; break; } else if (max == max2) { l++; if (l == 1) break; } else l = 0; } switch (l) { case -1: label5.Text = "Спад"; break; case 1: label5.Text = "Устойчивость"; richTextBox1.Text += "\n=== " + age + " поколение ===\n"; richTextBox1.Text += "Максимум =" + Max(person) + "\n"; Print(person, richTextBox1); labelgGeneration.Text = age.ToString(); labelBest.Text = max.ToString(); break; default: label5.Text = "Произошло что то не известное"; break; } richTextBox1.Text += "Время работы программы:" + (DateTime.Now - dt).ToString(); }
И другие ф-ии:
public static Random rn = new Random(); public static Random rn = new Random(); ////// Поиск максимального кол-ва хромосом у особи /// /// Особь ///Максимальное кол-во public static int Max(Listg) { int m = 0; for (int i = 0; i < g.Count; i++) { int temp = 0; for (int j = 0; j < g[i].Length; j++) temp += g[i][j]; if (m < temp) m = temp; // richTextBox1.Text +="s"+(i+1)+"="+m); } return m; } /// /// Вывод геннов особи в консоль /// /// Особь public static void Print(Listg, RichTextBox richTextBox1) { for (int i = 0; i < g.Count; i++) richTextBox1.Text += g[i].ToString() + "\n"; //richTextBox1.Text +=); } /// /// Сортировка коллекции /// public static ListSort(List temp) { int i, j; for (i = 0; i < temp.Count; i++) { for (j = 0; j < temp.Count - i - 1; j++) { if (temp[j].SumI < temp[j + 1].SumI) { int[] b = (int[])temp[j].g; temp[j].g = (int[])temp[j + 1].g; temp[j + 1].g = (int[])b; } } } return temp; }
И вот что получаем:
Исходники
Добавить комментарий