Реализация алгоритма на 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;
List person = 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(List g)
{
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(List g, RichTextBox richTextBox1)
{
for (int i = 0; i < g.Count; i++)
richTextBox1.Text += g[i].ToString() + "\n";
//richTextBox1.Text +=);
}
///
/// Сортировка коллекции
///
public static List Sort(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;
}
И вот что получаем:
Комментарии 0
Комментариев пока нет, стань первым!