コード例 #1
0
        /// <summary>
        /// Gets variable, which indicates creative row
        /// </summary>
        public string GetCreativeVariable(SimplexTable table, ProblemForGomory problem)
        {
            var maxVariables = new List<string>();
            var maxFractionalPart = new Fraction();
            foreach (var basisVariable in table.GetBasis())
            {
                if (!problem.WholeConstraints.Contains(basisVariable.Key))
                    continue;
                var fractionalPart = GetFractionalPart(basisVariable.Value);
                if (fractionalPart > maxFractionalPart)
                {
                    maxVariables.Clear();
                    maxFractionalPart = fractionalPart;
                }
                if (fractionalPart == maxFractionalPart)
                    maxVariables.Add(basisVariable.Key);
            }
            if (maxVariables.Count == 1) return maxVariables[0];

            maxFractionalPart = new Fraction();
            var maxVariable = string.Empty;
            foreach (var variable in maxVariables)
            {
                var sumOfFractionalParts = new Fraction();
                foreach (var rowVariable in table.GetRow(variable).Key)
                    sumOfFractionalParts += GetFractionalPart(rowVariable);
                var ratio = sumOfFractionalParts != 0
                                ? GetFractionalPart(table.GetRow(variable).Value) / sumOfFractionalParts
                                : new Fraction();
                if (ratio <= maxFractionalPart) continue;
                maxFractionalPart = ratio;
                maxVariable = variable;
            }
            return maxVariable;
        }
コード例 #2
0
        /// <summary>
        /// Makes cutoff
        /// </summary>
        public new KeyValuePair<Fraction[], Fraction> MakeCutoff(SimplexTable table,
            string creativeVar, ProblemForGomory problem)
        {
            var j = 0;
            var creativeRow = table.GetRow(creativeVar);
            var row = new Fraction[creativeRow.Key.Length + 1];

            foreach (var variable in table.Variables)
                row[j++] = GetCoefficientForCutoff(variable, table, creativeVar, problem.WholeConstraints) * -1;

            row[j] = new Fraction(1, 1);

            return new KeyValuePair<Fraction[], Fraction>(row, GetFractionalPart(creativeRow.Value) * -1);
        }
コード例 #3
0
 /// <summary>
 /// Returs true if result is whole
 /// </summary>
 protected bool IsWhole(LppResult result, ProblemForGomory problem)
 {
     foreach (var variable in result.Coordinates)
         if (variable.Value.Denominator != 1 && problem.WholeConstraints.Contains(variable.Key))
             return false;
     return true;
 }
コード例 #4
0
 /// <summary>
 /// Returns true if problem have varables, which isn't whole
 /// </summary>
 protected bool HaveNotWholeVariable(ProblemForGomory problem)
 {
     foreach (var variable in problem.TargetFunction.Arguments)
         if (!problem.WholeConstraints.Contains(variable))
             return true;
     return false;
 }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Solving by Gompry's first method
        /// </summary>
        public LppResult Solve(ProblemForGomory problem)
        {
            if (!IsSuitable(problem))
                throw new FormatException("Problem isn't suitable for Gomory's first method");

            SimplexTable table;
            LppForSimplexMethod normalizedForSimplex;

            var result = SolveInitialWeekenedProblem(problem, out normalizedForSimplex, out table);

            while (!IsEnd(result, problem))
            {
                var creativeVar = GetCreativeVariable(table, problem);

                var basisVar = GetFreeBasisVariableLabel(table);
                var cutoff = MakeCutoff(table, creativeVar, problem);

                table = AddCutoff(table, basisVar, cutoff);

                result = SolveWeekenedProblemWithCutoff(problem, table, out table);
            }

            return GetInitialProblemResult(table, normalizedForSimplex);
        }
コード例 #7
0
        /// <summary>
        /// Makes cutoff
        /// </summary>
        public KeyValuePair<Fraction[], Fraction> MakeCutoff(SimplexTable table,
            string creativeVar, ProblemForGomory problem)
        {
            var j = 0;
            var creativeRow = table.GetRow(creativeVar);
            var row = new Fraction[creativeRow.Key.Length + 1];

            foreach (var coefficient in creativeRow.Key)
                row[j++] = GetFractionalPart(coefficient) * -1;

            row[j] = new Fraction(1, 1);

            return new KeyValuePair<Fraction[], Fraction>(row, GetFractionalPart(creativeRow.Value) * -1);
        }
コード例 #8
0
 /// <summary>
 /// Returns true if weakened problem is normalized
 /// </summary>
 public bool IsWeakenedProblemNormalized(ProblemForGomory problem)
 {
     return _simplex.IsNormalized(problem);
 }
コード例 #9
0
 /// <summary>
 /// Indicates is problem suitable for solving by Gomory method
 /// </summary>
 public bool IsSuitable(ProblemForGomory problem)
 {
     return !HaveNotWholeCoefficient(problem.GetAllConstraints()) && !HaveNotWholeVariable(problem);
 }
コード例 #10
0
 /// <summary>
 /// Returns true if result of weakened problem solving is result of initial problem solving
 /// </summary>
 public bool IsEnd(LppResult result, ProblemForGomory problem)
 {
     return result.Value == null || IsWhole(result, problem);
 }
コード例 #11
0
        private UiDescription InputProblemAnalyzingStep(UiDescription userData)
        {
            if (!_gomoryFirst.IsSuitable((DiscreteProgrammingProblem)userData["DPP"].Value))
                return IsNotSuitableMessagingStep(userData);

            InitialProblem = new ProblemForGomory((DiscreteProgrammingProblem)userData["DPP"].Value);

            return AfterInitActionChoosingStep();
        }