// результат нажатия опорного элемента private void ClickedButton(string method, Button butt, List <Fraction[, ]> matrixs, Grid grid) { // определить какая матрица на экране в данный момент int nowNum = MAB_SM.getNowNum(lpp, method); // очистить хвост списка (все матрицы большие по номеру, чем текущая) int count = matrixs.Count - nowNum - 1; matrixs.RemoveRange(nowNum + 1, count); // определить координаты кнопки int row = Grid.GetRow(butt); int column = Grid.GetColumn(butt); // кол-во столбцов в матрице int columns = matrixs[nowNum].GetLength(0); MessageBox.Show("Вы выбрали опорным элемент,\n" + "расположенный на пересечении x" + column + " и x" + (row + columns - 2)); // сделать шаг мет.иск.баз./симп.метода MAB_SM.Step(lpp, column, row, method, nowNum, matrixs); // определить № последней матрицы в списке nowNum = matrixs.Count - 1; // проверка на положительность всех эл. в нижней строке IsBottomStringPositive(method, matrixs[nowNum]); switch (method) { case "SM": // проверка на отр. столбец IsContainNegativeColumn(method, matrixs[nowNum]); break; } // отобразить расчет Display.InitializeGrid_3_4(this, method, grid, matrixs[nowNum]); }
// все ли числа (кроме посл. эл.) в нижней строке положительны // true - если >= 0 private bool IsBottomStringPositive(string method, Fraction[,] matrix) { int nowNum = MAB_SM.getNowNum(lpp, method); int columns = matrix.GetLength(0); int rows = matrix.GetLength(1); bool flagNegative = false; bool flagPositive = false; for (int i = 1; i < columns - 1; i++) { if (matrix[i, rows - 1].Numerator < 0) { flagNegative = true; } if (matrix[i, rows - 1].Numerator > 0) { flagPositive = true; } } // >=0 if (!flagNegative && flagPositive) { switch (method) { case "MAB": message.Content = "Система условий несовместна"; break; case "SM": message2.Content = "Найдено решение"; TakeAnswer(method, matrix); break; } return(true); } // =0 if (!flagNegative && !flagPositive) { switch (method) { case "MAB": message.Content = "Найден базис"; TakeAnswer(method, matrix); break; case "SM": message2.Content = "Найдено решение"; TakeAnswer(method, matrix); break; } return(true); } return(false); }
// выбор опорного элемента public static void SelectSupportElem(LinearProgrammingProblem lpp, out int column, out int row, string method, Fraction[,] matrixIn) { column = -1; row = -1; Fraction[,] matrix = (Fraction[, ])matrixIn.Clone(); int columns = matrix.GetLength(0); int rows = matrix.GetLength(1); Fraction[] supportElementsIndex = new Fraction[columns]; for (int i = 1; i < columns - 1; i++) { supportElementsIndex[i] = MAB_SM.FindSupportMinRatio(i, matrix); } bool flagSupportElem = false; for (int y = 0; y < rows && !flagSupportElem; y++) { for (int x = 0; x < columns; x++) { Fraction ratio = matrix[columns - 1, y] / matrix[x, y]; if (x != 0 && x != columns - 1 && y != 0 && y != rows - 1 && supportElementsIndex[x] != null && supportElementsIndex[x].IsEquals(ratio) && matrix[x, y] > 0 && !flagSupportElem) { switch (method) { case "MAB": if (matrix[0, y] >= lpp.matrix2.GetLength(0)) { column = x; row = y; flagSupportElem = true; } break; case "SM": column = x; row = y; flagSupportElem = true; break; } } } } }
private void CalculateMAB() { DeleteClickButton(); prevButton.Click += prevButton_Click; nextButton.Click += nextButton_Click; startButton.Click += startButton_Click; endButton.Click += endButton_Click; autoButton.Visibility = Visibility.Visible; // заполнить матрицу для расчета методом иск. базиса MAB_SM.InitializeMAB(this); //lpp.methodOfArtificialBasis[lpp.nowNumMatrixMAB][0, 0].Text = "№" + (lpp.nowNumMatrixMAB).ToString(); // проверка совместности системы IsBottomStringPositive("MAB", lpp.methodOfArtificialBasis[lpp.nowNumMatrixMAB]); // отобразить таблицу иск. базиса Display.InitializeGrid_3_4(this, "MAB", grid3, lpp.methodOfArtificialBasis[lpp.nowNumMatrixMAB]); }
// симлекс метод private void autoButton2_Click(object sender, RoutedEventArgs e) { // очистить хвост списка int countMatrix = lpp.simplexMethod.Count - lpp.nowNumMatrixSM - 1; lpp.simplexMethod.RemoveRange(lpp.nowNumMatrixSM + 1, countMatrix); int column; int row; while (true) { MAB_SM.SelectSupportElem(lpp, out column, out row, "SM", lpp.simplexMethod[lpp.nowNumMatrixSM]); // рассчитать if (column > 0 && row > 0) { // проверка if (IsBottomStringPositive("SM", lpp.simplexMethod[lpp.nowNumMatrixSM]) || IsContainNegativeColumn("SM", lpp.simplexMethod[lpp.nowNumMatrixSM])) { // отобразить расчет Display.InitializeGrid_3_4(this, "SM", grid4, lpp.simplexMethod[lpp.nowNumMatrixSM]); break; } MAB_SM.Step(lpp, column, row, "SM", lpp.nowNumMatrixSM, lpp.simplexMethod); if (IsBottomStringPositive("SM", lpp.simplexMethod[lpp.nowNumMatrixSM]) || IsContainNegativeColumn("SM", lpp.simplexMethod[lpp.nowNumMatrixSM])) { // отобразить расчет Display.InitializeGrid_3_4(this, "SM", grid4, lpp.simplexMethod[lpp.nowNumMatrixSM]); break; } // отобразить расчет Display.InitializeGrid_3_4(this, "SM", grid4, lpp.simplexMethod[lpp.nowNumMatrixSM]); } else { if (message2.Content.Equals("")) { message2.Content = "Упс... См. autoButton2_Click"; } break; } } }
//// после метода иск. баз. private void calculateButton2_Click(object sender, RoutedEventArgs e) { // очистить матрицы симпл. метода ClearSM(); message2.Content = ""; messageAnswer2.Content = ""; // сделать кнопки навигации недоступными Display.ChangePropertiesButton_EnabledFalse_2(this); // заполнить матрицу для расчета сим. методом switch (selectedMethod) { case "Gauss": MAB_SM.InitializeSM_G(this); break; case "MAB": MAB_SM.InitializeSM(this); break; } // проверка IsBottomStringPositive("SM", lpp.simplexMethod[lpp.nowNumMatrixSM]); IsContainNegativeColumn("SM", lpp.simplexMethod[lpp.nowNumMatrixSM]); if (message2.Content.Equals("Функция неограничена")) { // отобразить таблицу Display.InitializeGrid_3_intermediary(this, grid4, lpp.simplexMethod[lpp.nowNumMatrixSM]); autoButton2.IsEnabled = false; } else { // отобразить таблицу Display.InitializeGrid_3_4(this, "SM", grid4, lpp.simplexMethod[lpp.nowNumMatrixSM]); autoButton2.IsEnabled = true; } }
//// для метода иск. баз. private void autoButton_Click(object sender, RoutedEventArgs e) { // очистить хвост списка if (lpp.nowNumMatrixMAB % 2 != 0) { lpp.nowNumMatrixMAB++; } int countMatrix = lpp.methodOfArtificialBasis.Count - lpp.nowNumMatrixMAB - 1; lpp.methodOfArtificialBasis.RemoveRange(lpp.nowNumMatrixMAB + 1, countMatrix); int column; int row; // количество шагов int countStep = lpp.matrix2.GetLength(1) - (lpp.nowNumMatrixMAB / 2); for (int i = 0; i < countStep; i++) { // найти координаты опорного элемента MAB_SM.SelectSupportElem(lpp, out column, out row, "MAB", lpp.methodOfArtificialBasis[lpp.nowNumMatrixMAB]); // рассчитать if (column > 0 && row > 0) { MAB_SM.Step(lpp, column, row, "MAB", lpp.nowNumMatrixMAB, lpp.methodOfArtificialBasis); lpp.methodOfArtificialBasis[lpp.nowNumMatrixMAB][0, 0].Text = "№" + (lpp.nowNumMatrixMAB).ToString(); // проверка совместности системы IsBottomStringPositive("MAB", lpp.methodOfArtificialBasis[lpp.nowNumMatrixMAB]); // отобразить расчет Display.InitializeGrid_3_4(this, "MAB", grid3, lpp.methodOfArtificialBasis[lpp.nowNumMatrixMAB]); } else { if (message.Content.Equals("")) { message.Content = "Нет подходящего опорного элемента. Найден цикл"; } } } }
// отбразить матрицу мет. иск. баз./ сим. мет. public static void InitializeGrid_3_4(MainWindow w, string method, Grid grid, Fraction[,] matrix) { // изменить доступность кнопок навигации switch (method) { case "MAB": ChangePropertiesButton_Enabled_1(w); break; case "SM": ChangePropertiesButton_Enabled_2(w); break; } // grid - где отображаем if (grid != null) { int columns; int rows; // разлинеить сетку DisplayGrid_3_4(w, grid, matrix, out columns, out rows); // минимальные отношения b/a в каждом столбце Fraction[] minRatio = new Fraction[columns]; for (int i = 1; i < columns - 1; i++) { minRatio[i] = MAB_SM.FindSupportMinRatio(i, matrix); } // флаг зацикливания bool flagCycle = true; // добавить TextBox/Label в grid for (int y = 0; y < rows; y++) { for (int x = 0; x < columns; x++) { if (MAB_SM.IsCanBeSupperElem(matrix, columns, rows, minRatio, y, x)) { switch (method) { case "MAB": // в строке вспомогательный х if (matrix[0, y] >= w.lpp.matrix2.GetLength(0)) { DisplayButton(w, grid, matrix, y, x); flagCycle = false; } else { DisplayLabel(grid, matrix, y, x); }; break; case "SM": DisplayButton(w, grid, matrix, y, x); flagCycle = false; break; } } else { DisplayLabel(grid, matrix, y, x); } } } if (flagCycle && w.message.Content.Equals("")) { w.message.Content = "Нет подходящего опорного элемента. Найден цикл"; } } }