/// <summary>
        /// Represents linear programming problem(1. target function, 2. constraint system, 3. zero constraints)
        /// </summary>
        /// <param name="targetFunction"></param>
        /// <param name="constraints">Constraint system with zero constraints</param>
        /// <exception cref="FormatException"></exception>
        /// <exception cref="NullReferenceException"></exception>
        public LinearProgrammingProblem(TargetFunction targetFunction, ICollection<Constraint> constraints)
        {
            if (!IsLinearFormula(targetFunction.Formula))
                throw new FormatException("Target function must be linear");

            TargetFunction = new TargetFunction(targetFunction);
            SetConstraintSystem(constraints);
            CompleteTargetFunction();
        }
 /// <summary>
 /// Represents linear programming problem(1. target function, 2. constraint system, 3. zero constraints)
 /// </summary>
 /// <param name="targetFunction"></param>
 /// <param name="constraints">Constraint system without zero constraints</param>
 /// <param name="zeroConstraints">Zero constraints</param>
 /// <exception cref="FormatException"></exception>
 /// <exception cref="NullReferenceException"></exception>
 public LinearProgrammingProblem(TargetFunction targetFunction, IEnumerable<Constraint> constraints,
     IEnumerable<Constraint> zeroConstraints)
     : this(targetFunction, CombineConstraints(constraints, zeroConstraints))
 {
 }
        /// <summary>
        /// Parses target function
        /// </summary>
        /// <param name="problemDescription">LPP or just target function description</param>
        public static TargetFunction ParseTargetFunction(IList<string> problemDescription)
        {
            var flag = false;
            var formula = new List<Variable>();
            var target = string.Empty;
            var mLabels = new List<string>();
            for (var i = 0; i < problemDescription.Count; i++)
            {
                if (problemDescription[i].Replace(" ", "") == "->")
                {
                    target = problemDescription[i + 1].Replace(" ", "");
                    break;
                }

                if (flag)
                {
                    if (problemDescription[i].Contains("M"))
                    {
                        mLabels.Add(problemDescription[i].Substring(problemDescription[i].IndexOf("M", StringComparison.Ordinal) + 1));
                        continue;
                    }
                    try
                    {
                        formula.Add(CreateVariable(problemDescription[i]));
                    }
                    catch (FormatException)
                    {
                        return null;
                    }
                }

                if (problemDescription[i].Replace(" ", "") == "f(x)=")
                    flag = true;
            }
            var tf = new TargetFunction(formula, target);
            foreach (var label in mLabels)
                tf.AddVariableWithMaxCoefficient(label);
            return tf;
        }
 /// <summary>
 /// Compares two target functions
 /// </summary>
 public static bool IsTargetFunctionsEquals(TargetFunction first, TargetFunction second)
 {
     if (first.Target != second.Target || first.Arguments.Count != second.Arguments.Count)
         return false;
     foreach (var varF in first.Formula)
     {
         var flag = false;
         foreach (var varS in second.Formula)
         {
             if (varF.Label != varS.Label) continue;
             if (varF.Coefficient != varS.Coefficient || varF.Power != varS.Power)
                 return false;
             flag = true;
             break;
         }
         if (flag == false)
             return false;
     }
     return true;
 }
 /// <summary>
 /// Represents copy of target function
 /// </summary>
 /// <exception cref="NullReferenceException"></exception>
 /// <exception cref="FormatException"></exception>
 public TargetFunction(TargetFunction targetFunction)
     : this(targetFunction._formula, targetFunction.Target)
 {
     _variablesWithMaxCoefficient = new List<string>(targetFunction._variablesWithMaxCoefficient);
 }
 /// <summary>
 /// Represents discrete programming problem description 
 /// (1. target function, 2. constraint system, 3. zero constraints, 4. whole constraint)
 /// </summary>
 /// <param name="targetFunction">Target function</param>
 /// <param name="constraints">Constraint system without zero constraints</param>
 /// <param name="zeroConstraints">Zero constraints</param>
 /// <param name="wholeConstraints">Variables with whole constraint</param>
 public DiscreteProgrammingProblem(TargetFunction targetFunction, IEnumerable<Constraint> constraints,
     IEnumerable<Constraint> zeroConstraints, IEnumerable<string> wholeConstraints)
     : base(targetFunction, constraints, zeroConstraints)
 {
     WholeConstraints = new List<string>(wholeConstraints);
 }
 /// <summary>
 /// Represents discrete programming problem description 
 /// (1. target function, 2. constraint system, 3. zero constraints, 4. whole constraint)
 /// </summary>
 /// <param name="targetFunction">Target function</param>
 /// <param name="constraintSystem">Constraint system with zero constraints</param>
 /// <param name="wholeConstraints">Variables with whole constraint</param>
 public DiscreteProgrammingProblem(TargetFunction targetFunction, ICollection<Constraint> constraintSystem,
     IEnumerable<string> wholeConstraints)
     : base(targetFunction, constraintSystem)
 {
     WholeConstraints = new List<string>(wholeConstraints);
 }