/// <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>
        /// 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>
 /// 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>
        /// Variant of 4th step of normalizing(should be used if constraint system has only more than 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 ChangeMoreThanConstraints(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);
            //1.
            for (var i = 0; i < problemCopy.ConstraintCount; i++)
                if (!problemCopy.LessThanConstraintsIndexes.Contains(i))
                    problemCopy.AddAdditionalVariable(i);
            //2.
            var maxIndex = EqualConstraintWithBiggestFreeCoefficient(problemCopy);
            //3.
            for (var i = 0; i < problemCopy.ConstraintCount; i++)
            {
                if (problemCopy.LessThanConstraintsIndexes.Contains(i) || i == maxIndex) continue;

                var first = problemCopy.GetConstraint(maxIndex);
                var second = problemCopy.GetConstraint(i);
                second.Multiply(-1);
                second.Add(first);
            }
            //4.
            if (problemCopy.GetBasisVariableLabel(maxIndex) == null)
                problemCopy.AddArtificialVariable(maxIndex);

            return problemCopy;
        }
        /// <summary>
        /// 3rd step of normalizing
        /// </summary>
        /// <param name="problem">Initial problem</param>
        /// <returns>Changed problem(new object)</returns>
        public LppForSimplexMethod ChangeLessThanConstraints(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            for (var i = 0; i < problemCopy.ConstraintCount; i++)
                if (problemCopy.GetConstraint(i).Sign == "<=")
                {
                    problemCopy.AddAdditionalVariable(i);
                    problemCopy.LessThanConstraintsIndexes.Add(i);
                }

            return problemCopy;
        }
        /// <summary>
        /// Variant of 4th step of normalizing(should be used if constraint system has only 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 ChangeEqualConstraints(LppForSimplexMethod problem)
        {
            var problemCopy = new LppForSimplexMethod(problem);

            for (var i = 0; i < problemCopy.ConstraintCount; i++)
                if (problemCopy.GetConstraint(i).Sign == "=" && problemCopy.GetBasisVariableLabel(i) == null)
                    problemCopy.AddArtificialVariable(i);

            return problemCopy;
        }
        private void SetCoeffientsMatrix(LppForSimplexMethod problem)
        {
            _rows = new Dictionary<int, Fraction[]>();
            _freeCoefficients = new Dictionary<int, Fraction>();

            for (var rowIndex = 0; rowIndex < problem.ConstraintCount; rowIndex++)
            {
                var limitation = problem.GetConstraint(rowIndex);
                var row = CreateRow(_allVariables.Count);
                foreach (var var in limitation.LeftSide)
                {
                    var cellIndex = IndexOf(var.Label);
                    row[cellIndex] = new Fraction(var.Coefficient);
                }
                _rows.Add(rowIndex, row);
                _freeCoefficients.Add(rowIndex, limitation.RightSide);
            }
        }