/// <summary>
 /// Returns true if all constraints in constraint system are equal
 /// </summary>
 public bool AreAllConstraintsEqual(LppForSimplexMethod problem)
 {
     foreach (var constraint in problem.ConstraintSystem)
         if (constraint.Sign != "=")
             return false;
     return true;
 }
 /// <summary>
 /// Returns true if problem can be solved by simplex-method
 /// </summary>
 public new bool IsNormalized(LppForSimplexMethod problem)
 {
     return IsTargetFunctionMinimized(problem)
         && AreAllConstraintsEqual(problem)
         && DoAllConstraintsHaveBasisVariable(problem)
         && DoAllVariablesHaveZeroConstraint(problem);
 }
        /// <summary>
        /// Variant of 4th step of normalizing(should be used if constraint system has more than(>=) and equal(=) constraints, 
        /// except less than constraints, which were changed on previous step)
        /// </summary>
        /// <param name="problem">Initial problem</param>
        /// <returns>Changed problem(new object)</returns>
        public LppForSimplexMethod ChangeBothTypesOfConstraints(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            //1.
            var maxIndex = EqualConstraintWithBiggestFreeCoefficient(problemCopy);
            //2.
            for (var i = 0; i < problemCopy.ConstraintCount; i++)
            {
                var currConstraint = problemCopy.GetConstraint(i);
                if (problemCopy.LessThanConstraintsIndexes.Contains(i) || currConstraint.Sign != ">=")
                    continue;

                var constraintWithMaxCoef = problemCopy.GetConstraint(maxIndex);

                while (currConstraint.RightSide >= constraintWithMaxCoef.RightSide)
                    currConstraint.Divide(2);

                currConstraint.Multiply(-1);
                problemCopy.AddAdditionalVariable(i);

                currConstraint.Add(constraintWithMaxCoef);
            }
            //3.
            for (var i = 0; i < problemCopy.ConstraintCount; i++)
                if (problemCopy.GetBasisVariableLabel(i) == null)
                    problemCopy.AddArtificialVariable(i);

            return problemCopy;
        }
        /// <summary>
        /// Gets result of solving
        /// </summary>
        public new LppResult GetResult(SimplexTable table, LppForSimplexMethod problem)
        {
            if (!HaveNegativeFreeCoefficients(table))
                return GetInitialProblemResult(table, problem);

            return HaveNegativeRowsWithoutNegativeElements(table) ? new LppResult(null, null) : null;
        }
        private Dictionary<int, MaxCoefficient> _targetFunctionCoefficients; //Dictionary<variableId, coefficient>

        #endregion Fields

        #region Constructors

        //======================================================================================
        /// <summary>
        /// Represents symplex-table
        /// </summary>
        public SimplexTable(LppForSimplexMethod problem)
        {
            SetVariables(problem);
            SetBasis(problem);
            SetCoeffientsMatrix(problem);
            SetTargetFunctionCoefficints(problem);
        }
 /// <summary>
 /// Returns true if all free coefficients are more than or equal zero
 /// </summary>
 public bool AreFreeCoefficientsNonNegative(LppForSimplexMethod problem)
 {
     foreach (var constraint in problem.ConstraintSystem)
         if (constraint.RightSide < 0)
             return false;
     return true;
 }
        /// <summary>
        /// 2nd step of normalizing
        /// </summary>
        /// <param name="problem">Initial problem</param>
        /// <returns>Changed problem(new object)</returns>
        public LppForSimplexMethod ConstraintsToLessThanForm(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            foreach (var lim in problemCopy.ConstraintSystem)
                if (lim.Sign == ">=")
                    lim.Multiply(-1);

            return problemCopy;
        }
        public new LppForSimplexMethod Normalize(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            problemCopy = TargetToMinimize(problemCopy);
            problemCopy = ConstraintsToLessThanForm(problemCopy);
            problemCopy = ChangeLessThanConstraints(problemCopy);
            problemCopy = ChangeEqualConstraints(problemCopy);
            problemCopy = ReplaceVariablesWithoutZeroConstraints(problemCopy);

            return problemCopy;
        }
 /// <summary>
 /// Represents linear programming problem for symplex-method
 /// </summary>
 /// <param name="problem">Initial problem</param>
 public LppForSimplexMethod(LppForSimplexMethod problem)
     : base(problem.TargetFunction, problem.ConstraintSystem, problem.ZeroConstraints)
 {
     InitializeComponents();
     InitialProblem = new LinearProgrammingProblem(problem.InitialProblem);
     VariablesWithMaxCoefficient.AddRange(problem.VariablesWithMaxCoefficient);
     LessThanConstraintsIndexes.AddRange(problem.LessThanConstraintsIndexes);
     foreach (var replacement in problem.Replacements)
         Replacements.Add(replacement.Key,
                          new KeyValuePair<string, string>(replacement.Value.Key, replacement.Value.Value));
     IsTargetWasChanged = problem.IsTargetWasChanged;
 }
        /// <summary>
        /// Solving by simplex-method
        /// </summary>
        public new LppResult Solve(LppForSimplexMethod problem)
        {
            if (!IsNormalized(problem))
                throw new FormatException("Problem must be normalized");

            var table = MakeFirstSimplexTable(problem);

            while (!IsEnd(table))
            {
                table = CalculateRatings(table);

                var solvingElement = GetSolvingElement(table);

                table = ChangeBasis(table, solvingElement);
            }

            return GetResult(table, problem);
        }
        /// <summary>
        /// Returns index of constraint with biggest free coefficient
        /// </summary>
        private int EqualConstraintWithBiggestFreeCoefficient(LppForSimplexMethod problem)
        {
            var maxIndex = -1;
            for (var i = 0; i < problem.ConstraintCount; i++)
            {
                var currConstraint = problem.GetConstraint(i);

                if (currConstraint.Sign != "=" || problem.LessThanConstraintsIndexes.Contains(i)) continue;

                if (maxIndex == -1)
                {
                    maxIndex = i;
                    continue;
                }

                if (currConstraint.RightSide > problem.GetConstraint(maxIndex).RightSide)
                    maxIndex = i;
            }
            return maxIndex;
        }
        /// <summary>
        /// 1st step of normalizing
        /// </summary>
        /// <param name="problem">Initial problem</param>
        /// <returns>Changed problem(new object)</returns>
        public LppForSimplexMethod TargetToMinimize(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            if (problemCopy.TargetFunction.Target != "min")
            {
                problemCopy.TargetFunction.ChangeTarget();
                problemCopy.IsTargetWasChanged = true;
            }

            return problemCopy;
        }
 /// <summary>
 /// Returns true if constraint system contains constraints with such sign
 /// </summary>
 private bool ContainsSuchConstraints(LppForSimplexMethod problem, string sign)
 {
     for (var i = 0; i < problem.ConstraintCount; i++)
     {
         if (problem.LessThanConstraintsIndexes.Contains(i)) continue;
         if (problem.GetConstraint(i).Sign == sign)
             return true;
     }
     return false;
 }
 /// <summary>
 /// Returns true if problem have more than zero constraint
 /// </summary>
 public bool DoProblemHaveMoreThanZeroConstraint(LppForSimplexMethod problem)
 {
     foreach (var constraint in problem.ConstraintSystem)
         if (constraint.Sign == ">=" && constraint.RightSide == 0)
             return true;
     return false;
 }
        /// <summary>
        /// 5th step of normalizing
        /// </summary>
        /// <param name="problem">Initial problem</param>
        /// <returns>Changed problem(new object)</returns>
        public LppForSimplexMethod ReplaceVariablesWithoutZeroConstraints(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            var needReplacement = new List<string>();
            foreach (var tFuncArgument in problemCopy.TargetFunction.Arguments)
            {
                var containedZeroConstraint = false;
                foreach (var zeroConstraint in problemCopy.ZeroConstraints)
                    if (zeroConstraint.LeftSide.ElementAt(0).Label == tFuncArgument)
                    {
                        containedZeroConstraint = true;
                        break;
                    }
                if (!containedZeroConstraint)
                    needReplacement.Add(tFuncArgument);
            }

            foreach (var label in needReplacement)
                problemCopy.AddVariableReplacement(label, label + "'", label + "''");

            return problemCopy;
        }
 /// <summary>
 /// Makes first simplex table(without ratings)
 /// </summary>
 public SimplexTable MakeFirstSimplexTable(LppForSimplexMethod problem)
 {
     return new SimplexTable(problem);
 }
 /// <summary>
 /// Gets initial problem result
 /// </summary>
 public LppResult GetInitialProblemResult(SimplexTable lastTable, LppForSimplexMethod normalizedForSimplexProblem)
 {
     return _simplex.GetInitialProblemResult(lastTable, normalizedForSimplexProblem);
 }
 /// <summary>
 /// Represents linear programming problem for symplex-method
 /// </summary>
 /// <param name="problem">Initial problem</param>
 public ProblemForGomory(LppForSimplexMethod problem)
     : base(problem)
 {
     InitializeComponents();
 }
 /// <summary>
 /// Returns true if all variables have constraint 'more than zero'
 /// </summary>
 public bool DoAllVariablesHaveZeroConstraint(LppForSimplexMethod problem)
 {
     var zeroConstraintedVariables = new List<string>();
     foreach (var zeroConstraint in problem.ZeroConstraints)
         zeroConstraintedVariables.Add(zeroConstraint.LeftSide.ElementAt(0).Label);
     foreach (var argument in problem.TargetFunctionArguments)
         if (!zeroConstraintedVariables.Contains(argument))
             return false;
     return true;
 }
        /// <summary>
        /// Gets result of solving
        /// </summary>
        public LppResult GetResult(SimplexTable table, LppForSimplexMethod problem)
        {
            if (!HavePositiveRatings(table))
                return GetInitialProblemResult(table, problem);

            return HavePositiveCellsWithoutPositiveElements(table) ? new LppResult(null, null) : null;
        }
 /// <summary>
 /// Gets acceptable solution of normalixed problem
 /// </summary>
 public LppResult GetNormalizedProblemResult(SimplexTable table, LppForSimplexMethod problem)
 {
     return problem.GetNormalizedProblemResult(table);
 }
 /// <summary>
 /// Gets acceptable solution of initial problem
 /// </summary>
 public LppResult GetInitialProblemResult(SimplexTable table, LppForSimplexMethod problem)
 {
     return problem.GetInitialProblemResult(table);
 }
        /// <summary>
        /// Solves weakened problem(without whole constraints) by simplex-method
        /// </summary>
        /// <param name="problem">Initial problem</param>
        /// <param name="normalizedProblem"></param>
        /// <param name="lastSimplexTable">Last simplex-table(optimal plan)</param>
        /// <returns></returns>
        public LppResult SolveInitialWeekenedProblem(ProblemForGomory problem,
            out LppForSimplexMethod normalizedProblem, out SimplexTable lastSimplexTable)
        {
            normalizedProblem = _simplex.Normalize(problem);
            lastSimplexTable = _simplex.MakeFirstSimplexTable(normalizedProblem);
            lastSimplexTable = _simplex.Solve(lastSimplexTable);

            return _simplex.GetNormalizedProblemResult(lastSimplexTable, normalizedProblem);
        }
        /// <summary>
        /// 2nd step of normalizing(can be after or befor changing of more than zero constraints)
        /// </summary>
        /// <param name="problem">Initial problem</param>
        /// <returns>Changed problem(new object)</returns>
        public LppForSimplexMethod MakeFreeCoefficientsNonNegative(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            foreach (var constraint in problemCopy.ConstraintSystem)
                if (constraint.RightSide < 0)
                    constraint.Multiply(-1);

            return problemCopy;
        }
 /// <summary>
 /// Solves weakened problem(without whole constraints) by dual simplex-method
 /// </summary>
 public LppResult SolveWeekenedProblemWithCutoff(LppForSimplexMethod problem, SimplexTable firstTable, out SimplexTable lastTable)
 {
     lastTable = _dualSimplex.Solve(firstTable);
     return _dualSimplex.GetNormalizedProblemResult(lastTable, problem);
 }
        /// <summary>
        /// Nomalizing for simplex-method
        /// </summary>
        public LppForSimplexMethod Normalize(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            problemCopy = TargetToMinimize(problemCopy);
            problemCopy = MakeFreeCoefficientsNonNegative(problemCopy);
            problemCopy = ChangeMoreThanZeroConstraints(problemCopy);
            problemCopy = ChangeLessThanConstraints(problemCopy);
            problemCopy = ChangeMoreThanAndEqualConstraints(problemCopy);
            problemCopy = ReplaceVariablesWithoutZeroConstraints(problemCopy);

            return problemCopy;
        }
        private UiDescription SolveOrNormalizeChoiceStep(UiDescription userData)
        {
            CurrentProblem = new LppForSimplexMethod(((LinearProgrammingProblem)userData["LPP"].Value));

            //CurrentProblem = _simplex.Normalize(CurrentProblem);
            //CurrentSimplexTable = _simplex.MakeFirstSimplexTable(CurrentProblem);
            //CurrentSimplexTable = _simplex.Solve(CurrentSimplexTable);
            //return NormalizedProblemResultEnteringStep(userData);

            var nextStep = SolveOrNormalizing();
            SetNextStep(nextStep == SolveLabel ? (Step)MakeFirstSimplexTableStep : NormalizeActionChoiceStep);
            return new UiDescription
                       {
                           {"LppView", "LPP", "", CurrentProblem, false, false},
                           {"Label", "lab", null, "Виберіть наступний крок:", false, false},
                           {"StepsContainer", "NextSteps", SolveOrNormalizeVariants, new StepVariants(new[] {nextStep}), true, true}
                       };
        }
 /// <summary>
 /// Returns true if problem have less than constraints
 /// </summary>
 public bool DoProblemHaveLessThanConstraint(LppForSimplexMethod problem)
 {
     foreach (var constraint in problem.ConstraintSystem)
         if (constraint.Sign == "<=")
             return true;
     return false;
 }
 /// <summary>
 /// Represents linear programming problem for symplex-method
 /// </summary>
 /// <param name="problem">Initial problem</param>
 /// <param name="wholeConstraints"> </param>
 public ProblemForGomory(LppForSimplexMethod problem, IEnumerable<string> wholeConstraints)
     : base(problem)
 {
     InitializeComponents();
     WholeConstraints.AddRange(wholeConstraints);
 }
 /// <summary>
 /// Returns true if target in problem's target function is min
 /// </summary>
 public bool IsTargetFunctionMinimized(LppForSimplexMethod problem)
 {
     return problem.TargetFunction.Target == "min";
 }