/// <summary> /// Метод для получения результатов работы генетического алгоритма /// </summary> /// <param name="population">Популяция, на основе которой строится результат</param> /// <returns>Результат работы генетического алгоритма</returns> private static AdditiveMethodResult PrepareResult(AdditivePopulation population) { AdditiveMethodResult result = new AdditiveMethodResult("Генетический алгоритм", "Значение функции приспособленности"); // Отсортируем результаты по возрастанию по значению // аддитивного критерия (меньше - лучше) List <SortableDouble> sortedIndividuals = population.Select <AdditiveIndividual, SortableDouble>( ind => new SortableDouble() { Direction = SortDirection.Ascending, Id = ind.Number, Value = ind.FitnessValue } ).ToList(); sortedIndividuals.Sort(); // Заполним результаты foreach (SortableDouble sortedIndividual in sortedIndividuals) { result.SortedPoints.Add(sortedIndividual.Id); result.AdditionalData.Add(sortedIndividual.Id, sortedIndividual.Value); } return(result); }
/// <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); }
/// <summary> /// Метод для заполнения таблицы результатами поиска решения с /// помощью генетического алгоритма /// </summary> /// <param name="model">Оптимизациионная модель</param> /// <param name="result">Результаты поиска решения</param> /// <param name="table">Таблица для вывода результатов</param> public static void FillDataGrid( Model model, AdditiveMethodResult result, DataGridView table) { table.SuspendLayout(); table.Rows.Clear(); table.Columns.Clear(); // Колонки для параметров foreach (KeyValuePair <TId, Parameter> kvp in model.Parameters) { DataGridViewColumn paramCol = new DataGridViewColumn(); paramCol.CellTemplate = new DataGridViewTextBoxCell(); paramCol.SortMode = DataGridViewColumnSortMode.NotSortable; paramCol.HeaderText = kvp.Value.Name; paramCol.Name = "param_" + kvp.Key.ToString(); paramCol.HeaderCell.ToolTipText = kvp.Value.GetDescription(); table.Columns.Add(paramCol); } // Колонки для критериев foreach (KeyValuePair <TId, Criterion> kvp in model.Criteria) { DataGridViewColumn critCol = new DataGridViewColumn(); critCol.CellTemplate = new DataGridViewTextBoxCell(); critCol.SortMode = DataGridViewColumnSortMode.NotSortable; critCol.HeaderText = kvp.Value.Name; critCol.Name = "crit_" + kvp.Key.ToString(); critCol.HeaderCell.ToolTipText = kvp.Value.GetDescription(); table.Columns.Add(critCol); } // Колонки для функциональных ограничения foreach (KeyValuePair <TId, Constraint> kvp in model.FunctionalConstraints) { DataGridViewColumn constrCol = new DataGridViewColumn(); constrCol.CellTemplate = new DataGridViewTextBoxCell(); constrCol.SortMode = DataGridViewColumnSortMode.NotSortable; constrCol.HeaderText = kvp.Value.Name; constrCol.Name = "constr_" + kvp.Key.ToString(); constrCol.HeaderCell.ToolTipText = kvp.Value.GetDescription(); table.Columns.Add(constrCol); } // Колонка для дополнительных данных DataGridViewColumn additionalCol = new DataGridViewColumn(); additionalCol.CellTemplate = new DataGridViewTextBoxCell(); additionalCol.SortMode = DataGridViewColumnSortMode.NotSortable; additionalCol.HeaderText = result.AdditionalDataDescription; additionalCol.Name = "additional_col"; table.Columns.Add(additionalCol); foreach (TId expId in result.SortedPoints) { // Добавим рядок int rowInd = table.Rows.Add(); // Запишем в хедер номер эксперимента table.Rows[rowInd].HeaderCell.Value = model.Experiments[expId].Number.ToString(); // Запишем в ячейки значения оптимизируемых параметров foreach (KeyValuePair <TId, double> pvs in model.Experiments[expId].ParameterValues) { int colInd = 0; try { colInd = table.Columns["param_" + pvs.Key.ToString()].Index; } catch (Exception ex) { MessageBoxHelper.ShowError(ex.Message); return; } table[colInd, rowInd].Value = pvs.Value.ToString(SettingsManager.Instance.DoubleStringFormat); } // Запишем в ячейки значения критериев оптимальности foreach (KeyValuePair <TId, double> pvs in model.Experiments[expId].CriterionValues) { int colInd = 0; try { colInd = table.Columns["crit_" + pvs.Key.ToString()].Index; } catch (Exception ex) { MessageBoxHelper.ShowError(ex.Message); return; } table[colInd, rowInd].Value = pvs.Value.ToString(SettingsManager.Instance.DoubleStringFormat); } // Запишем в ячейки значения ФО foreach (KeyValuePair <TId, double> pvs in model.Experiments[expId].ConstraintValues) { int colInd = 0; if (table.Columns["constr_" + pvs.Key.ToString()] != null) { colInd = table.Columns["constr_" + pvs.Key.ToString()].Index; table[colInd, rowInd].Value = pvs.Value.ToString(SettingsManager.Instance.DoubleStringFormat); } } // Запишем в ячейки дополнительные данные int colId = 0; colId = table.Columns["additional_col"].Index; table[colId, rowInd].Style.BackColor = Color.LightGray; table[colId, rowInd].Value = result.AdditionalData[expId].ToString(SettingsManager.Instance.DoubleStringFormat); } table.ResumeLayout(); }