Esempio n. 1
0
        /// <summary>
        /// Метод для поиска решения с помощью генетического алгоритма
        /// </summary>
        /// <param name="model">Оптимизационная модель, эксперименты из которой
        /// выступят в качестве начальной популяции</param>
        /// <param name="gaParams">Параметры генетического алгоритма</param>
        /// <param name="table">Таблица для отображения процесса поиска решения.
        /// Если null, то процесс поиска решения не отображается</param>
        public static AdditiveMethodResult FindDecision(Model model, AdditiveParams gaParams, DataGridView table)
        {
            bool showProcess       = (table != null);
            int  currentGeneration = 0;

            // 1. Получим начальную популяцию из модели
            AdditivePopulation population =
                AdditiveSolver.ModelToPopulation(model, currentGeneration);

            // Рассчитаем значения функции приспособленности
            AdditiveSolver.CalcUnitsFitness(
                ref model,
                ref population,
                gaParams.ExternalAppPath);

            // Если надо, подготовим таблицу к выводу процесса и
            // выведем начальную популяцию (без разделителя)
            if (showProcess)
            {
                AdditiveDataGridFiller.PrepareProcessDataGrid(table);
                AdditiveDataGridFiller.AddPopulationToDataGrid(table, population, false);
            }

            // 2. Пока не достигнуто нужное количество поколений
            while (currentGeneration < gaParams.MaxGenerationsNumber)
            {
                // Увеличим счетчик поколений
                currentGeneration++;

                // 3. Отбор
                population =
                    AdditiveSelection.TournamentSelection(population, gaParams.SelectionLimit);

                // 4. Скрещивание
                population =
                    AdditiveCrossover.OnePointCrossover(population, currentGeneration);

                // 5. Мутация
                population =
                    AdditiveMutation.PerformMutation(population, gaParams.MutationProbability);

                // 6. Расчет приспособленности
                // Модель обновится, метод CalcUnitsFitness рассчитает
                // для популяции значения функции приспособленности, а для
                // модели - значения критериев и Ф.О.
                model = AdditiveSolver.PopulationToModel(model, population);
                AdditiveSolver.CalcUnitsFitness(
                    ref model,
                    ref population,
                    gaParams.ExternalAppPath);

                // Если надо, то выведем на экран информацию (с разделителем)
                if (showProcess)
                {
                    AdditiveDataGridFiller.AddPopulationToDataGrid(table, population, true);
                }
            }

            // Подготовим результат на основе конечной популяции
            AdditiveMethodResult result = AdditiveSolver.PrepareResult(population);

            // Вернем результат
            return(result);
        }
Esempio n. 2
0
        private static void CalcUnitsFitness(
            ref Model initModel,
            ref AdditivePopulation population,
            string externalAppPath)
        {
            // У нас есть модель. Рассчитаем для нее с помощью внешней
            // программы значения критериев оптимальности и Ф.О.
#if DUMMY
            // Запустим внешнюю программу и дождемся, пока она отработает
            if (!AdditiveSolver.UseDummyExternalApplication(initModel, externalAppPath))
            {
                throw new Exception("Can not calculate fitness values using external program");
            }
#else
            // Файл для обмена данными между opt и расчетной программой
            string dataFilePath = System.IO.Path.GetDirectoryName(externalAppPath) + "\\_ga_temp_file.xml";

            // Запустим внешнюю программу и дождемся, пока она отработает
            if (!AdditiveSolver.UseExternalApplication(
                    initModel,
                    externalAppPath,
                    dataFilePath))
            {
                throw new Exception("Can not calculate fitness values using external program");
            }

            // Раз программа отработала, прочтем результаты из файла
            initModel = modelProvider.Load(dataFilePath);

            // Удалим файл с данными
            if (System.IO.File.Exists(dataFilePath))
            {
                System.IO.File.Delete(dataFilePath);
            }
#endif
            // Применим решатель для аддитивного критерия, чтобы получить его значения.
            // Они послужат нам эквивалентом функции приспособленности
            AdditiveCriterionSolver       solver = new AdditiveCriterionSolver();
            IntegralCriterionMethodResult result = solver.FindDecision(initModel);

            // Из результатов аддитивного критерия выдерем его значения
            foreach (TId expId in result.SortedPoints)
            {
                int unitNumber = initModel.Experiments[expId].Number;
                population[unitNumber].FitnessValue = result.AdditionalData[expId];
            }

            // Применим Ф.О. к модели
            initModel.ApplyFunctionalConstraints();

            // Пометим на удаление в популяции особи, соответсвующие экспериментам,
            // ставшим неактивными после применения Ф.О.
            foreach (Experiment exp in initModel.Experiments.Values)
            {
                if (!exp.IsActive)
                {
                    population.MarkForRemoval(exp.Number);
                }
            }
            // И удалим помеченные
            population.RemoveMarked();
        }