/// <summary> /// Метод, возвращающий Id критерия, по которому нужно произвести сортировку /// экспериментов /// </summary> /// <param name="concessions">Коллекция уступок по критериям</param> /// <returns>Id критерия, по которому нужно отсортировать эксперименты</returns> public static TId FindSortingCriterionId(CriterialConcessions concessions) { TId result = -1; // НЕ ЗАБЫТЬ: Если последняя уступка (last usable criterion) // задана для критерия N, то сортировка происходит по критерию // N + 1 foreach (CriterialConcession concession in concessions) { // Если все критерии not usable, то возвращается // индекс первого критерия, что и требуется. // Если критерий N usable, a (N + 1) - not usable, // то возвращается индекс (N + 1)-го критерия result = concession.CriterionId; if (!concession.IsUsable) { break; } } return(result); }
public static void FillMidDataGrid( Model model, DataGridView grid, ScMethodResult result, CriterialConcessions concessions, TId sortingCritId, bool showConstraints, bool showParams) { grid.SuspendLayout(); // Очистка grid.Columns.Clear(); grid.Rows.Clear(); // Колонка для номера эксперимента var numberCol = new DataGridViewColumn(); numberCol.SortMode = DataGridViewColumnSortMode.NotSortable; numberCol.HeaderText = "Номер эксперимента"; numberCol.Name = "num"; numberCol.CellTemplate = new DataGridViewTextBoxCell(); numberCol.CellTemplate.Style.BackColor = Color.LightGray; grid.Columns.Add(numberCol); // Колонки для значений критериев foreach (CriterialConcession concession in concessions) { Criterion crit = model.Criteria[concession.CriterionId]; // вспомогательная строка для заголовка колонки критерия string sortString = SortDirectionManager.GetSortDirectionName(crit.SortDirection); // Колонка для значений критерия var critCol = new DataGridViewColumn(); critCol.CellTemplate = new DataGridViewTextBoxCell(); critCol.SortMode = DataGridViewColumnSortMode.NotSortable; critCol.HeaderText = crit.Name + "\n" + sortString; critCol.Name = "crit_" + crit.Id; critCol.HeaderCell.ToolTipText = crit.GetDescription(); // Отметим цветом колонку того критерия, по которому сделана сортировка if (crit.Id == sortingCritId) { critCol.CellTemplate.Style.BackColor = Color.Aqua; } grid.Columns.Add(critCol); } // Если надо - колонки для функциональных ограничения if (showConstraints) { foreach (KeyValuePair <TId, Constraint> kvp in model.FunctionalConstraints) { var constrCol = new DataGridViewColumn(); constrCol.CellTemplate = new DataGridViewTextBoxCell(); constrCol.SortMode = DataGridViewColumnSortMode.NotSortable; constrCol.HeaderText = kvp.Value.Name; constrCol.Name = "constr_" + kvp.Key; constrCol.HeaderCell.ToolTipText = kvp.Value.GetDescription(); grid.Columns.Add(constrCol); } } // Если надо - колонки для параметров if (showParams) { foreach (KeyValuePair <TId, Parameter> kvp in model.Parameters) { var paramCol = new DataGridViewColumn(); paramCol.CellTemplate = new DataGridViewTextBoxCell(); paramCol.SortMode = DataGridViewColumnSortMode.NotSortable; paramCol.HeaderText = kvp.Value.Name; paramCol.Name = "param_" + kvp.Key; paramCol.HeaderCell.ToolTipText = kvp.Value.GetDescription(); grid.Columns.Add(paramCol); } } // Создадим рядки и заполним их инфой // Будем выводить эксперименты согласно порядку, указанному в // полученном результате вычислений (result) foreach (TId expId in result.SortedPoints) { int rowId = grid.Rows.Add(); string colName = string.Empty; int colId = -1; // Сначала номер эксперимента grid[0, rowId].Value = model.Experiments[expId].Number.ToString(); // Потом - значения критериев foreach (CriterialConcession concession in concessions) { Criterion crit = model.Criteria[concession.CriterionId]; colName = "crit_" + crit.Id; colId = grid.Columns[colName].Index; grid[colId, rowId].Value = model.Experiments[expId].CriterionValues[crit.Id].ToString(SettingsManager.Instance.DoubleStringFormat); } // Потом - если надо - ФО if (showConstraints) { foreach (Constraint constr in model.FunctionalConstraints.Values) { colName = "constr_" + constr.Id; colId = grid.Columns[colName].Index; grid[colId, rowId].Value = model.Experiments[expId].ConstraintValues[constr.Id].ToString(SettingsManager.Instance.DoubleStringFormat); } } // И наконец - если нужно - оптимизируемые параметры if (showParams) { foreach (Parameter param in model.Parameters.Values) { colName = "param_" + param.Id; colId = grid.Columns[colName].Index; grid[colId, rowId].Value = model.Experiments[expId].ParameterValues[param.Id].ToString(SettingsManager.Instance.DoubleStringFormat); } } } grid.ResumeLayout(); // Конец метода }
/// <summary> /// Применяет наложенные уступки /// </summary> /// <param name="model">Исходная модель</param> /// <param name="concessions">Уступки</param> /// <param name="sortingCritId">Критерий, по которому должна производиться сортировка</param> /// <returns>Результат поиска решения</returns> public static ScMethodResult ApplyConcessions( ref Model model, CriterialConcessions concessions, TId sortingCritId) { var result = new ScMethodResult("Метод последовательных уступок"); // Если уступки вообще еще не заданы, то нужно вывести только // эксперимент, лучший по самому важному критерию if (concessions.IsFirstElementIndex(sortingCritId)) { TId bestExperimentId = FindBestValueId(model.Experiments, model.Criteria[sortingCritId]); foreach (Experiment exp in model.Experiments.Values) { if (exp.Id != bestExperimentId) { exp.IsActive = false; } } result.SortedPoints.Add(bestExperimentId); return(result); } // Иначе же будем последовательно применять уступки, отсеивая // не проходящие по ним эксперименты foreach (CriterialConcession concession in concessions) { if (concession.IsUsable) { // Рассчитаем интервал concession.BestValue = FindBestValue(model.Experiments, model.Criteria[concession.CriterionId]); concession.CalcWorstValue(); // Для каждого активного эксперимента проверим: // если он вписывается в интервал, то оставляем активным, // а если нет, то делаем неактивным foreach (Experiment exp in model.Experiments.Values) { if (exp.IsActive) { double expValue = exp.CriterionValues[concession.CriterionId]; exp.IsActive = concession.IsValueFittingInterval(expValue); } } } } // Посчитаем все активные эксперименты if (model.Experiments.CountActiveExperiments() > 0) { SortDirection sortDirection = model.Criteria[sortingCritId].SortDirection; List <SortableDouble> sortedExperiments = model.Experiments.Values.Where(e => e.IsActive).Select <Experiment, SortableDouble>( e => new SortableDouble() { Direction = sortDirection, Id = e.Id, Value = e.CriterionValues[sortingCritId] } ).ToList(); sortedExperiments.Sort(); foreach (SortableDouble sortedExperiment in sortedExperiments) { result.SortedPoints.Add(sortedExperiment.Id); } } return(result); }