[Test] public void DirectSimplex() { var x1 = Variable.Input("X1"); var x2 = Variable.Input("X2"); var x3 = Variable.Input("X3"); var s1 = Variable.Slack("S1"); var s2 = Variable.Slack("S2"); var s3 = Variable.Slack("S3"); var c1 = Constraint.LessThanOrEqualTo("C1", 8, x1.As(2), x2.As(3)); var c2 = Constraint.LessThanOrEqualTo("C2", 10, x2.As(2), x3.As(5)); var c3 = Constraint.LessThanOrEqualTo("C3", 15, x1.As(3), x2.As(2), x3.As(4)); var solverIteration = new SolverIteration { ObjectiveVariables = new BigRational[] { 3, 5, 4, 0, 0, 0 }, Variables = new[] { x1, x2, x3, s1, s2, s3 }, Bases = new[] { s1, s2, s3 }, BaseVariables = new BigRational[] { 8, 10, 15 }, DecisionVariables = new BigRational[] { -3, -5, -4, 0, 0, 0 }, InputGrid = new[] { new BigRational[] { 2, 3, 0, 1, 0, 0 }, new BigRational[] { 0, 2, 5, 0, 1, 0 }, new BigRational[] { 3, 2, 4, 0, 0, 1 } } }; var res = LinearModelSolver.Simplex(solverIteration, new List <Constraint>(new[] { c1, c2, c3 })); Assert.IsTrue(res.Result == SolvedResult.Optimized); Assert.AreEqual(new BigRational(765, 41), res.Z); }
//Compute SolverIteration from preceding iteration private static SolverIteration ComputeIteration(SolverIteration previous) { SolverIteration iteration = previous.Copy(); var column = IncomingVariable(iteration.DecisionVariables); var row = LeavingVariable(GetColumn(iteration.InputGrid, column), iteration.BaseVariables); var variable = iteration.InputGrid[row][column]; var rowArray = iteration.InputGrid[row]; for (int i = 0; i < rowArray.Length; i++) { rowArray[i] /= variable; } iteration.BaseVariables[row] /= variable; for (int i = 0; i < iteration.InputGrid.Length; i++) { if (i == row) { continue; } var value = iteration.InputGrid[i][column]; for (int j = 0; j < iteration.InputGrid[i].Length; j++) { iteration.InputGrid[i][j] -= value * iteration.InputGrid[row][j]; } iteration.BaseVariables[i] -= value * iteration.BaseVariables[row]; } var val = iteration.DecisionVariables[column]; for (int i = 0; i < iteration.DecisionVariables.Length; i++) { iteration.DecisionVariables[i] -= val * iteration.InputGrid[row][i]; } iteration.Bases[row] = iteration.Variables[column]; iteration.Z = 0; for (var i = 0; i < iteration.Bases.Length; i++) { var baseVar = iteration.Bases[i]; iteration.Z += GetVariableObjective(baseVar, iteration) * iteration.BaseVariables[i]; } previous.SelectedGridPositions = (row, column); return(iteration); }
//Run simplex algorithm starting from an initial SolverIteration public static SolvedModel Simplex(SolverIteration initialIteration, List <Constraint> constraints) { var listIterations = new List <SolverIteration>(new [] { initialIteration }); SolverIteration currentIteration = initialIteration; while (true) { if (currentIteration.DecisionVariables.All(dv => dv >= 0)) { var model = new SolvedModel { SimplexIterations = listIterations, Constraints = constraints.ToList(), Variables = currentIteration.Variables.ToList(), Z = currentIteration.Z }; //Initialize dir for all vars foreach (var variable in currentIteration.Variables) { model.ObjectiveResult[variable] = BigRational.Zero; } for (int i = 0; i < currentIteration.Bases.Length; i++) { model.ObjectiveResult[currentIteration.Bases[i]] = currentIteration.BaseVariables[i]; } model.Result = constraints.All(c => ConstraintPasses(c, model.ObjectiveResult)) ? SolvedResult.Optimized : SolvedResult.Infeasible; return(model); } try { currentIteration = ComputeIteration(currentIteration); listIterations.Add(currentIteration); } catch (UnboundedException) { return(new SolvedModel { Variables = initialIteration.Variables.ToList(), Constraints = constraints.ToList(), SimplexIterations = listIterations, Result = SolvedResult.Unbounded }); } } }
//Get objective value of variable from current iteration private static BigRational GetVariableObjective(Variable variable, SolverIteration iteration) { var columnIndex = Array.IndexOf(iteration.Variables, variable); if (columnIndex == -1) { return(0); } else { return(iteration.ObjectiveVariables[columnIndex]); } }
//Remove artificial variable indexes after two-phases finishes public static SolverIteration RemoveIndexes(SolverIteration iteration, int cutoffIndex) { var cutIteration = iteration.Copy(); var variables = iteration.Variables.Take(cutoffIndex).ToArray(); var objectiveVariables = iteration.ObjectiveVariables.Take(cutoffIndex) .ToArray(); var decisionVariables = iteration.DecisionVariables.Take(cutoffIndex) .ToArray(); var inputGrid = new List <BigRational[]>(); for (int i = 0; i < iteration.InputGrid.Length; i++) { inputGrid.Add(iteration.InputGrid[i].Take(cutoffIndex).ToArray()); } cutIteration.Variables = variables; cutIteration.ObjectiveVariables = objectiveVariables; cutIteration.DecisionVariables = decisionVariables; cutIteration.InputGrid = inputGrid.ToArray(); return(cutIteration); }
[Test] public void DirectTwoPhases() { var x1 = new Variable { Name = "X1", Type = VariableType.Input }; var x2 = new Variable { Name = "X2", Type = VariableType.Input }; var s1 = new Variable { Name = "S1", Type = VariableType.Slack }; var s2 = new Variable { Name = "S2", Type = VariableType.Slack }; var a1 = new Variable { Name = "A1", Type = VariableType.Artificial }; var a2 = new Variable { Name = "A2", Type = VariableType.Artificial }; var c1 = new Constraint { Name = "C1", ConstraintType = ConstraintType.GreaterThanOrEqualTo, Variables = new List <ValueVariable>(new[] { new ValueVariable { Variable = x1, Coefficient = 2 }, new ValueVariable { Variable = x2, Coefficient = 1 }, }), ConstraintValue = 4 }; var c2 = new Constraint { Name = "C2", ConstraintType = ConstraintType.GreaterThanOrEqualTo, Variables = new List <ValueVariable>(new[] { new ValueVariable { Variable = x1, Coefficient = 1 }, new ValueVariable { Variable = x2, Coefficient = 7 }, }), ConstraintValue = 7 }; var solverIteration = new SolverIteration { ObjectiveVariables = new BigRational[] { -1, -1, 0, 0, 0, 0 }, Variables = new[] { x1, x2, s1, s2, a1, a2 }, Bases = new[] { x1, x2 }, BaseVariables = new BigRational[] { 4, 7 }, DecisionVariables = new BigRational[] { -3, -8, 1, 1, 0, 0 }, InputGrid = new[] { new BigRational[] { 2, 1, -1, 0, 1, 0 }, new BigRational[] { 1, 7, 0, -1, 0, 1 }, } }; var res = LinearModelSolver.TwoPhases(solverIteration, new List <Constraint>(new[] { c1, c2 })); Assert.AreEqual(new BigRational(-31, 13), res.Z); }
//Run two-phases simplex algorithm starting from an initial SolverIteration public static SolvedModel TwoPhases(SolverIteration initialIteration, List <Constraint> constraints) { var twoPhasesInitialIteration = initialIteration.Copy(); int artificialCutoff = -1; for (int i = 0; i < initialIteration.Variables.Length; i++) { if (initialIteration.Variables[i].Type == VariableType.Artificial) { artificialCutoff = i; break; } } if (artificialCutoff == -1) { throw new ArgumentException(); } var twoPhasesObjective = Enumerable.Repeat <BigRational>( BigRational.One, twoPhasesInitialIteration.Variables.Length).ToArray(); for (int i = 0; i < artificialCutoff; i++) { twoPhasesObjective[i] = 0; } twoPhasesInitialIteration.ObjectiveVariables = twoPhasesObjective; var twoPhaseBases = twoPhasesInitialIteration .Variables.Skip( twoPhasesInitialIteration.Variables.Length - twoPhasesInitialIteration.Bases.Length) .ToArray(); twoPhasesInitialIteration.Bases = twoPhaseBases; for (int i = 0; i < twoPhasesInitialIteration.Variables.Length; i++) { BigRational Zj = BigRational.Zero; for (int j = 0; j < twoPhasesInitialIteration.Bases.Length; j++) { var rowVariable = twoPhasesInitialIteration.Bases[j]; var rowObjectiveIndex = Array.IndexOf(twoPhasesInitialIteration.Variables, rowVariable); var rowObjective = twoPhasesInitialIteration.ObjectiveVariables[rowObjectiveIndex]; Zj += twoPhasesInitialIteration.InputGrid[j][i] * rowObjective; } twoPhasesInitialIteration.DecisionVariables[i] = twoPhasesInitialIteration.ObjectiveVariables[i] - Zj; } twoPhasesInitialIteration.Z = 0; for (var i = 0; i < twoPhasesInitialIteration.Bases.Length; i++) { var baseVar = twoPhasesInitialIteration.Bases[i]; var columnIndex = Array.IndexOf(twoPhasesInitialIteration.Variables, baseVar); twoPhasesInitialIteration.Z += twoPhasesInitialIteration.BaseVariables[i] * twoPhasesInitialIteration.ObjectiveVariables[columnIndex]; } var solvedTwoPhases = Simplex(twoPhasesInitialIteration, constraints); solvedTwoPhases.TwoPhasesIterations = solvedTwoPhases.SimplexIterations; solvedTwoPhases.SimplexIterations = new List <SolverIteration>(); if (solvedTwoPhases.Result != SolvedResult.Optimized) { return(solvedTwoPhases); } if (solvedTwoPhases.Z != 0) { solvedTwoPhases.Result = SolvedResult.Unbounded; return(solvedTwoPhases); } var finalIteration = solvedTwoPhases.TwoPhasesIterations.Last(); for (int i = 0; i < finalIteration.Bases.Length; i++) { if (finalIteration.Bases[i].Type == VariableType.Artificial && finalIteration.BaseVariables[i] > 0) { solvedTwoPhases.Result = SolvedResult.Infeasible; return(solvedTwoPhases); } } finalIteration = RemoveIndexes( finalIteration.Copy(), artificialCutoff); finalIteration.ObjectiveVariables = initialIteration.ObjectiveVariables.Take(artificialCutoff).ToArray(); finalIteration.Z = 0; for (var i = 0; i < finalIteration.Bases.Length; i++) { var baseVar = finalIteration.Bases[i]; var columnIndex = Array.IndexOf(finalIteration.Variables, baseVar); if (columnIndex == -1) { finalIteration.Z += 0; } else { finalIteration.Z += finalIteration.BaseVariables[i] * finalIteration.ObjectiveVariables[columnIndex]; } } for (int i = 0; i < finalIteration.Variables.Length; i++) { var zj = -GetColumn(finalIteration.InputGrid, i).Sum(); var cj = finalIteration.ObjectiveVariables[i]; finalIteration.DecisionVariables[i] = -GetColumn(finalIteration.InputGrid, i).Sum() - finalIteration.ObjectiveVariables[i]; } var simplexResult = Simplex(finalIteration, constraints); simplexResult.TwoPhasesIterations = solvedTwoPhases.TwoPhasesIterations; return(simplexResult); }
//Build first SolverIteration from LinearModel public static SolverIteration BuildFirstIteration(LinearModel model) { var variables = model.Variables.ToList(); var constraints = model.Constraints.Select(c => c.Copy()).ToList(); var objectives = model.ObjectiveFunction .Select(vv => vv.Coefficient).ToList(); if (model.Objective == Objective.MIN) { objectives = objectives.Select(o => o * -1).ToList(); } var inputGrid = new List <List <BigRational> >(); int slackCount = 0; int artificialCount = 0; foreach (var constraint in constraints) { if (constraint.ConstraintValue < 0) { switch (constraint.ConstraintType) { case ConstraintType.LessThanOrEqualTo: constraint.ConstraintType = ConstraintType.GreaterThanOrEqualTo; break; case ConstraintType.GreaterThanOrEqualTo: constraint.ConstraintType = ConstraintType.LessThanOrEqualTo; break; case ConstraintType.EqualTo: break; default: throw new ArgumentOutOfRangeException(); } for (int i = 0; i < constraint.Variables.Count; i++) { constraint.Variables[i].Coefficient *= -1; } constraint.ConstraintValue *= -1; } switch (constraint.ConstraintType) { case ConstraintType.LessThanOrEqualTo: { var slack = new Variable { Name = $"S{++slackCount}", Type = VariableType.Slack }; variables.Add(slack); objectives.Add(0); constraint.Variables.Add(new ValueVariable { Variable = slack, Coefficient = 1 }); break; } case ConstraintType.GreaterThanOrEqualTo: { var slack = new Variable { Name = $"S{++slackCount}", Type = VariableType.Slack }; var artificial = new Variable { Name = $"A{++artificialCount}", Type = VariableType.Artificial }; variables.Add(slack); objectives.Add(BigRational.Zero); variables.Add(artificial); objectives.Add(BigRational.Zero); constraint.Variables.Add(new ValueVariable { Variable = slack, Coefficient = -1 }); constraint.Variables.Add(new ValueVariable { Variable = artificial, Coefficient = 1 }); break; } case ConstraintType.EqualTo: { var artificial = new Variable { Name = $"A{++artificialCount}", Type = VariableType.Artificial }; variables.Add(artificial); objectives.Add(0); constraint.Variables.Add(new ValueVariable { Variable = artificial, Coefficient = 1 }); break; } default: throw new ArgumentOutOfRangeException(); } } variables.Sort((v1, v2) => v1.Type - v2.Type); foreach (var constraint in constraints) { foreach (var missingVariable in variables.Except(constraint.Variables.Select(vv => vv.Variable))) { constraint.Variables.Add(missingVariable.As(0)); } } foreach (var constraint in constraints) { constraint.Variables.Sort((vv1, vv2) => variables.IndexOf(vv1.Variable) - variables.IndexOf(vv2.Variable)); } inputGrid = constraints .Select(c => c.Variables .Select(v => v.Coefficient).ToList()) .ToList(); var firstIteration = new SolverIteration { Variables = variables.ToArray(), Z = BigRational.Zero, ObjectiveVariables = objectives.ToArray(), DecisionVariables = objectives.Select(o => o * -1).ToArray(), BaseVariables = constraints.Select(c => c.ConstraintValue).ToArray(), Bases = variables.Skip(variables.Count - constraints.Count).ToArray(), InputGrid = inputGrid.Select(r => r.ToArray()).ToArray() }; return(firstIteration); }
private void BuildGrid(SolverIteration iterationBase) { //Set grid alignment Grid.HorizontalAlignment = HorizontalAlignment.Left; Grid.VerticalAlignment = VerticalAlignment.Top; //Clear previous grid info Grid.Children.Clear(); Grid.ColumnDefinitions.Clear(); Grid.RowDefinitions.Clear(); //Default columns var baseColumn = new ColumnDefinition(); Grid.ColumnDefinitions.Add(baseColumn); var objectiveColumn = new ColumnDefinition(); Grid.ColumnDefinitions.Add(objectiveColumn); foreach (var _ in iterationBase.Variables) { Grid.ColumnDefinitions.Add(new ColumnDefinition()); } var objectiveRow = new RowDefinition(); Grid.RowDefinitions.Add(objectiveRow); var nameRow = new RowDefinition(); Grid.RowDefinitions.Add(nameRow); foreach (var _ in Model.Constraints) { Grid.RowDefinitions.Add(new RowDefinition()); } var decisionRow = new RowDefinition(); Grid.RowDefinitions.Add(decisionRow); //Size rows and columns // var gridWidth = Grid.Width; // var cellWidth = gridWidth / Grid.ColumnDefinitions.Count; // // // var gridHeight = Grid.Height; // var cellHeight = gridHeight / Grid.RowDefinitions.Count; // // // foreach (var columnDefinition in Grid.ColumnDefinitions) // { // columnDefinition.Width = new GridLength(cellWidth); // } // // foreach (var rowDefinition in Grid.RowDefinitions) // { // rowDefinition.Height = new GridLength(cellHeight); // } //Build grid rectangles var rects = new List <List <Rectangle> >(); for (int i = 0; i < Grid.RowDefinitions.Count; i++) { var rectR = new List <Rectangle>(); for (int j = 0; j < Grid.ColumnDefinitions.Count; j++) { var rect = new Rectangle { Stroke = Brushes.Black, Fill = Brushes.Transparent }; rectR.Add(rect); Grid.SetRow(rect, i); Grid.SetColumn(rect, j); Grid.Children.Add(rect); } rects.Add(rectR); } Rectangles = rects.Select(r => r.ToArray()).ToArray(); //Build default grid blocks Tableau = new TextBlock { Text = "Tableau", FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; Rectangles[0][0].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(Tableau, 0); Grid.SetColumn(Tableau, 0); Grid.Children.Add(Tableau); var baseBlock = new TextBlock { Text = "Base", FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; Rectangles[1][0].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(baseBlock, 1); Grid.SetColumn(baseBlock, 0); Grid.Children.Add(baseBlock); var b = new TextBlock { Text = "b", FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center };; Rectangles[1][1].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(b, 1); Grid.SetColumn(b, 1); Grid.Children.Add(b); var z = new TextBlock { Text = "Z", FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; Rectangles[Grid.RowDefinitions.Count - 1][0].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(z, Grid.RowDefinitions.Count - 1); Grid.SetColumn(z, 0); Grid.Children.Add(z); Z = new TextBlock { Text = "0", FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center };; Grid.SetRow(Z, Grid.RowDefinitions.Count - 1); Grid.SetColumn(Z, 1); Grid.Children.Add(Z); var objectiveBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.ColumnDefinitions.Count; i++) { var block = new TextBlock { Text = $"X{i-1}", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; objectiveBlocks.Add(block); Grid.SetRow(block, 0); Grid.SetColumn(block, i); Grid.Children.Add(block); } ObjectiveRows = objectiveBlocks.ToArray(); var variableBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.ColumnDefinitions.Count; i++) { var block = new TextBlock { Text = $"X{i-1}", FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; variableBlocks.Add(block); Rectangles[1][i].Fill = Brushes.CadetBlue; Grid.SetRow(block, 1); Grid.SetColumn(block, i); Grid.Children.Add(block); } Variables = variableBlocks.ToArray(); var baseBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.RowDefinitions.Count - 1; i++) { var block = new TextBlock { Text = $"X{i-1}", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; baseBlocks.Add(block); Grid.SetRow(block, i); Grid.SetColumn(block, 0); Grid.Children.Add(block); } Bases = baseBlocks.ToArray(); var baseVarBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.RowDefinitions.Count - 1; i++) { var block = new TextBlock { Text = $"0", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; baseVarBlocks.Add(block); Grid.SetRow(block, i); Grid.SetColumn(block, 1); Grid.Children.Add(block); } BaseVariables = baseVarBlocks.ToArray(); var varGrid = new List <List <TextBlock> >(); for (int i = 2; i < Grid.RowDefinitions.Count - 1; i++) { var varRow = new List <TextBlock>(); for (int j = 2; j < Grid.ColumnDefinitions.Count; j++) { var block = new TextBlock { Text = $"0", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; varRow.Add(block); Grid.SetRow(block, i); Grid.SetColumn(block, j); Grid.Children.Add(block); } varGrid.Add(varRow); } VariableGrid = varGrid.Select(r => r.ToArray()).ToArray(); var decisionVars = new List <TextBlock>(); for (int i = 2; i < Grid.ColumnDefinitions.Count; i++) { var block = new TextBlock { Text = $"0", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; decisionVars.Add(block); Grid.SetColumn(block, i); Grid.SetRow(block, Grid.RowDefinitions.Count - 1); Grid.Children.Add(block); } DecisionVariables = decisionVars.ToArray(); //BackButton.Content = Resources["BackArrowEnabled"]; //https://stackoverflow.com/questions/3789256/wpf-gridlines-changing-style //https://www.c-sharpcorner.com/UploadFile/mahesh/grid-in-wpf/#:~:text=The%20ColumnDefinitions%20property%20is%20used,three%20rows%20to%20a%20grid.&text=Any%20control%20in%20WPF%20can,Row%20and%20Grid. }
public void BuildGrid(SolverIteration iterationBase) { //Set grid alignment Grid.HorizontalAlignment = HorizontalAlignment.Left; Grid.VerticalAlignment = VerticalAlignment.Top; //Clear previous grid info Grid.Children.Clear(); Grid.ColumnDefinitions.Clear(); Grid.RowDefinitions.Clear(); //Default columns var baseColumn = new ColumnDefinition(); Grid.ColumnDefinitions.Add(baseColumn); var objectiveColumn = new ColumnDefinition(); Grid.ColumnDefinitions.Add(objectiveColumn); foreach (var _ in iterationBase.Variables) { Grid.ColumnDefinitions.Add(new ColumnDefinition()); } var objectiveRow = new RowDefinition(); Grid.RowDefinitions.Add(objectiveRow); var nameRow = new RowDefinition(); Grid.RowDefinitions.Add(nameRow); foreach (var _ in Model.Constraints) { Grid.RowDefinitions.Add(new RowDefinition()); } var decisionRow = new RowDefinition(); Grid.RowDefinitions.Add(decisionRow); //Size rows and columns var init = Grid.IsInitialized; //var gridWidth = 774d; var gridWidth = Grid.Width; var cellWidth = gridWidth / Grid.ColumnDefinitions.Count; //var gridHeight = 375.04d; var gridHeight = Grid.Height; var cellHeight = gridHeight / Grid.RowDefinitions.Count; foreach (var columnDefinition in Grid.ColumnDefinitions) { columnDefinition.Width = new GridLength(cellWidth); } foreach (var rowDefinition in Grid.RowDefinitions) { rowDefinition.Height = new GridLength(cellHeight); } //Build grid rectangles var rects = new List <List <Rectangle> >(); for (int i = 0; i < Grid.RowDefinitions.Count; i++) { var rectR = new List <Rectangle>(); for (int j = 0; j < Grid.ColumnDefinitions.Count; j++) { var rect = new Rectangle { Stroke = Brushes.Black, Fill = Brushes.Transparent, }; var border = new Border { BorderBrush = Brushes.Black, BorderThickness = new Thickness(1) }; rectR.Add(rect); Grid.SetRow(rect, i); Grid.SetRow(border, i); Grid.SetColumn(rect, j); Grid.SetColumn(border, j); Grid.Children.Add(rect); Grid.Children.Add(border); } rects.Add(rectR); } Rectangles = rects.Select(r => r.ToArray()).ToArray(); //Build default grid blocks Tableau = new TextBlock { Text = "Tableau", FontWeight = FontWeight.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; Rectangles[0][0].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(Tableau, 0); Grid.SetColumn(Tableau, 0); Grid.Children.Add(Tableau); var baseBlock = new TextBlock { Text = "Base", FontWeight = FontWeight.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; Rectangles[1][0].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(baseBlock, 1); Grid.SetColumn(baseBlock, 0); Grid.Children.Add(baseBlock); var b = new TextBlock { Text = "b", FontWeight = FontWeight.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center };; Rectangles[1][1].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(b, 1); Grid.SetColumn(b, 1); Grid.Children.Add(b); var z = new TextBlock { Text = "Z", FontWeight = FontWeight.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; Rectangles[Grid.RowDefinitions.Count - 1][0].Fill = new SolidColorBrush(Colors.CadetBlue); Grid.SetRow(z, Grid.RowDefinitions.Count - 1); Grid.SetColumn(z, 0); Grid.Children.Add(z); Z = new TextBlock { Text = "0", FontWeight = FontWeight.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; Grid.SetRow(Z, Grid.RowDefinitions.Count - 1); Grid.SetColumn(Z, 1); Grid.Children.Add(Z); var objectiveBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.ColumnDefinitions.Count; i++) { var block = new TextBlock { Text = $"X{i-1}", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; objectiveBlocks.Add(block); Grid.SetRow(block, 0); Grid.SetColumn(block, i); Grid.Children.Add(block); } ObjectiveRows = objectiveBlocks.ToArray(); var variableBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.ColumnDefinitions.Count; i++) { var block = new TextBlock { Text = $"X{i-1}", FontWeight = FontWeight.Bold, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; variableBlocks.Add(block); Rectangles[1][i].Fill = Brushes.CadetBlue; Grid.SetRow(block, 1); Grid.SetColumn(block, i); Grid.Children.Add(block); } Variables = variableBlocks.ToArray(); var baseBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.RowDefinitions.Count - 1; i++) { var block = new TextBlock { Text = $"X{i-1}", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; baseBlocks.Add(block); Grid.SetRow(block, i); Grid.SetColumn(block, 0); Grid.Children.Add(block); } Bases = baseBlocks.ToArray(); var baseVarBlocks = new List <TextBlock>(); for (int i = 2; i < Grid.RowDefinitions.Count - 1; i++) { var block = new TextBlock { Text = $"0", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; baseVarBlocks.Add(block); Grid.SetRow(block, i); Grid.SetColumn(block, 1); Grid.Children.Add(block); } BaseVariables = baseVarBlocks.ToArray(); var varGrid = new List <List <TextBlock> >(); for (int i = 2; i < Grid.RowDefinitions.Count - 1; i++) { var varRow = new List <TextBlock>(); for (int j = 2; j < Grid.ColumnDefinitions.Count; j++) { var block = new TextBlock { Text = $"0", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; varRow.Add(block); Grid.SetRow(block, i); Grid.SetColumn(block, j); Grid.Children.Add(block); } varGrid.Add(varRow); } VariableGrid = varGrid.Select(r => r.ToArray()).ToArray(); var decisionVars = new List <TextBlock>(); for (int i = 2; i < Grid.ColumnDefinitions.Count; i++) { var block = new TextBlock { Text = $"0", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; decisionVars.Add(block); Grid.SetColumn(block, i); Grid.SetRow(block, Grid.RowDefinitions.Count - 1); Grid.Children.Add(block); } DecisionVariables = decisionVars.ToArray(); }