public FormalMethodResult FindDecision(Model model) { FormalMethodResult result = new FormalMethodResult("Метод поиска точки с минимальным удалением от идеальной", "Расстояние до идеальной точки"); // Search among active pareto-optimal experiments only IEnumerable <Experiment> targetPoints = model.Experiments.Values.Where(e => e.IsActive && e.IsParetoOptimal); // Координаты идеальной точки Dictionary <TId, double> idealPoint = new Dictionary <TId, double>(model.Criteria.Count); // В качестве дефолтных возьмем лучшие из тех, // что есть foreach (Criterion criterion in model.Criteria.Values) { IEnumerable <double> criterionValues = targetPoints.Select <Experiment, double>(e => e.CriterionValues[criterion.Id]); double bestCriterionValue = double.NaN; switch (criterion.Type) { case CriterionType.Minimizing: bestCriterionValue = criterionValues.Min(); break; case CriterionType.Maximizing: bestCriterionValue = criterionValues.Max(); break; } idealPoint.Add(criterion.Id, bestCriterionValue); } // Спросим у юзера, может он хочет их поменять idealPoint = GetUserIdealPoint(model.Criteria, idealPoint); // Теперь координаты идеальной точки есть. // Можем найти расстояния от нее до каждой из // паретовских точек Dictionary <TId, double> distances = new Dictionary <TId, double>(targetPoints.Count()); foreach (Experiment experiment in targetPoints) { double distance = 0; foreach (Criterion criterion in model.Criteria.Values) { double pointCoordinate = experiment.CriterionValues[criterion.Id]; double idealPointCoordinate = idealPoint[criterion.Id]; distance += Math.Pow(idealPointCoordinate - pointCoordinate, 2); } distance = Math.Sqrt(distance); distances.Add(experiment.Id, distance); } // Отсортируем результаты по возрастанию по расстоянию // до идеальной точки (ближайшая - лучшая) List <SortableDouble> sortedDistances = distances.Select <KeyValuePair <TId, double>, SortableDouble>( kvp => new SortableDouble() { Direction = SortDirection.Ascending, Id = kvp.Key, Value = kvp.Value } ).ToList(); sortedDistances.Sort(); foreach (SortableDouble distance in sortedDistances) { result.SortedPoints.Add(distance.Id); result.AdditionalData.Add(distance.Id, distance.Value); } return(result); }
public FormalMethodResult FindDecision(Model model) { FormalMethodResult result = new FormalMethodResult("Метод поиска точки с максимальной мощностью", "Мощность точки"); // Search among active experiments only IEnumerable <Experiment> activeExperiments = model.Experiments.Values.Where(e => e.IsActive); // Словарь для хранения мощности каждой точки // Ключ - индекс точки, Значение - ее мощность Dictionary <TId, int> powers = new Dictionary <TId, int>(activeExperiments.Count()); foreach (Experiment currentExperiment in activeExperiments) { powers.Add(currentExperiment.Id, 0); foreach (Experiment experiment in activeExperiments) { if (experiment.Id == currentExperiment.Id) { continue; } // Подсчитаем, по скольки критериям точка currExp // оказалась лучше, чем exp int currExpWins = 0; foreach (Criterion criterion in model.Criteria.Values) { double currExpCritValue = currentExperiment.CriterionValues[criterion.Id]; double expCritValue = experiment.CriterionValues[criterion.Id]; if (Comparer.IsFirstValueBetter( currExpCritValue, expCritValue, criterion.Type)) { currExpWins++; } } // Если currExp оказалась лучше по всем критериям, // то запишем ей +1 к мощности if (currExpWins == model.Criteria.Count) { powers[currentExperiment.Id]++; } } } // Отсортируем результаты по убыванию по мощности // (больше - лучше) List <SortableDouble> sortedPowers = powers.Select <KeyValuePair <TId, int>, SortableDouble>( kvp => new SortableDouble() { Direction = SortDirection.Descending, Id = kvp.Key, Value = (double)kvp.Value } ).ToList(); sortedPowers.Sort(); // Сформируем результат foreach (SortableDouble power in sortedPowers) { result.SortedPoints.Add(power.Id); result.AdditionalData.Add(power.Id, power.Value); } return(result); }
public FormalMethodResult FindDecision(Model model) { FormalMethodResult result = new FormalMethodResult("Метод бинарных отношений", "Количество \"побед\" точки"); IEnumerable <Experiment> paretoExperiments = model.Experiments.Values.Where(e => e.IsParetoOptimal); // Словарь для хранения количества побед каждой точки // Ключ - индекс точки, Значение - количество ее побед Dictionary <TId, int> wins = new Dictionary <TId, int>(paretoExperiments.Count()); foreach (Experiment experiment in paretoExperiments) { wins.Add(experiment.Id, 0); } List <TId> seenPoints = new List <TId>(paretoExperiments.Count()); foreach (Experiment currentExperiment in paretoExperiments) { foreach (Experiment experiment in paretoExperiments) { if (experiment.Id != currentExperiment.Id && !seenPoints.Contains(experiment.Id)) { foreach (Criterion criterion in model.Criteria.Values) { double currExpCritValue = currentExperiment.CriterionValues[criterion.Id]; double expCritValue = experiment.CriterionValues[criterion.Id]; if (Comparer.IsFirstValueBetter(currExpCritValue, expCritValue, criterion.Type)) { wins[currentExperiment.Id]++; } else { wins[experiment.Id]++; } } } } seenPoints.Add(currentExperiment.Id); } // Отсортируем результаты по убыванию по количеству // побед (больше - лучше) List <SortableDouble> sortedWins = wins.Select <KeyValuePair <TId, int>, SortableDouble>( kvp => new SortableDouble() { Direction = SortDirection.Descending, Id = kvp.Key, Value = (double)kvp.Value } ).ToList(); sortedWins.Sort(); // Сформируем результат foreach (SortableDouble win in sortedWins) { result.SortedPoints.Add(win.Id); result.AdditionalData.Add(win.Id, win.Value); } return(result); }
public static void FillDataGrid(Model model, FormalMethodResult result, DataGridView table) { table.SuspendLayout(); table.Rows.Clear(); table.Columns.Clear(); // Колонки для параметров 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(); table.Columns.Add(paramCol); } // Колонки для критериев foreach (KeyValuePair <TId, Criterion> kvp in model.Criteria) { var critCol = new DataGridViewColumn(); critCol.CellTemplate = new DataGridViewTextBoxCell(); critCol.SortMode = DataGridViewColumnSortMode.NotSortable; critCol.HeaderText = kvp.Value.Name; critCol.Name = "crit_" + kvp.Key; critCol.HeaderCell.ToolTipText = kvp.Value.GetDescription(); table.Columns.Add(critCol); } // Колонки для функциональных ограничения 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(); table.Columns.Add(constrCol); } // Колонка для дополнительных данных var 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].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].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] != null) { colInd = table.Columns["constr_" + pvs.Key].Index; table[colInd, rowInd].Value = pvs.Value.ToString(SettingsManager.Instance.DoubleStringFormat); } } // Запишем в ячейки дополнительные данные int 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(); }