Загрузка страницы..
Моделирование генетического алгоритма на C#
<span style="color: #28A84C">C#</span>
2014-04-15T16:04 15 апр. 2014 16:04
Просмотров: 3432

Реализация алгоритма на 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

Коментарий пока нет, стань первым!

Добавить комментарий

Яндекс.Метрика Яндекс.Метрик