/// <summary> /// Сохранение задачи в файл /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void saveFileToolStripMenuButton_Click(object sender, EventArgs e) { // Считываем коэффициенты с ячеек List <List <string> > targetFunction = DataGridWorker.ReadGridsFrom(_dataGridViewTargetFunction); List <List <string> > restrictions = DataGridWorker.ReadGridsFrom(_dataGridViewRestrictions); // В зависимости от выбранного режима добавляем ->max или ->min if (radioButtonMax.Checked) { targetFunction[0].Add("->max"); } else { targetFunction[0].Add("->min"); } // Добавляем "=" перед последним коэффициентом в ограничения foreach (List <string> equation in restrictions) { equation.Insert(equation.Count - 1, "="); } if (saveFileDialog.ShowDialog() == DialogResult.OK) { string filePath = saveFileDialog.FileName; using (TextWriter tw = new StreamWriter(filePath)) { string joinString = String.Join(" ", targetFunction[0].ToArray()); tw.WriteLine(joinString); foreach (List <string> equation in restrictions) { joinString = String.Join(" ", equation.ToArray()); tw.WriteLine(joinString); } tw.Close(); } saveFileDialog.FileName = ""; MessageBox.Show("Файл успешно сохранён.", "Сохранить задачу в файл.", MessageBoxButtons.OK); } }
/// <summary> /// Кнопка "Далее" /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonNext_Click(object sender, EventArgs e) { switch (Step) { case 0: try { // Буферизируем данные BufferingTableValues(Problem.ToFractionList(DataGridWorker.ReadGridsFrom(_dataGridViewProblem))); // Прямой ход Гаусса Problem.Gauss(); // Обновляем параметры DataGridWorker.SetParamToGrids(_dataGridViewProblem, Problem.Restrictions, false); Step++; tabControl.TabPages[0].Text = "Шаг 1: Прямой ход метода Гаусса."; } catch (Exception ex) { MessageBox.Show(ex.Message, $"Ошибка на {Step} шаге!", MessageBoxButtons.OK); } break; case 1: try { // Буферизируем данные BufferingTableValues(Problem.ToFractionList(DataGridWorker.ReadGridsFrom(_dataGridViewProblem))); // Выражение базисных переменных + обратный ход Гаусса Problem.HoistingMatrix(); // Обновляем параметры DataGridWorker.SetParamToGrids(_dataGridViewProblem, Problem.Restrictions, false); Step++; tabControl.TabPages[0].Text = "Шаг 2: Выражение базисных переменных."; } catch (Exception ex) { MessageBox.Show(ex.Message, $"Ошибка на {Step} шаге!", MessageBoxButtons.OK); } break; case 2: try { // Буферизируем данные BufferingTableValues(Problem.ToFractionList(DataGridWorker.ReadGridsFrom(_dataGridViewProblem))); BufferingHeaders(_dataGridViewProblem); if (simplexTableWasDraw == false) { Problem.TransformGridForSimplexTable(_dataGridViewProblem); Problem.SimplexTable = new SimplexTable(_dataGridViewProblem); simplexTableWasDraw = true; } } catch (Exception ex) { MessageBox.Show(ex.Message, $"Ошибка создания симплекс таблицы на {Step} шаге!", MessageBoxButtons.OK); return; } // Если симплекс таблица создалась и отрисовалась успешно // Проверяеем её на ответ switch (Problem.SimplexTable.ResponseCheck()) { case 0: // Продолжаем искать решение Step++; tabControl.TabPages[0].Text = "Шаг 3: Симплекс-таблица."; break; case 1: // Если ответ готов сразу без выбора опорного элемента tabControl.TabPages[0].Text = "Ответ готов!"; Step++; labelAnswer.Visible = true; groupBoxCornerDot.Visible = true; buttonNext.Enabled = false; // Подставляем ответ if (Problem.Min == false) { labelAnswer.Text = "Ответ :" + Problem.SimplexTable.Response(); } else { labelAnswer.Text = "Ответ :" + Problem.SimplexTable.Response() * (-1); } // Выводим угловую точку ответа (X*) if (cornerDotAnswerWasAdded == false) { //добавляем точку DataGridWorker.SetParamToGrids( _dataGridViewCornerDot, Problem.ResponseCornerDot(_dataGridViewProblem), true); cornerDotAnswerWasAdded = true; } break; case -1: Step++; MessageBox.Show("Задача не разрешима!"); tabControl.TabPages[0].Text = "Задача не разрешима!"; buttonNext.Enabled = false; break; } break; case 3: try { BufferingTableValues(Problem.SimplexTable.SimplexTableElements); //выбор опорного Problem.SimplexTable.SelectionOfTheSupportElements(_dataGridViewProblem); Step++; tabControl.TabPages[0].Text = $"Шаг {Step}: Выбор опорного элемента"; } catch (Exception ex) { MessageBox.Show(ex.Message, $"Ошибка при выборе опорных элементов на {Step} шаге.", MessageBoxButtons.OK); } break; default: try { // Проверяем, выбран ли опорный элемент Problem.SimplexTable.SupportElementPressedOrNot(_dataGridViewProblem); // Меняем хэдэры колонки и строки местами Problem.SimplexTable.ChangeHeaders(_dataGridViewProblem); // Буферизируем симплекс таблицу BufferingTableValues(Problem.SimplexTable.SimplexTableElements); // Удаляем подсвеченные ячейки UncolorGreenGrids(_dataGridViewProblem); // Вычисление симплекс таблицы по выбранному опорному элементу Problem.SimplexTable.CalculateSimplexTable(); // Обновление ячеек DataGridWorker.SetParamToGrids(_dataGridViewProblem, Problem.SimplexTable.SimplexTableElements, false); } catch (Exception ex) { MessageBox.Show(ex.Message, $"Ошибка при выборе опорного элемента на шаге {Step}", MessageBoxButtons.OK); return; } switch (Problem.SimplexTable.ResponseCheck()) { case 0: Step++; tabControl.TabPages[0].Text = $"Шаг {Step}: Выбор опорного элемента"; //выбор опорного Problem.SimplexTable.SelectionOfTheSupportElements(_dataGridViewProblem); break; case 1: tabControl.TabPages[0].Text = "Ответ готов!"; Step++; labelAnswer.Visible = true; groupBoxCornerDot.Visible = true; if (Problem.Min == false) { labelAnswer.Text = "Ответ :" + Problem.SimplexTable.Response(); } else { labelAnswer.Text = "Ответ :" + Problem.SimplexTable.Response() * (-1); } if (cornerDotAnswerWasAdded == false) { //добавляем угловую точку решения (X*) DataGridWorker.SetParamToGrids( _dataGridViewCornerDot, Problem.ResponseCornerDot(_dataGridViewProblem), true); cornerDotAnswerWasAdded = true; } buttonNext.Enabled = false; break; case -1: Step++; MessageBox.Show("Задача не разрешима!"); tabControl.TabPages[0].Text = "Задача не разрешима!"; buttonNext.Enabled = false; break; } break; } }
/// <summary> /// Кнопка "Назад" /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonBack_Click(object sender, EventArgs e) { switch (Step) { case 0: // Отменить операцию закрытия окна bool CancelСlosing = false; var result = MessageBox.Show( "Предыдущего шага нет. Возврат приведёт к закрытию текущей задачи. Вы уверены?", "Закрыть задачу?", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.No) { // Если пользователь не хочет закрывать окно, отменяем операцию CancelСlosing = true; } if (!CancelСlosing) { this.Close(); } break; case 1: // Возвращение с шага 1 try { // Достаём данные из буфера и заносим их в ячейки DataGridWorker.SetParamToGrids(_dataGridViewProblem, GetOutOfTheBuffer(), false); // Заносим данные из буфера в данные задачи Problem.Restrictions = Problem.ToFractionList(DataGridWorker.ReadGridsFrom(_dataGridViewProblem)); // Убавляем шаг Step--; tabControl.TabPages[0].Text = "Матрица коэффициентов системы ограничений равенств."; } catch (Exception ex) { MessageBox.Show(ex.Message, $"Ошибка при возвращении с шага {Step}.", MessageBoxButtons.OK); } break; case 2: try { // Достаём данные из буфера и заносим их в ячейки DataGridWorker.SetParamToGrids(_dataGridViewProblem, GetOutOfTheBuffer(), false); // Заносим данные из буфера в данные задачи Problem.Restrictions = Problem.ToFractionList(DataGridWorker.ReadGridsFrom(_dataGridViewProblem)); // Убавляем шаг Step--; tabControl.TabPages[0].Text = "Шаг 1: Прямой ход метода Гаусса."; } catch (Exception ex) { MessageBox.Show(ex.Message, $"Ошибка при возвращении с шага {Step}.", MessageBoxButtons.OK); } break; case 3: // Достаём данные из буфера и заносим их в ячейки DataGridWorker.SetParamToGrids(_dataGridViewProblem, GetOutOfTheBuffer(), true); // Достаём хэдэры из буфера DataGridWorker.SetHeaders(_dataGridViewProblem, GetOutOfTheBufferHeaders()); // Обнуляем данные симплекс таблицы Problem.SimplexTable.SimplexTableElements = new List <List <Fraction> >(); simplexTableWasDraw = false; Step--; tabControl.TabPages[0].Text = "Шаг 2: Выражение базисных переменных."; // Если ответ был готов сразу и уже отобразился - скрываем его labelAnswer.Visible = false; groupBoxCornerDot.Visible = false; buttonNext.Enabled = true; break; case 4: UncolorGreenGrids(_dataGridViewProblem); GetOutOfTheBuffer(); Step--; tabControl.TabPages[0].Text = "Шаг 3: Симплекс-таблица."; break; default: UncolorGreenGrids(_dataGridViewProblem); // Достаём из буффера элементы симплекс таблицы Problem.SimplexTable.SimplexTableElements = GetOutOfTheBuffer(); // Достаём данные из буфера и заносим их в ячейки DataGridWorker.SetParamToGrids(_dataGridViewProblem, Problem.SimplexTable.SimplexTableElements, false); // Меняем хэдэры обратно, доставая их из буффера Problem.SimplexTable.ChangeHeadersFromBuffer(_dataGridViewProblem); // Выбор опорного Problem.SimplexTable.SelectionOfTheSupportElements(_dataGridViewProblem); Step--; tabControl.TabPages[0].Text = $"Шаг {Step}: Выбор опорного элемента"; labelAnswer.Visible = false; groupBoxCornerDot.Visible = false; buttonNext.Enabled = true; break; } }
/// <summary> /// Кнопка "Решить" /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonSolve_Click(object sender, EventArgs e) { // Задача на минимум? bool min = radioButtonMin.Checked; // Пошаговый режим? bool stepByStepModeOn = radioButtonStepByStepMode.Checked; // Задана угловая точка? bool cornerDotOn = checkBoxCornerDot.Checked; // Создаём объект задачи LinearProgrammingProblem problem; // Инициализируем try { // Данные задачи List <List <string> > targetFunction = DataGridWorker.ReadGridsFrom(_dataGridViewTargetFunction); List <List <string> > retrictions = DataGridWorker.ReadGridsFrom(_dataGridViewRestrictions); List <List <string> > cornerDot; // Если включена угловая точка if (cornerDotOn) { cornerDot = DataGridWorker.ReadGridsFrom(_dataGridViewCornerDot); problem = new LinearProgrammingProblem(targetFunction, retrictions, cornerDot, min); // Использование LINQ var query = problem.CornerDot[0].Where(fraction => !fraction.Equals(new Fraction(0))); if (problem.Restrictions.Count != query.Count()) { throw new Exception("Невозможно выразить базис с данной угловой точкой. " + "Количество ненулевых параметров начальной угловой точки не равно количеству линейно независимых строк"); } } else { problem = new LinearProgrammingProblem(targetFunction, retrictions, null, min); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Ошибка при создании задачи!", MessageBoxButtons.OK); return; } // Меню // Проверяем режим switch (stepByStepModeOn) { // Если выбран пошаговый режим case true: StepByStepWindow stepByStepWindow = new StepByStepWindow(problem); stepByStepWindow.ShowDialog(); break; // Если выбран авто-режим case false: AutoStepWindow autoStepWindow = new AutoStepWindow(problem); autoStepWindow.ShowDialog(); break; } }