Ejemplo n.º 1
0
        private static List <Genotip> Crossengover(Genotip parent_one, Genotip parent_two, List <int> employees, int max_count_employees, Random rnd) //равномерное скрещивание
        //входные данные - генотип из родительского пула 1, генотип из родительского пула 2, список идентификаторов сотрудников, максимальное число сотрудников на проект, рандомайзер
        //выходные данные - массив генотипов
        {
            List <int> empl1 = new List <int>();  //массив сотрудников 1 потомка
            List <int> empl2 = new List <int>();  //массив сотрудников 2 потомка

            List <int> none_empl_on1 = new List <int>();
            List <int> none_empl_on2 = new List <int>();

            int sum_par_one = 0;
            int sum_par_two = 0;

            foreach (int em in employees) //заполнение массивов
            {
                int i = em;
                int j = em;
                empl1.Add(i);
                empl2.Add(j);
            }


            List <Genotip> new_individs = new List <Genotip>();         //массив дочерних генотипов

            Genotip child_one = new Genotip();                          //потомок 1
            Genotip child_two = new Genotip();                          //потомок 2

            for (int i = 0; i < parent_one.Get_chromosome_count(); ++i) //для всех проектов в хромосоме  выбирается информация о соответствующем проекте из обеих хромосом
            {
                int proj_id = parent_one.Chromosome[i].ID;

                Project_chromosome par1 = parent_one.Chromosome[i];

                Project_chromosome par2 = new Project_chromosome();

                foreach (Project_chromosome pr in parent_two.Chromosome)
                {
                    if (pr.ID == proj_id)
                    {
                        par2 = pr;
                        break;
                    }
                }

                /* count_empl_on_par1.Add(par1.Get_count_employees());
                 * count_empl_on_par2.Add(par2.Get_count_employees());*/

                sum_par_one += par1.Get_count_employees();                                                                                           //подсчёт суммарного числа сотрудников в родителе 1
                sum_par_two += par2.Get_count_employees();                                                                                           //подсчёт суммарного числа сотрудников в родителе 2

                int max_count = (par1.Get_count_employees() > par2.Get_count_employees()) ? par1.Get_count_employees() : par2.Get_count_employees(); //максимум - максимальная длина цепочки сотрудников в проекте из 2 хромсом

                Project_chromosome ch1 = new Project_chromosome();
                ch1.ID = proj_id;
                Project_chromosome ch2 = new Project_chromosome();
                ch2.ID = proj_id;

                for (int j = 0; j < max_count; ++j)
                {
                    int randomize = rnd.Next(0, 2);
                    //случайное число показывает порядок копирвоания: если 1 - то из 1 родителя в 1 потомка, из 2 родителя во 2 потомка, 0 - наоборот
                    // int rand2 = randomize;
                    //если найдена попытка повторного добавления одного и того же сотрудника в потомка, то идентификатор этого сотрудника заносится в список сотрудников первого порядка для другого потомка
                    if (randomize == 1)
                    {
                        if (j < par1.Get_count_employees())
                        {
                            if (empl1.IndexOf(par1.Employees[j]) != -1)
                            {
                                ch1.Add_employees(par1.Employees[j]);
                                empl1.Remove(par1.Employees[j]);
                            }
                            else
                            {
                                none_empl_on2.Add(par1.Employees[j]);
                            }
                        }


                        if (j < par2.Get_count_employees())
                        {
                            if (empl2.IndexOf(par2.Employees[j]) != -1)
                            {
                                ch2.Add_employees(par2.Employees[j]);
                                empl2.Remove(par2.Employees[j]);
                            }
                            else
                            {
                                none_empl_on1.Add(par2.Employees[j]);
                            }
                        }
                    }
                    else
                    {
                        if (j < par2.Get_count_employees())
                        {
                            if (empl1.IndexOf(par2.Employees[j]) != -1)
                            {
                                ch1.Add_employees(par2.Employees[j]);
                                empl1.Remove(par2.Employees[j]);
                            }
                            else
                            {
                                none_empl_on2.Add(par2.Employees[j]);
                            }
                        }


                        if (j < par1.Get_count_employees())
                        {
                            if (empl2.IndexOf(par1.Employees[j]) != -1)
                            {
                                ch2.Add_employees(par1.Employees[j]);
                                empl2.Remove(par1.Employees[j]);
                            }
                            else
                            {
                                none_empl_on1.Add(par1.Employees[j]);
                            }
                        }
                    }
                }

                child_one.Add_chromosome(ch1);
                child_two.Add_chromosome(ch2);

                List <int> max_empl_in_project = new List <int>();

                //если массивы предположительных сотрудников для потомков не пусты, то производится занесение сотрудников в соответствующего потомка, при нехватке в нём сотрудников
                //распределение сотрудников по проектам производится аналогично способу, используемому при формировании стартового поколения

                if (none_empl_on1.Count > 0)
                {
                    child_one.Chromosome = InsertionSort(child_one.Chromosome);
                }

                while (none_empl_on1.Count > 0 & max_empl_in_project.Count < child_one.Get_chromosome_count())
                {
                    int num      = rnd.Next(none_empl_on1.Count);
                    int employee = none_empl_on1.ElementAt(num);



                    bool flag     = false;
                    bool del_flag = true;

                    while (flag == false)
                    {
                        if (empl1.IndexOf(employee) == -1)
                        {
                            break;
                        }

                        foreach (Project_chromosome pr in child_one.Chromosome)
                        {
                            int ch = rnd.Next(2);

                            if (ch == 1)
                            {
                                if (pr.Get_count_employees() < max_count_employees)
                                {
                                    pr.Add_employees(employee);
                                    flag = true;
                                    break;
                                }
                                else
                                {
                                    if (max_empl_in_project.IndexOf(pr.ID) == -1)
                                    {
                                        max_empl_in_project.Add(pr.ID);
                                        if (max_empl_in_project.Count == child_one.Get_chromosome_count())
                                        {
                                            flag     = true;
                                            del_flag = false;
                                        }
                                    }
                                    continue;
                                }
                            }
                        }
                    }

                    child_one.Chromosome = InsertionSort(child_one.Chromosome);

                    if (del_flag)
                    {
                        none_empl_on1.RemoveAt(num);
                        empl1.Remove(employee);
                    }
                }

                max_empl_in_project.Clear();

                if (none_empl_on2.Count > 0)
                {
                    child_two.Chromosome = InsertionSort(child_two.Chromosome);
                }

                while (none_empl_on2.Count > 0 & max_empl_in_project.Count < child_two.Get_chromosome_count())
                {
                    int num      = rnd.Next(none_empl_on2.Count);
                    int employee = none_empl_on2.ElementAt(num);


                    bool flag     = false;
                    bool del_flag = true;

                    while (flag == false)
                    {
                        if (empl2.IndexOf(employee) == -1)
                        {
                            break;
                        }

                        foreach (Project_chromosome pr in child_two.Chromosome)
                        {
                            int ch = rnd.Next(2);

                            if (ch == 1)
                            {
                                if (pr.Get_count_employees() < max_count_employees)
                                {
                                    pr.Add_employees(employee);
                                    flag = true;
                                    break;
                                }
                                else
                                {
                                    if (max_empl_in_project.IndexOf(pr.ID) == -1)
                                    {
                                        max_empl_in_project.Add(pr.ID);
                                        if (max_empl_in_project.Count == child_two.Get_chromosome_count())
                                        {
                                            flag     = true;
                                            del_flag = false;
                                        }
                                    }
                                    continue;
                                }
                            }
                        }
                    }

                    child_two.Chromosome = InsertionSort(child_two.Chromosome);

                    if (del_flag)
                    {
                        none_empl_on2.RemoveAt(num);
                        empl2.Remove(employee);
                    }
                }
            }

            int sum_child_one = 0;
            int sum_child_two = 0;

            //поиск числа сотрудников в генотипах потомков
            foreach (Project_chromosome c1 in child_one.Chromosome)
            {
                sum_child_one += c1.Get_count_employees();
            }

            foreach (Project_chromosome c2 in child_two.Chromosome)
            {
                sum_child_two += c2.Get_count_employees();
            }

            //если суммы не совпадают, то дополняем потомков из основного массива для сотрудников

            if (sum_par_one != sum_child_one)
            {
                List <int> max_empl_in_project = new List <int>();

                if (empl1.Count > 0)
                {
                    child_one.Chromosome = InsertionSort(child_one.Chromosome);
                }

                while (empl1.Count > 0 & max_empl_in_project.Count < child_one.Get_chromosome_count())
                {
                    int num      = rnd.Next(empl1.Count);
                    int employee = empl1.ElementAt(num);


                    bool flag     = false;
                    bool del_flag = true;

                    while (flag == false)
                    {
                        foreach (Project_chromosome pr in child_one.Chromosome)
                        {
                            int ch = rnd.Next(2);

                            if (ch == 1)
                            {
                                if (pr.Get_count_employees() < max_count_employees)
                                {
                                    pr.Add_employees(employee);
                                    flag = true;
                                    break;
                                }
                                else
                                {
                                    if (max_empl_in_project.IndexOf(pr.ID) == -1)
                                    {
                                        max_empl_in_project.Add(pr.ID);
                                        if (max_empl_in_project.Count == child_one.Get_chromosome_count())
                                        {
                                            flag     = true;
                                            del_flag = false;
                                        }
                                    }
                                    continue;
                                }
                            }
                        }
                    }

                    child_one.Chromosome = InsertionSort(child_one.Chromosome);

                    if (del_flag)
                    {
                        empl1.RemoveAt(num);
                    }
                }
            }

            if (sum_child_two != sum_par_two)
            {
                List <int> max_empl_in_project = new List <int>();

                if (empl2.Count > 0)
                {
                    child_two.Chromosome = InsertionSort(child_two.Chromosome);
                }

                while (empl2.Count > 0 & max_empl_in_project.Count < child_two.Get_chromosome_count())
                {
                    int num      = rnd.Next(empl2.Count);
                    int employee = empl2.ElementAt(num);


                    bool flag     = false;
                    bool del_flag = true;

                    while (flag == false)
                    {
                        foreach (Project_chromosome pr in child_two.Chromosome)
                        {
                            int ch = rnd.Next(2);

                            if (ch == 1)
                            {
                                if (pr.Get_count_employees() < max_count_employees)
                                {
                                    pr.Add_employees(employee);
                                    flag = true;
                                    break;
                                }
                                else
                                {
                                    if (max_empl_in_project.IndexOf(pr.ID) == -1)
                                    {
                                        max_empl_in_project.Add(pr.ID);
                                        if (max_empl_in_project.Count == child_two.Get_chromosome_count())
                                        {
                                            flag     = true;
                                            del_flag = false;
                                        }
                                    }
                                    continue;
                                }
                            }
                        }
                    }

                    child_two.Chromosome = InsertionSort(child_two.Chromosome);

                    if (del_flag)
                    {
                        empl2.RemoveAt(num);
                    }
                }
            }

            new_individs.Add(child_one);
            new_individs.Add(child_two);

            return(new_individs);
        }
Ejemplo n.º 2
0
        private static Genotip Mutation(Genotip parent, List <int> employees, int max_count_employees, Random rnd) //мутация
        //входные данные - генотип из родительского пула, список идентификаторов сотрудников, максимальное число сотрудников на проект, рандомайзер
        //выходные данные - генотип
        {
            //мутация заключается в формировании новой хромосомы.
            //формирвоание аналогично формированию хромосом для стартовой популяции
            List <int> empl_temp = new List <int>();


            List <int> prog_id = new List <int>();

            foreach (Project_chromosome pr in parent.Chromosome)
            {
                prog_id.Add(pr.ID);
            }

            List <Project_chromosome> pr_chrom = new List <Project_chromosome>();

            foreach (int em in employees)
            {
                int i = em;
                empl_temp.Add(i);
            }

            // foreach (Project_chromosome pr in parent.Chromosome)
            while (pr_chrom.Count < parent.Chromosome.Count)
            {
                Project_chromosome mut_pr = new Project_chromosome();
                int proj_id = rnd.Next(prog_id.Count);
                mut_pr.ID = prog_id.ElementAt(proj_id);
                prog_id.RemoveAt(proj_id);

                int num = rnd.Next(empl_temp.Count);
                mut_pr.Add_employees(empl_temp.ElementAt(num));
                empl_temp.RemoveAt(num);

                pr_chrom.Add(mut_pr);
            }


            List <int> max_empl_in_project = new List <int>();

            while (empl_temp.Count > 0 & max_empl_in_project.Count < parent.Get_chromosome_count())
            {
                int num      = rnd.Next(empl_temp.Count);
                int employee = empl_temp.ElementAt(num);


                bool flag     = false;
                bool del_flag = true;

                while (flag == false)
                {
                    foreach (Project_chromosome pr in pr_chrom)
                    {
                        int ch = rnd.Next(2);

                        if (ch == 1)
                        {
                            if (pr.Get_count_employees() < max_count_employees)
                            {
                                pr.Add_employees(employee);
                                flag = true;
                                break;
                            }
                            else
                            {
                                if (max_empl_in_project.IndexOf(pr.ID) == -1)
                                {
                                    max_empl_in_project.Add(pr.ID);
                                }
                                if (max_empl_in_project.Count == parent.Get_chromosome_count())
                                {
                                    flag     = true;
                                    del_flag = false;
                                }
                                break;
                            }
                        }
                    }
                }

                pr_chrom = InsertionSort(pr_chrom);

                if (del_flag)
                {
                    empl_temp.RemoveAt(num);
                }
            }


            Genotip mut_individ = new Genotip(pr_chrom);

            return(mut_individ);
        }