private void FindInitialCosts() { int costMRow = SimplexTable.GetLength(0) - 1; int costRow = costMRow - 1; for (int j = 0; j < SimplexTable.GetLength(1); j++) { SimplexTable[costRow, j] = 0; SimplexTable[costMRow, j] = 0; for (int i = 1; i < SimplexTable.GetLength(0) - 2; i++) { if (SimplexTable[0, Basis[i - 1]] == -M) { SimplexTable[costMRow, j] += (SimplexTable[i, j] * (-1)); } else { SimplexTable[costRow, j] += (SimplexTable[i, j] * SimplexTable[0, Basis[i - 1]]); } } if (SimplexTable[0, j] == -M) { SimplexTable[costMRow, j] += 1; } else { SimplexTable[costRow, j] -= SimplexTable[0, j]; } } }
/// <summary> /// Конструктор для окна выполнения пошагового симплекс-метода. /// </summary> /// <param name="elements">Матрица коэффициентов системы ограничений-равенств.</param> /// <param name="selected_number_of_rows">Выбранное число строк.</param> /// <param name="selected_number_of_columns">Выбранное число столбцов.</param> /// <param name="variable_visualization">Вспомогательный массив для визуализации переменных(по типу x1,x2,x3 и т.д.).</param> /// <param name="number_of_permutations">Количество базисных переменных.</param> /// <param name="target_function_elements">Коэффициенты целевой функции.</param> public StepByStepSimplexWindow(List <List <double> > elements, int selected_number_of_rows, int selected_number_of_columns, int[] variable_visualization, int number_of_permutations, double[] target_function_elements, int MinMax, bool?CornerDot) { InitializeComponent(); //переносим заполненный массив с главного окна this.elements = elements; //изначально мы на нулевом шаге step = 0; //Количество базисных переменных. this.number_of_permutations = number_of_permutations; //вычисляем количество свободных переменных number_of_free_variables = variable_visualization.Length - number_of_permutations; //Вспомогательный массив для визуализации переменных(по типу x1, x2, x3 и т.д.). this.variable_visualization = variable_visualization; //Вспомогательная переменная, которая определяет была ли создана симплекс-таблица. True - была создана. False - не была создана. simplex_table_was_draw = false; //Коэффициенты целевой функции. this.target_function_elements = target_function_elements; //Задача на минимум или максимум(0 - минимум, 1 - максимум) this.MinMax = MinMax; //Была ли введена угловая точка(false - нет, true - да). this.CornerDot = CornerDot; //настройка количества строк и столбцов матрицы SimplexTable.SettingMatrix(selected_number_of_rows, selected_number_of_columns, gaussgrid); //отрисовка закруглённых скобок матрицы и вертикальной черты, отделяющей столбец свободных членов DrawExtendedMatrix(); //добавляем лейблы с визуализацией переменных(по типу x1, x2, x3 и т.д.) VariableVisualization(variable_visualization); //заполнение таблицы числами FillingtheTableWithNumbers(); }
public Vector <double> Solve(SimplexTable table) { var request = new Request { A = table.Coefficients.ToRowArrays(), B = table.Limitations.ToArray(), C = table.Target.ToArray() }; var jsonRequest = JsonSerializer.Serialize(request); while (!_socket.Connected) { Thread.Sleep(100); } var encoding = new UTF8Encoding(); var buffer = encoding.GetBytes(jsonRequest); _socket.Send(buffer); buffer = new byte[1024]; _socket.Receive(buffer); var jsonResponse = encoding.GetString(buffer.Where(it => it != 0).ToArray()); var response = JsonSerializer.Deserialize <Response>(jsonResponse); return(Vector <double> .Build.DenseOfArray(response.X)); }
private int FindPivotRow(int pivotCol) { int pivotRow = -1; for (int i = 1; i < SimplexTable.GetLength(0) - 2; i++) { if (SimplexTable[i, pivotCol] > 0) { pivotRow = i; break; } } if (pivotRow == -1) { return(pivotRow); } for (int i = pivotRow + 1; i < SimplexTable.GetLength(0) - 2; i++) { if ((SimplexTable[i, pivotCol] > 0) && ((SimplexTable[i, 0] / SimplexTable[i, pivotCol]) < (SimplexTable[pivotRow, 0] / SimplexTable[pivotRow, pivotCol]))) { pivotRow = i; } } return(pivotRow); }
public bool Pivoting(ref SimplexTable table, out KeyValuePair <string, double> refCol, out KeyValuePair <string, double> refRow) { bool isCorrect = false; refCol = new KeyValuePair <string, double>("", double.MinValue); refRow = new KeyValuePair <string, double>(); if (table != null) { if (table.ObjectiveFunction.isMaximice) { refCol = new KeyValuePair <string, double>("", double.MaxValue); } foreach (KeyValuePair <string, double> kv in table.ObjectiveFunction.VectorBody) { if (table.ObjectiveFunction.isMaximice && kv.Value != 0 && kv.Value < refCol.Value) { refCol = kv; } else if (!table.ObjectiveFunction.isMaximice && kv.Value != 0 && kv.Value > refCol.Value) { refCol = kv; } } refRow = GetRefRow(refCol, ref table); isCorrect = true; } return(isCorrect); }
private void TaskTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (TaskTypeComboBox.SelectedIndex != SourceTaskType) { SourceTaskType = TaskTypeComboBox.SelectedIndex; SimplexTables.Clear(); if (!IsNewTask) { CanonicalTaskType = TaskTypeComboBox.SelectedIndex; for (int i = 0; i < CanonicalN; i++) { CanonicalVectorc[i] = -CanonicalVectorc[i]; } } PrintSolveLog(TaskInfotextBox); SimplexTable smptbl = new SimplexTable(CanonicalN, CanonicalM); smptbl.GetTable(CanonicalMatrixA, CanonicalVectorb, CanonicalVectorc); smptbl.TaskType = CanonicalTaskType; SimplexTables.Add(smptbl); currentSimplexTable = SimplexTables.Count - 1; UpdateSimplexGrid(); OpenTableMode(); } }
/// <summary> /// Выполнение. /// </summary> private void Implementation() { //Прямой ход метода Гаусса для приведения к треугольному виду. MatrixTransformation.Gauss(elements, CornerDot, variable_visualization); //Выражение базисных переменных. MatrixTransformation.HoistingMatrix(elements, number_of_basix); //создаём сиплекс-таблицу simplextable = new SimplexTable(number_of_basix, number_of_free_variables, variable_visualization, elements, target_function_elements, true); MainGrid.Children.Add(simplextable); int responce; int step = 1; while (true) { if ((responce = simplextable.ResponseCheck()) == 0) { //выбор любого опорного simplextable.SelectionRandomSupportElement(); //смена визуализации переменных в симплек-таблице simplextable.ChangeOfVisualWithoutBuffer(); //вычисление согласно выбранному опорному элементу simplextable.CalculateSimplexTable(); //обновление данных сиплекс-таблицы simplextable.UpdateSimplexTableValues(); //номер угловой точки simplextable.CornerPoint(step); step++; } else if (responce == 1) { if (MinMax == 0) { labelanswer.Content = "Ответ :" + simplextable.Response() * (-1); } else { labelanswer.Content = "Ответ :" + simplextable.Response(); } //добавляем точку corner_dot = simplextable.ResponseCornerDot(step - 1); MainGrid.Children.Add(corner_dot); buttonToMainWindow.Visibility = Visibility.Visible; break; } else if (responce == -1) { labelanswer.Content = "Задача не разрешима!"; buttonToMainWindow.Visibility = Visibility.Visible; break; } } }
public Tuple <double, double[]> Calculate() { ConvertToStandardForm(); AddArtificialVariables(); FindInitialCosts(); int prev = -1; while (true) { int pivotColumn = FindPivotColumn(); if (pivotColumn == -1 || pivotColumn == prev) { if (Math.Round(SimplexTable[SimplexTable.GetLength(0) - 1, 0], 10) != 0) { return(null); } else { double[] xOpt = new double[Prob.CountVariables]; for (int i = 0; i < Basis.Length; i++) { if (Basis[i] - 1 < Prob.CountVariables) { xOpt[Basis[i] - 1] = SimplexTable[i + 1, 0]; } } if (additionalVars.Count != 0) { foreach (KeyValuePair <int, int> pair in additionalVars) { xOpt[pair.Key] -= xOpt[pair.Value]; } } double optObjectiveValue = SimplexTable[SimplexTable.GetLength(0) - 2, 0]; if (Prob.Minimize[CriteriaInd] == true) { optObjectiveValue *= -1; } return(new Tuple <double, double[]>(optObjectiveValue, xOpt)); } } else { int pivotRow = FindPivotRow(pivotColumn); if (pivotRow == -1) { return(null); } Basis[pivotRow - 1] = pivotColumn; FindNewSimplexTable(pivotRow, pivotColumn); prev = pivotColumn; } } }
public void MakeConstantsPositive() { for (int i = 0; i < Prob.CountConstraint; i++) { if (Prob.Constants[i] < 0) { for (int j = 0; j < SimplexTable.GetLength(1); j++) { SimplexTable[i + 1, j] *= -1; } } } }
public void ReduceRowsTest() { PrimalSimplexService simplexService = new PrimalSimplexService(new VectorOperations(new VectorHelper()), new VectorHelper()); Constraint c1 = new Constraint(new Dictionary <string, double> { { "x1", 2 }, { "x2", 1 } }, Simplex.Entities.EComparator.LessEqualThan, 18); c1.Name = "r1"; Constraint c2 = new Constraint(new Dictionary <string, double> { { "x1", 2 }, { "x2", 3 } }, Simplex.Entities.EComparator.LessEqualThan, 42); c2.Name = "r2"; Constraint c3 = new Constraint(new Dictionary <string, double> { { "x1", 3 }, { "x2", 1 } }, Simplex.Entities.EComparator.LessEqualThan, 24); c3.Name = "r3"; ObjectiveFunction fo = new ObjectiveFunction(new Dictionary <string, double> { { "x1", 3 }, { "x2", 2 } }, true); fo.Name = "FO"; List <Constraint> constraints = new List <Constraint> { c1, c2, c3 }; SimplexTable table = new SimplexTable(); table.StandardConstraint = simplexService.StandarizeConstraint(constraints, out List <string> header).ToList(); table.ObjectiveFunction = simplexService.StandarizeObjectiveFunction(fo, header); bool isPovoting = simplexService.Pivoting(ref table, out KeyValuePair <string, double> refCol, out KeyValuePair <string, double> refRow); bool isReduce = simplexService.ReduceRows(ref table, refCol, refRow); Assert.True(isPovoting); Assert.True(isReduce); Assert.Equal(24, table.ObjectiveFunction.Constant); Assert.Equal(-1, table.ObjectiveFunction.VectorBody.FirstOrDefault(v => v.Key.Equals("x2")).Value); }
public bool ValidPivotColRow(int pivotCol, int pivotRow) { bool result = true; if ((currentSimplexTable >= 0) & (currentSimplexTable < SimplexTables.Count)) { SimplexTable currentsmptbl = SimplexTables[currentSimplexTable]; currentsmptbl.CalcMeritRestrictions(pivotCol); result = currentsmptbl.MRVector(pivotRow) >= 0; } return(result); }
private ILPTask Clone() { return(new ILPTask { OptimizeType = OptimizeType, VariablesCount = VariablesCount, RestrictionsCount = RestrictionsCount, InfoVariablesCount = InfoVariablesCount, Coefficients = Coefficients.Clone() as float[], Restrictions = Restrictions.Clone() as float[, ], StartBasis = StartBasis.Clone() as int[], SimplexTable = SimplexTable.Clone() as float[, ], OptimizationResult = OptimizationResult, M = M }); }
private void DrawCurStep() { SimplexTable.Columns.Clear(); SimplexTable.Rows.Clear(); lblCurStep.Text = $"Текущий шаг {curStep} из {nSteps}"; SimplexMethod sm = steps[curStep]; for (int i = 0; i < sm.freeVariables.Count + 2; i++) { SimplexTable.Columns.Add("", ""); } List <string> r1 = new List <string>(); r1.Add($"X({sm.NStep})"); for (int i = 0; i < sm.freeVariables.Count; i++) { r1.Add("X" + sm.freeVariables[i]); } r1.Add(""); SimplexTable.Rows.Add(r1.ToArray()); for (int i = 0; i <= sm.basisVariables.Count; i++) { List <string> r = new List <string>(); if (i != sm.basisVariables.Count) { r.Add("X" + sm.basisVariables[i]); } else { r.Add(""); } for (int j = 0; j < sm.freeVariables.Count + 1; j++) { r.Add(sm.table[i, j].ToString()); } SimplexTable.Rows.Add(r.ToArray()); } SimplexTable.ClearSelection(); DrawOporniyElements(); setStyle(); WriteSolution(); }
private int FindPivotColumn() { List <int> minInd = new List <int>(); double minM = SimplexTable[costMRow, 1]; for (int j = 2; j < SimplexTable.GetLength(1); j++) { if (SimplexTable[costMRow, j] < minM) { minM = SimplexTable[costMRow, j]; } } for (int j = 1; j < SimplexTable.GetLength(1); j++) { if (SimplexTable[costMRow, j] == minM) { minInd.Add(j); } } if (minInd.Count == 1) { return(minInd[0]); } else { double min = SimplexTable[costRow, 1]; int pivotCol = minInd[0]; foreach (int j in minInd) { if (SimplexTable[costRow, j] < min) { min = SimplexTable[costRow, j]; pivotCol = j; } } if (min >= 0 && minM >= 0) { return(-1); } else { return(pivotCol); } } }
public bool CheckEnd(SimplexTable table) { bool isEnd = false; if (table != null && table.ObjectiveFunction != null) { foreach (string item in table.Base) { if (table.ObjectiveFunction.isMaximice && !table.ObjectiveFunction.VectorBody.Any(v => v.Value < 0) || !table.ObjectiveFunction.isMaximice && !table.ObjectiveFunction.VectorBody.Any(v => v.Value > 0) || !table.StandardConstraint.Any(c => c.VectorBody.FirstOrDefault(v => v.Key.Equals(item)).Value < 0)) { isEnd = true; } } } return(isEnd); }
private void TaskTypeComboBox_DropDownClosed(object sender, EventArgs e) { if (TaskTypeComboBox.SelectedIndex == 0) { SimplexGrid.Rows[SimplexGrid.RowCount - 1].HeaderCell.Value = "Fmax"; } else { SimplexGrid.Rows[SimplexGrid.RowCount - 1].HeaderCell.Value = "Fmin"; } if ((currentSimplexTable >= 0) & (currentSimplexTable < SimplexTables.Count)) { SimplexTable currentsmptbl = SimplexTables[currentSimplexTable]; currentsmptbl.TaskType = TaskTypeComboBox.SelectedIndex; } }
private void SimplexGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e) { currentSimplexTable = SimplexTables.Count - 1; SimplexTable cursmptbl = SimplexTables[currentSimplexTable]; SimplexTable smptbl = new SimplexTable(cursmptbl.N, cursmptbl.M); smptbl.Assign(cursmptbl); SimplexTables.Clear(); SimplexTables.Add(smptbl); if (smptbl.FillTable(SimplexGrid)) { IsNewTask = false; smptbl.Solved = false; smptbl.Infinity = false; smptbl.Unsolvable = false; smptbl.ResetbaseVector(); CanonicalN = smptbl.N; CanonicalM = smptbl.M; for (int i = 0; i < CanonicalM; i++) { CanonicalSign[i] = 2; } CanonicalTaskType = TaskTypeComboBox.SelectedIndex; smptbl.FillVectorb(CanonicalVectorb); smptbl.FillVectorc(CanonicalVectorc); smptbl.FillMatrixA(CanonicalMatrixA); PrintSolveLog(TaskInfotextBox); toolStripStatusLabel.Text = "Итерация: "; } }
private void FindNewSimplexTable(int pivotRow, int pivotColumn) { double[,] oldTable = new double[SimplexTable.GetLength(0), SimplexTable.GetLength(1)]; Array.Copy(SimplexTable, oldTable, SimplexTable.Length); double pivotElem = SimplexTable[pivotRow, pivotColumn]; for (int j = 0; j < SimplexTable.GetLength(1); j++) { SimplexTable[pivotRow, j] = oldTable[pivotRow, j] / pivotElem; } for (int i = 1; i < SimplexTable.GetLength(0); i++) { if (i == pivotRow || oldTable[i, pivotColumn] == 0) { continue; } for (int j = 0; j < SimplexTable.GetLength(1); j++) { SimplexTable[i, j] = oldTable[i, j] - (oldTable[i, pivotColumn] * SimplexTable[pivotRow, j]); } } }
/// <summary> /// Выполнение. /// </summary> private void Implementation() { //создаём сиплекс-таблицу simplextable = new SimplexTable(number_of_basix, number_of_free_variables, variable_visualization, elements, target_function_elements, false); MainGrid.Children.Add(simplextable); //добавляем тильду simplextable.AddTilde(); if (simplextable.ResponseCheck() == 1) { labelsteps.Content = "Холостой шаг: Метод искусственного базиса. Выбор опорного элемента."; //холостой шаг simplextable.IdleStep(); this.Width = 720; } else { labelsteps.Content = "Шаг " + step + ": Метод искусственного базиса. Выбор опорного элемента."; //выбор опорного simplextable.SelectionOfTheSupportElement(); this.Width = 651; } }
private void NewTaskToolStripMenuItem_Click(object sender, EventArgs e) { NewTaskForm ntf = new NewTaskForm(); if (ntf.ShowDialog() == DialogResult.OK) { TaskEditForm tef = new TaskEditForm(); tef.InitForm(ntf.N, ntf.M); if (tef.ShowDialog() == DialogResult.OK) { IsNewTask = true; TaskTypeComboBox.SelectedIndex = tef.TaskType; SimplexTables.Clear(); SourceN = tef.N; SourceM = tef.M; SourceSign = tef.Signs; SourceVectorb = tef.Vectorb; SourceVectorc = tef.Vectorc; SourceMatrixA = tef.MatrixA; SourceTaskType = tef.TaskType; PrintSolveLog(TaskInfotextBox); SimplexTable smptbl = new SimplexTable(CanonicalN, CanonicalM); smptbl.GetTable(CanonicalMatrixA, CanonicalVectorb, CanonicalVectorc); smptbl.TaskType = CanonicalTaskType; SimplexTables.Add(smptbl); currentSimplexTable = SimplexTables.Count - 1; UpdateSimplexGrid(); OpenTableMode(); } } }
private void NewSimplexTableToolStripMenuItem_Click(object sender, EventArgs e) { NewTaskForm ntf = new NewTaskForm(); ntf.Text = NewSimplexTableToolStripMenuItem.Text; if (ntf.ShowDialog() == DialogResult.OK) { IsNewTask = false; SimplexTables.Clear(); SimplexTable smptbl = new SimplexTable(ntf.N, ntf.M); CanonicalN = smptbl.N; CanonicalM = smptbl.M; for (int i = 0; i < CanonicalM; i++) { CanonicalSign[i] = 2; } SourceTaskType = 0; CanonicalTaskType = 0; TaskTypeComboBox.SelectedIndex = 0; smptbl.FillVectorb(CanonicalVectorb); smptbl.FillVectorc(CanonicalVectorc); smptbl.FillMatrixA(CanonicalMatrixA); SimplexTables.Add(smptbl); currentSimplexTable = SimplexTables.Count - 1; UpdateSimplexGrid(); OpenTableMode(); PrintSolveLog(TaskInfotextBox); } }
private KeyValuePair <string, double> GetRefRow(KeyValuePair <string, double> refCol, ref SimplexTable tabla) { double valorCompareIteracion = new double(); string restriccionS = string.Empty; double pivoteValor = double.NaN; valorCompareIteracion = double.MaxValue; foreach (VectorEquation eq in tabla.StandardConstraint) { double iteracionN = eq.VectorBody.Where(v => v.Key == refCol.Key).FirstOrDefault().Value; string iteracionS = !string.IsNullOrEmpty(eq.Name) ? eq.Name : string.Empty; if (iteracionN > 0 && (tabla.GetConstants().Where(v => v.Key == eq.Name).FirstOrDefault().Value / iteracionN) < valorCompareIteracion) { pivoteValor = iteracionN; restriccionS = iteracionS; valorCompareIteracion = (tabla.GetConstants().Where(v => v.Key == eq.Name).FirstOrDefault().Value / iteracionN); } if (tabla.IsSolution) { tabla.IsSolution = (iteracionN > 0); } } return(new KeyValuePair <string, double>(restriccionS, pivoteValor)); }
/// <summary> /// Кнопка "вперёд". /// </summary> private void buttonNext_Click(object sender, RoutedEventArgs e) { switch (step) { case 0: //буферизация данных BufferingTableValues(); try { buffer_variable_visualization = new int[variable_visualization.Length]; for (int i = 0; i < variable_visualization.Length; i++) { buffer_variable_visualization[i] = variable_visualization[i]; } //прямой ход Гаусса MatrixTransformation.Gauss(elements, CornerDot, variable_visualization); } catch (Exception d) { MessageBox.Show(d.Message); buttonToMainWindow.Visibility = Visibility.Visible; } //Обновление визуализации переменных. UpdateVisualVariables(); //обновление таблицы UpdateTableValues(); step++; labelsteps.Content = "Шаг 1: Прямой ход метода Гаусса."; break; case 1: //буферизация данных BufferingTableValues(); //Выражение базисных переменных. MatrixTransformation.HoistingMatrix(elements, number_of_permutations); //обновление таблицы UpdateTableValues(); step++; labelsteps.Content = "Шаг 2: Выражение базисных переменных."; break; case 2: //скрываем матрицу scrollgaussgrid.Visibility = Visibility.Hidden; if (simplex_table_was_draw == false) { simplextable = new SimplexTable(number_of_permutations, number_of_free_variables, variable_visualization, elements, target_function_elements, true); MainGrid.Children.Add(simplextable); //Симплекс-таблица была создана simplex_table_was_draw = true; } //показываем симплекс-таблицу simplextable.Visibility = Visibility.Visible; switch (simplextable.ResponseCheck()) { case 0: step++; labelsteps.Content = "Шаг 3: Симплекс-таблица."; break; case 1: step++; if (MinMax == 0) { labelsteps.Content = "Ответ :" + simplextable.Response() * (-1); } else { labelsteps.Content = "Ответ :" + simplextable.Response(); } if (corner_dot_was_added == false) { //добавляем точку corner_dot = simplextable.ResponseCornerDot(step); MainGrid.Children.Add(corner_dot); corner_dot_was_added = true; } //показываем угловую точку решения corner_dot.Visibility = Visibility.Hidden; buttonToMainWindow.Visibility = Visibility.Visible; break; case -1: step++; labelsteps.Content = "Задача не разрешима!"; buttonToMainWindow.Visibility = Visibility.Visible; break; } break; case 3: //выбор опорного simplextable.SelectionOfTheSupportElement(); //обновление данных сиплекс-таблицы simplextable.UpdateSimplexTableValues(); step++; labelsteps.Content = "Шаг " + step + ": Симплекс-таблица. Выбор опорного элемента."; break; default: try { //выбран ли опорный элемент simplextable.ButtonPressedOrNot(); //Смена местами визуализаций переменных(после выбора опорного элемента) + буферизация. simplextable.ChangeOfVisualizationVariables(); //буферизация данных simplextable.BufferingSimplexTableValues(step); //удаляем кнопки simplextable.DeleteButtons(); //вычисление согласно выбранному опорному элементу simplextable.CalculateSimplexTable(); //обновление данных сиплекс-таблицы simplextable.UpdateSimplexTableValues(); switch (simplextable.ResponseCheck()) { case 0: step++; labelsteps.Content = "Шаг " + step + ": Симплекс-таблица. Выбор опорного элемента."; //выбор опорного simplextable.SelectionOfTheSupportElement(); break; case 1: step++; if (MinMax == 0) { labelsteps.Content = "Ответ :" + simplextable.Response() * (-1); } else { labelsteps.Content = "Ответ :" + simplextable.Response(); } //если не была добавлена, то добавляем if (corner_dot_was_added == false) { //добавляем точку corner_dot = simplextable.ResponseCornerDot(step - 4); MainGrid.Children.Add(corner_dot); corner_dot_was_added = true; } //показываем угловую точку решения corner_dot.Visibility = Visibility.Visible; buttonToMainWindow.Visibility = Visibility.Visible; break; case -1: step++; labelsteps.Content = "Задача не разрешима!"; buttonToMainWindow.Visibility = Visibility.Visible; break; } simplextable.CornerPoint(step - 4); } catch (Exception d) { MessageBox.Show(d.Message); } break; } }
// Обновление UpdateGrid в соответствии с текущей симплекс таблицей private void UpdateSimplexGrid() { if ((currentSimplexTable >= 0) & (currentSimplexTable < SimplexTables.Count)) { SimplexTable smptbl = SimplexTables[currentSimplexTable]; Mainpanel.Visible = true; SimplexGrid.RowCount = smptbl.M + 1; SimplexGrid.ColumnCount = smptbl.N + smptbl.M + 2; SimplexGrid.Columns[0].HeaderText = "b"; for (int i = 1; i < SimplexGrid.ColumnCount - 1; i++) { SimplexGrid.Columns[i].HeaderText = "x" + i.ToString(); } SimplexGrid.Columns[SimplexGrid.ColumnCount - 1].HeaderText = "O.O"; for (int i = 0; i < SimplexGrid.RowCount - 1; i++) { SimplexGrid.Rows[i].HeaderCell.Value = "x" + smptbl.BaseVector(i); } if (TaskTypeComboBox.SelectedIndex == 0) { SimplexGrid.Rows[SimplexGrid.RowCount - 1].HeaderCell.Value = "Fmax"; } else { SimplexGrid.Rows[SimplexGrid.RowCount - 1].HeaderCell.Value = "Fmin"; } for (int i = 0; i < SimplexGrid.RowCount; i++) { for (int j = 0; j < SimplexGrid.ColumnCount; j++) { SimplexGrid[j, i].Style.BackColor = Color.White; } } if (smptbl.PivotRow != -1) { for (int i = 0; i < SimplexGrid.ColumnCount; i++) { SimplexGrid[i, smptbl.PivotRow].Style.BackColor = Color.LightYellow; } } if (smptbl.PivotCol != -1) { for (int i = 0; i < SimplexGrid.RowCount; i++) { SimplexGrid[smptbl.PivotCol, i].Style.BackColor = Color.LightYellow; } smptbl.CalcMeritRestrictions(smptbl.PivotCol); } if ((smptbl.PivotRow != -1) & (smptbl.PivotCol != -1)) { for (int i = 0; i < smptbl.M; i++) { if (smptbl.MRVector(i) < 0) { SimplexGrid[SimplexGrid.ColumnCount - 1, i].Value = "Не огр."; } else { SimplexGrid[SimplexGrid.ColumnCount - 1, i].Value = smptbl.MRVector(i); } } } else { for (int i = 0; i < smptbl.M; i++) { SimplexGrid[SimplexGrid.ColumnCount - 1, i].Value = ""; } } smptbl.PrintTable(SimplexGrid); } }
public void SetPivotColRow(int col, int row) { if (SimplexGrid.Visible) { for (int i = 0; i < SimplexGrid.RowCount; i++) { for (int j = 0; j < SimplexGrid.ColumnCount; j++) { SimplexGrid[j, i].Style.BackColor = Color.White; } } if ((col != -1) & (row != -1)) { for (int i = 0; i < SimplexGrid.RowCount; i++) { SimplexGrid[col + 1, i].Style.BackColor = Color.LightYellow; } for (int i = 0; i < SimplexGrid.ColumnCount; i++) { SimplexGrid[i, row].Style.BackColor = Color.LightYellow; } if ((currentSimplexTable >= 0) & (currentSimplexTable < SimplexTables.Count)) { SimplexTable currentsmptbl = SimplexTables[currentSimplexTable]; int PivotCol = col + 1; int PivotRow = row + 1; currentsmptbl.CalcMeritRestrictions(PivotCol); if ((PivotRow != -1) & (PivotCol != -1)) { for (int i = 0; i < currentsmptbl.M; i++) { if (currentsmptbl.MRVector(i) < 0) { SimplexGrid[SimplexGrid.ColumnCount - 1, i].Value = "Не огр."; } else { SimplexGrid[SimplexGrid.ColumnCount - 1, i].Value = currentsmptbl.MRVector(i); } } } else { for (int i = 0; i < currentsmptbl.M; i++) { SimplexGrid[SimplexGrid.ColumnCount - 1, i].Value = ""; } } } } else { for (int i = 0; i < SimplexGrid.RowCount - 1; i++) { SimplexGrid[SimplexGrid.ColumnCount - 1, i].Value = ""; } } } }
private void Implementation() { //создаём сиплекс-таблицу simplextable = new SimplexTable(number_of_basix, number_of_free_variables, variable_visualization, elements, target_function_elements, false); MainGrid.Children.Add(simplextable); //добавляем тильду simplextable.AddTilde(); while (simplextable.ArtificialResponseCheck() != true) { if (simplextable.ResponseCheck() == 1) { //холостой шаг simplextable.RandomIdleStep(); this.Width = 720; //Смена местами визуализаций переменных(после выбора опорного элемента) + буферизация. simplextable.ChangeOfVisualizationVariables(); //вычисление согласно выбранному опорному элементу simplextable.CalculateSimplexTable(); //обновление данных сиплекс-таблицы simplextable.UpdateSimplexTableValues(); simplextable.CornerPoint(step); } else { //выбор опорного simplextable.SelectionRandomSupportElement(); this.Width = 651; //Смена местами визуализаций переменных(после выбора опорного элемента) + буферизация. simplextable.ChangeOfVisualizationVariables(); //вычисление согласно выбранному опорному элементу simplextable.CalculateSimplexTable(); //обновление данных сиплекс-таблицы simplextable.UpdateSimplexTableValues(); simplextable.CornerPoint(step); } } variable_visualization = simplextable.ReturnVariableVisualization(); elements = simplextable.ReturnElements(); elements.RemoveAt(elements.Count - 1); //организация массива для симплекс-метода List <List <double> > temp_elements = new List <List <double> >(); for (int i = 0; i < number_of_basix; i++) { temp_elements.Add(new List <double>()); for (int j = 0; j < number_of_basix; j++) { if (temp_elements[i].Count == i) { temp_elements[i].Add(1); } else { temp_elements[i].Add(0); } } } for (int i = 0; i < number_of_basix; i++) { temp_elements[i].AddRange(elements[i]); } elements = temp_elements; simplextable.HideSimplexTable(); simplextable1 = new SimplexTable(number_of_basix, variable_visualization.Length - number_of_basix, variable_visualization, elements, target_function_elements, true); MainGrid.Children.Add(simplextable1); step = 0; while (simplextable1.ResponseCheck() != 1 && simplextable1.ResponseCheck() != -1) { //выбор опорного simplextable1.SelectionRandomSupportElement(); //Смена местами визуализаций переменных(после выбора опорного элемента) + буферизация. simplextable1.ChangeOfVisualizationVariables(); //вычисление согласно выбранному опорному элементу simplextable1.CalculateSimplexTable(); //обновление данных сиплекс-таблицы simplextable1.UpdateSimplexTableValues(); } if (simplextable1.ResponseCheck() == 1) { if (MinMax == 0) { labelanswer.Content = "Ответ :" + simplextable1.Response() * (-1); } else { labelanswer.Content = "Ответ :" + simplextable1.Response(); } //добавляем точку corner_dot = simplextable1.ResponseCornerDot(step); MainGrid.Children.Add(corner_dot); buttonToMainWindow.Visibility = Visibility.Visible; } else { labelanswer.Content = "Задача не разрешима!"; buttonToMainWindow.Visibility = Visibility.Visible; } step++; }
private void RecalcSimplexTableToolStripMenuItem_Click(object sender, EventArgs e) { if ((currentSimplexTable >= 0) & (currentSimplexTable < SimplexTables.Count)) { SimplexTable currentsmptbl = SimplexTables[currentSimplexTable]; if (currentsmptbl.FillTable(SimplexGrid)) { // Итеративно решаем задачу симплекс-методом if ((!currentsmptbl.Solved) & (!currentsmptbl.Unsolvable) & (!currentsmptbl.Infinity)) { // Проверяем, имеет ли задача бесконечное множество решений if (currentsmptbl.TestForInfinity()) { currentsmptbl.Infinity = true; toolStripStatusLabel.Text = "Задача не имеет бесконечное множество решений!"; } // Проверяем, является ли решение допустимым if (currentsmptbl.TestForUnsolvable()) { currentsmptbl.Unsolvable = true; toolStripStatusLabel.Text = "Задача не имеет допустимых решений!"; } // Проверяем, является ли решение оптимальным if (currentsmptbl.TestForSolved()) { // Проверяем получившееся решение на целочисленность if (currentsmptbl.TestForInteger()) { currentsmptbl.Solved = true; toolStripStatusLabel.Text = "Задача решена!"; } else { currentsmptbl.NonIntegerSolved = true; currentsmptbl.PivotRow = currentsmptbl.MaxDoubleIndex(); SimplexTable smptbl = new SimplexTable(currentsmptbl.N, currentsmptbl.M); smptbl.Assign(currentsmptbl); smptbl.FillTable(SimplexGrid); smptbl.AddNewRest(); smptbl.PivotRow = smptbl.PivotRow + 1; SimplexTables.Add(smptbl); currentSimplexTable = SimplexTables.Count - 1; currentsmptbl = SimplexTables[currentSimplexTable]; UpdateSimplexGrid(); PrintSolveLog(TaskInfotextBox); return; } } if (currentsmptbl.FindOptimalStep()) { SimplexTable smptbl = new SimplexTable(currentsmptbl.N, currentsmptbl.M); smptbl.Assign(currentsmptbl); smptbl.FillTable(SimplexGrid); SimplexTables.Add(smptbl); currentSimplexTable = SimplexTables.Count - 1; toolStripStatusLabel.Text = " Итерация: " + currentSimplexTable.ToString(); smptbl.PivotRow = smptbl.PivotRow + 1; smptbl.RecalcTable(); smptbl.PivotRow = -1; smptbl.PivotCol = -1; UpdateSimplexGrid(); } } } } PrintSolveLog(TaskInfotextBox); }
/// <summary> /// Кнопка "Вперёд". /// </summary> private void buttonNext_Click(object sender, RoutedEventArgs e) { try { //для запоминания типа шага if (simplextable.ResponseCheck() == 1) { type_of_step.Add(false); } else { type_of_step.Add(true); } //выбран ли опорный элемент simplextable.ButtonPressedOrNot(); //Смена местами визуализаций переменных(после выбора опорного элемента) + буферизация. simplextable.ChangeOfVisualizationVariables(); //буферизация данных simplextable.BufferingSimplexTableValuesTest(); //удаляем кнопки simplextable.DeleteButtons(); //вычисление согласно выбранному опорному элементу simplextable.CalculateSimplexTable(); //обновление данных сиплекс-таблицы simplextable.UpdateSimplexTableValues(); simplextable.CornerPoint(step); //проверка решения switch (simplextable.ArtificialResponseCheck()) { case true: variable_visualization = simplextable.ReturnVariableVisualization(); elements = simplextable.ReturnElements(); elements.RemoveAt(elements.Count - 1); //организация массива для симплекс-метода List <List <double> > temp_elements = new List <List <double> >(); for (int i = 0; i < number_of_basix; i++) { temp_elements.Add(new List <double>()); for (int j = 0; j < number_of_basix; j++) { if (temp_elements[i].Count == i) { temp_elements[i].Add(1); } else { temp_elements[i].Add(0); } } } for (int i = 0; i < number_of_basix; i++) { temp_elements[i].AddRange(elements[i]); } elements = temp_elements; buttonBack.Visibility = Visibility.Hidden; buttonNext.Visibility = Visibility.Hidden; buttonBack1.Visibility = Visibility.Visible; buttonNext1.Visibility = Visibility.Visible; simplextable.HideSimplexTable(); step++; if (simplex_table_was_draw == false) { simplextable1 = new SimplexTable(number_of_basix, variable_visualization.Length - number_of_basix, variable_visualization, elements, target_function_elements, true); MainGrid.Children.Add(simplextable1); //Симплекс-таблица была создана simplex_table_was_draw = true; } else { simplextable1.DeleteButtons(); MainGrid.Children.Add(simplextable1); simplextable1.SetVariableVisualization(simplextable.ReturnVariableVisualization()); simplextable1.SetElements(elements); simplextable1.UpdateValuesNewStage(); } //проверка решения switch (simplextable1.ResponseCheck()) { case 0: //выбор опорного simplextable1.SelectionOfTheSupportElement(); labelsteps.Content = "Шаг " + step + ": Симплекс-таблица."; break; case 1: if (MinMax == 0) { labelsteps.Content = "Ответ :" + simplextable1.Response() * (-1); } else { labelsteps.Content = "Ответ :" + simplextable1.Response(); } if (corner_dot_was_added == false) { //добавляем точку corner_dot = simplextable1.ResponseCornerDot(0); MainGrid.Children.Add(corner_dot); corner_dot_was_added = true; } corner_dot.Visibility = Visibility.Visible; buttonToMainWindow.Visibility = Visibility.Visible; buttonNext1.Visibility = Visibility.Hidden; break; case -1: labelsteps.Content = "Задача не разрешима!"; buttonToMainWindow.Visibility = Visibility.Visible; buttonNext1.Visibility = Visibility.Hidden; break; } break; case false: if (simplextable.ResponseCheck() == 1) { step++; labelsteps.Content = "Холостой шаг: Метод искусственного базиса. Выбор опорного элемента."; //холостой шаг simplextable.IdleStep(); this.Width = 720; } else { step++; labelsteps.Content = "Шаг " + step + ": Метод искусственного базиса. Выбор опорного элемента."; //выбор опорного simplextable.SelectionOfTheSupportElement(); this.Width = 651; } break; } } catch (Exception d) { MessageBox.Show(d.Message); } }
public MainWindowViewModel() { InputTable = new SimplexTable(); }
private void PrintSolveLog(TextBox txtBox) { try { LockWindowUpdate(TaskInfotextBox.Handle); TaskInfotextBox.Clear(); if (IsNewTask) { CanonicalN = SourceN; CanonicalM = SourceM; CanonicalTaskType = SourceTaskType; for (int i = 0; i < SourceM; i++) { CanonicalSign[i] = SourceSign[i]; CanonicalVectorb[i] = SourceVectorb[i]; for (int j = 0; j < SourceN; j++) { CanonicalVectorc[j] = SourceVectorc[j]; CanonicalMatrixA[i, j] = SourceMatrixA[i, j]; } } txtBox.AppendText("Исходная задача:"); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); for (int i = 0; i < SourceM; i++) { PrintRest(txtBox, SourceMatrixA, SourceSign, SourceVectorb, i, SourceN); } txtBox.AppendText(Environment.NewLine); PrintF(txtBox, SourceVectorc, SourceN, SourceTaskType); txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Приводим к каноническому виду: "); int LStepCount = 1; bool LCanonicalForm = true; for (int i = 0; i < SourceM; i++) { switch (SourceSign[i]) { case 0: // '=' LCanonicalForm = false; txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("{0}. Избавляемся от знака равенства в {1} - ограничении. Что бы поменять знак '=' на неравенство '<=', вводим в задачу еще одно такое же ограничение, но с противоположенными знаками: ", LStepCount, i + 1)); txtBox.AppendText(Environment.NewLine); CanonicalM++; for (int j = 0; j < CanonicalN; j++) { CanonicalMatrixA[CanonicalM - 1, j] = -CanonicalMatrixA[i, j]; } CanonicalVectorb[CanonicalM - 1] = -CanonicalVectorb[i]; CanonicalSign[i] = 2; CanonicalSign[CanonicalM - 1] = 2; txtBox.AppendText(Environment.NewLine); PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, CanonicalM - 1, CanonicalN); LStepCount++; break; case 1: // '>=' LCanonicalForm = false; txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("{0}. Избавляемся от знака больше-равно в {1} - ограничении. Что бы поменять неравенство '>=' на неравенство '<=', меняем знаки в этом ограничении на противоположенные: ", LStepCount, i + 1)); txtBox.AppendText(Environment.NewLine); CanonicalVectorb[i] = -CanonicalVectorb[i]; for (int j = 0; j < CanonicalN; j++) { CanonicalMatrixA[i, j] = -CanonicalMatrixA[i, j]; } CanonicalSign[i] = 2; txtBox.AppendText(Environment.NewLine); PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, i, CanonicalN); LStepCount++; break; } } // Меняем знаки при целевой функции if (SourceTaskType == 0) { for (int i = 0; i < CanonicalN; i++) { CanonicalVectorc[i] = -CanonicalVectorc[i]; } txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("{0}. Т.к. задача на максимизацию, то меняем знаки при целевой функции:", LStepCount)); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); PrintF(txtBox, CanonicalVectorc, CanonicalN, CanonicalTaskType); LStepCount++; } if (LCanonicalForm) { txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Задача уже записана в каноническом виде, и не требует дополнительных преобразований."); txtBox.AppendText(Environment.NewLine); } else { txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Записываем канонический вид задачи, после преобразований: "); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); for (int i = 0; i < CanonicalM; i++) { PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, i, CanonicalN); } txtBox.AppendText(Environment.NewLine); PrintF(txtBox, CanonicalVectorc, CanonicalN, CanonicalTaskType); txtBox.AppendText(Environment.NewLine); } } else { txtBox.AppendText("Исходная задача:"); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); for (int i = 0; i < CanonicalM; i++) { PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, i, CanonicalN); } txtBox.AppendText(Environment.NewLine); PrintF(txtBox, CanonicalVectorc, CanonicalN, CanonicalTaskType); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Задача уже записана в каноническом виде, и не требует дополнительных преобразований."); txtBox.AppendText(Environment.NewLine); } for (int i = 0; i < SimplexTables.Count; i++) { SimplexTable smptbl = SimplexTables[i]; txtBox.AppendText(Environment.NewLine); txtBox.AppendText("----------------------------"); if (smptbl.Solved) { txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Среди значений коэффициентов целевой функции нет отрицательных. Поэтому задача решена!"); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); for (int j = 0; j < smptbl.N; j++) { txtBox.AppendText(String.Format("x{0} = {1}", j + 1, smptbl.Roots(j))); txtBox.AppendText(Environment.NewLine); } txtBox.AppendText(Environment.NewLine); if (smptbl.TaskType == 1) { txtBox.AppendText("Так как исходной задачей был поиск минимума, оптимальное решение есть свободный член строки F, взятый с противоположным знаком."); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", -smptbl.FunctionValue())); } else { txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", smptbl.FunctionValue())); } return; } if (smptbl.Infinity) { txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Оптимального решения не существует! Т.к. данная задача не ограничена."); return; } if (smptbl.Unsolvable) { txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Так как в строке с отрицательным свободным членом нет отрицательных элементов, то система ограничений не совместна и задача не имеет решения."); return; } if (smptbl.NonIntegerSolved) { txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Среди значений коэффициентов целевой функции нет отрицательных. Поэтому найдено оптимальное решение."); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); for (int j = 0; j < smptbl.N; j++) { txtBox.AppendText(String.Format("x{0} = {1}", j + 1, smptbl.RootsFraction(j).ToString())); txtBox.AppendText(Environment.NewLine); } txtBox.AppendText(Environment.NewLine); if (smptbl.TaskType == 1) { txtBox.AppendText("Так как исходной задачей был поиск минимума, оптимальное решение есть свободный член строки F, взятый с противоположным знаком."); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", (-smptbl.FunctionValueFraction()).ToString())); } else { txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", smptbl.FunctionValueFraction().ToString())); } txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Получившееся оптимальное решение нецелочисленное. Среди свободных членов находим переменную с максимальным дробным числом:"); txtBox.AppendText(Environment.NewLine); double value = 0; int MaxIndex = 0; double MaxValue = 0; txtBox.AppendText(Environment.NewLine); for (int j = 0; j < smptbl.M; j++) { if (smptbl.BaseVector(j) <= smptbl.N) { value = Math.Abs(smptbl.Table(j, 0)) - Math.Abs(Math.Floor(smptbl.Table(j, 0))); if (MaxValue < value) { MaxValue = value; MaxIndex = j; } txtBox.AppendText(String.Format("x{0} = {1} = {2}", smptbl.BaseVector(j), smptbl.FractionTable(j, 0).ToString(), smptbl.Table(j, 0))); txtBox.AppendText(Environment.NewLine); } } txtBox.AppendText(Environment.NewLine); txtBox.AppendText("x" + smptbl.BaseVector(MaxIndex).ToString() + " - свободный член с максимальным дробным числом. Поэтому вводим дополнительное ограничение по " + (MaxIndex + 1) + " строке:"); txtBox.AppendText(Environment.NewLine); string LLineStr = ""; txtBox.AppendText(Environment.NewLine); double sign = smptbl.Table(MaxIndex, 0) / smptbl.Table(MaxIndex, 0); Fraction FractionValue = new Fraction(smptbl.FractionTable(MaxIndex, 0)); if (FractionValue < 0) { FractionValue = FractionValue * -1; } FractionValue = FractionValue - Math.Truncate(Math.Abs(smptbl.FractionTable(MaxIndex, 0).ToDouble())); bool isfirst = true; FractionValue = FractionValue * sign * -1; LLineStr = LLineStr + FractionValue.ToString() + " = "; for (int j = 1; j < smptbl.Сols; j++) { if (smptbl.FractionTable(MaxIndex, j) >= 0) { value = Math.Truncate(smptbl.FractionTable(MaxIndex, j).ToDouble()); FractionValue = -(smptbl.FractionTable(MaxIndex, j) - value); } else { value = Math.Abs(Math.Truncate(smptbl.FractionTable(MaxIndex, j).ToDouble())); FractionValue = -(smptbl.FractionTable(MaxIndex, j) + value + 1); } if (FractionValue > 0) { if (isfirst) { LLineStr = LLineStr + FractionValue.ToString() + "x" + j; } else { LLineStr = LLineStr + " + " + FractionValue.ToString() + "x" + j; } isfirst = false; } else { LLineStr = LLineStr + " - " + (FractionValue * -1).ToString() + "x" + j; isfirst = false; } } LLineStr = LLineStr + " + " + "x" + (smptbl.N + smptbl.M + 1); txtBox.AppendText(LLineStr); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); txtBox.AppendText("Пересчитываем получившуюся таблицу:"); continue; } if ((smptbl.PivotCol != -1) & (smptbl.PivotRow != -1)) { txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("Итерация {0}:", i + 1)); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("Ведущий столбец: {0}", SimplexTables[i].PivotCol)); txtBox.AppendText(Environment.NewLine); txtBox.AppendText(String.Format("Ведущая строка: {0}", SimplexTables[i].PivotRow + 1)); } } } finally { LockWindowUpdate(IntPtr.Zero); } }