private Solution SolveTwoPhase() { Solution tmp_solution = new Solution() { Quality = Enums.SolutionQuality.Infeasible }; m_RevisedModel.PrintMatrix(); //1) Solve the matrix for phase I /* * Steps * 1. Modify the constraints so that the RHS of each constraint is nonnegative (This requires that each constraint with a negative RHS be multiplied by -1. Remember that if you multiply an inequality by any negative number, the direction of the inequality is reversed!). After modification, identify each constraint as a ≤, ≥ or = constraint. * 2. Convert each inequality constraint to standard form (If constraint i is a ≤ constraint, we add a slack variable si; and if constraint i is a ≥ constraint, we subtract an excess variable ei). * 3. Add an artificial variable ai to the constraints identified as ≥ or = constraints at the end of Step 1. Also add the sign restriction ai ≥ 0. * 4. In the phase I, ignore the original LP’s objective function, instead solve an LP whose objective function is minimizing w = ai (sum of all the artificial variables). The act of solving the Phase I LP will force the artificial variables to be zero. 5. Since each artificial variable will be in the starting basis, all artificial variables must be eliminated from row 0 before beginning the simplex. Now solve the transformed problem by the simplex. */ m_ColumnSelector = ColumnSelectorFactory.GetSelector(ObjectiveType.Minumum); tmp_solution = Solve(m_RevisedModel.PhaseNonBasisObjectiveMatrix, m_RevisedModel.PhaseBasisObjectiveMatrix, m_RevisedModel.BasisMatrix, m_RevisedModel.BasisInverseMatrix, m_RevisedModel.NonBasisMatrix, m_RevisedModel.BasisRightHandMatrix, m_RevisedModel.BasicVariables, m_RevisedModel.ObjectiveCost); //Solving the Phase I LP will result in one of the following three cases: //I.Case : If w = 0 //TODO test //tmp_solution.RightHandValues[tmp_solution.RightHandValues.GetLength(0) - 1, 0] = 0; if (tmp_solution.ResultValue + m_RevisedModel.ObjectiveCost == 0) { m_ColumnSelector = ColumnSelectorFactory.GetSelector(m_RevisedModel.GoalType); //transfer the phaseoneobjective function factors RevisedSimplexModel tmp_phaseModel = m_RevisedModel; tmp_phaseModel.TruncatePhaseResult(tmp_solution); //II.Case : If w = 0, and no artificial variables are in the optimal Phase I basis: // i.Drop all columns in the optimal Phase I tableau that correspond to the artificial variables.Drop Phase I row 0. // ii.Combine the original objective function with the constraints from the optimal Phase I tableau(Phase II LP).If original objective function coefficients of BVs are nonzero row operations are done. // iii.Solve Phase II LP using the simplex method.The optimal solution to the Phase II LP is the optimal solution to the original LP. //tmp_phaseModel.BasisObjectiveMatrix = new Matrix(1, tmp_solution.BasicVariables.Count); //tmp_phaseModel.BasisRightHandMatrix = new Matrix(tmp_solution.BasicVariables.Count,1); //for (int i = 0; i < tmp_solution.BasicVariables.Count; i++) //{ // tmp_phaseModel.BasisObjectiveMatrix[0, i] =tmp_phaseModel.ObjectiveFunction.Terms[tmp_solution.BasicVariables[i]].Factor; // tmp_phaseModel.BasisRightHandMatrix[i,0] = tmp_phaseModel.Subjects[i].RightHandValue; //} tmp_solution = Solve(tmp_phaseModel.BasisNonObjectiveMatrix, tmp_phaseModel.BasisObjectiveMatrix, tmp_phaseModel.BasisMatrix, tmp_phaseModel.BasisInverseMatrix, tmp_phaseModel.NonBasisMatrix, tmp_phaseModel.BasisRightHandMatrix, tmp_phaseModel.BasicVariables, tmp_phaseModel.ObjectiveCost); //tmp_solution = Solve(tmp_phaseModel.PhaseNonOneBasisObjectiveMatrix, tmp_phaseModel.BasisObjectiveMatrix, tmp_phaseModel.PhaseOneBasisMatrix, tmp_phaseModel.BasisMatrix, tmp_phaseModel.PhaseOneNonBasisMatrix, tmp_phaseModel.BasisRightHandMatrix, tmp_solution.BasicVariables, tmp_phaseModel.ObjectiveCost); System.Diagnostics.Debug.WriteLine("Solution " + tmp_solution.Quality.ToString()); //if ( ) //III.Case : If w = 0, and at least one artificial variable is in the optimal Phase I basis: // i.Drop all columns in the optimal Phase I tableau that correspond to the nonbasic artificial variables and any variable from the original problem that has a negative coefficient in row 0 of the optimal Phase I tableau. Drop Phase I row 0. // ii.Combine the original objective function with the constraints from the optimal Phase I tableau(Phase II LP).If original objective function coefficients of BVs are nonzero row operations are done. // iii.Solve Phase II LP using the simplex method.The optimal solution to the Phase II LP is the optimal solution to the original LP. //if ( ) } //II.Case : If w > 0 then the original LP has no feasible solution(stop here). else { tmp_solution.Quality = SolutionQuality.Infeasible; } //assign the actual value to the result terms return(tmp_solution); }
Solution ISolutionBuilder.getResult() { Solution tmp_solution = new Solution() { Quality = Enums.SolutionQuality.Infeasible }; if (m_RevisedModel.IsTwoPhase) { tmp_solution = SolveTwoPhase(); } else { m_ColumnSelector = ColumnSelectorFactory.GetSelector(m_RevisedModel.GoalType); tmp_solution = Solve(m_RevisedModel.BasisNonObjectiveMatrix, m_RevisedModel.BasisObjectiveMatrix, m_RevisedModel.BasisMatrix, m_RevisedModel.BasisMatrix.Invert(), m_RevisedModel.NonBasisMatrix, m_RevisedModel.BasisRightHandMatrix, m_RevisedModel.BasicVariables, m_RevisedModel.ObjectiveCost); } //for feaseble solution, all of rhs values must be positive or zero and Z must be zero after all iteration PrepareSolutionResult(m_RevisedModel.NonBasisMatrix, WorkingRightHandValues, m_RevisedModel.ObjectiveFunction.Terms, tmp_solution); return(tmp_solution); }