Esempio n. 1
0
        public static LPModel RunGomory(LPModelDto dto)
        {
            Func <LPModel, IEnumerable <Equation> > findEquationsWithFractionConstant = (lm) => lm.Constraints.Where(
                dictionaryRow => IsDecisionVariable(dictionaryRow.LeftSide.Single().Variable.Value, lm) &&
                !(dictionaryRow.RightSide.SingleOrDefault(term => term.Constant)?.SignedCoefficient.Integer ?? true)                  // if no contstant term can be found it is equivalent with the zero constant
                );
            LPModel lpModel;
            IEnumerable <Equation> equationsWithFractionConstant;

            //IList<Equation> gomoryConstraints = new List<Equation>();

            lpModel = dto.MapTo(new LPModel());
            lpModel.TwoPhaseSimplex();

            // constraints are in dictionary form here... we need those rows where the contstant is not an integer
            equationsWithFractionConstant = findEquationsWithFractionConstant(lpModel);

            #region Changing aim to minimize
            lpModel.ChangeOptimizationAimTo(OptimizationAim.Minimize);
            #endregion

            while (equationsWithFractionConstant.Any())
            {
                // its form like (dictionary row): <basis variable> = <constant> +/- <coefficient><non-basis variable> +/- ... +/- <coefficient><non-basis variable>
                var eqWithFracConst = equationsWithFractionConstant.First();

                var varForGomory = new Variable {
                    Name = lpModel.DecisionVariableName.ToString(), Index = lpModel.AllVariables.Max(var => var.Index) + 1
                };
                var gomoryConstraint = MakeGomoryConstraint(eqWithFracConst);
                gomoryConstraint.Add(gomoryConstraint.LeftSide.Copy().Multiply(-1));
                gomoryConstraint.LeftSide.Add(new Term {
                    SignedCoefficient = 1,
                    Variable          = varForGomory
                });
                gomoryConstraint.SideConnection = SideConnection.Equal;
                lpModel.Constraints.Add(gomoryConstraint);

                lpModel.AllVariables.Add(varForGomory);
                lpModel.InterpretationRanges.Add(varForGomory.GreaterOrEqualThanZeroRange());

                lpModel.DualSimplex();
                equationsWithFractionConstant = findEquationsWithFractionConstant(lpModel);

                /*lpModel = dto.MapTo(new LPModel());
                 * gomoryConstraints.ForAll(constraint =>
                 * {
                 * lpModel.Constraints.Add(constraint.Copy());
                 * var newVariablesFromGomoryConstraint = constraint.LeftSide.Select(term => term.Variable).Where(variable => !lpModel.AllVariables.Contains(variable.Value));
                 * newVariablesFromGomoryConstraint.ForAll(variable =>
                 * {
                 *     lpModel.AllVariables.Add(variable.Value);
                 *     lpModel.InterpretationRanges.Add(variable.Value.GreaterOrEqualThanZeroRange());
                 * });
                 * });*/
            }
            // only integers we are done...
            return(lpModel);
        }
        public IActionResult DualSimplex([FromBody] LPModelDto lpModelDto)
        {
            bool   wrongFormat = false;
            string message     = null;

            try
            {
                lpModelDto.Validate();
            }
            catch (ArgumentException e)
            {
                wrongFormat = true;
                message     = string.Format(Messages.WRONG_FORMAT_CHECK_ARG, e.ParamName);
            }

            if (wrongFormat)
            {
                return(BadRequest(new { success = false, message = message }));
            }

            var lpModel = lpModelDto.MapTo(new LPModel());

            try
            {
                lpModel.DualSimplex();
                var solution = lpModel.GetSolutionFromDictionary(lpModelDto.MapTo(new LPModel()).Objective.Function);
            }
            catch (SimplexAlgorithmExectionException e)
            {
                message = e.ExecutionError == SimplexAlgorithmExectionErrorType.NoSolution ?
                          Messages.SIMPLEX_RESULT_NO_SOLUTION :
                          Messages.SIMPLEX_RESULT_NO_LIMIT;
            }

            return(Json(new { success = true, message = message }));
        }
        public async Task <IActionResult> Solve([FromBody] LPModelDto lpModelDto, bool integerProgramming = false)
        {
            bool               wrongFormat = false;
            string             message     = null;
            SimplexSolutionDto solution    = null;
            LPModel            lpModel     = null;

            try
            {
                lpModelDto.Validate();
            }
            catch (ArgumentException e)
            {
                wrongFormat = true;
                message     = string.Format(Messages.WRONG_FORMAT_CHECK_ARG, e.ParamName);
            }

            if (wrongFormat)
            {
                return(BadRequest(new { success = false, message = message }));
            }

            if (integerProgramming)
            {
                try
                {
                    lpModel  = Gomory.RunGomory(lpModelDto);
                    solution = lpModel.GetSolutionFromDictionary(lpModelDto.MapTo(new LPModel()).Objective.Function);
                }
                catch (SimplexAlgorithmExectionException e)
                {
                    message = e.ExecutionError == SimplexAlgorithmExectionErrorType.NoSolution ?
                              Messages.SIMPLEX_INT_RESULT_NO_SOLUTION :
                              Messages.SIMPLEX_INT_RESULT_NO_LIMIT;
                }
            }
            else
            {
                lpModel = lpModelDto.MapTo(new LPModel());

                try
                {
                    lpModel.TwoPhaseSimplex();
                    solution = lpModel.GetSolutionFromDictionary(lpModelDto.MapTo(new LPModel()).Objective.Function);
                }
                catch (SimplexAlgorithmExectionException e)
                {
                    message = e.ExecutionError == SimplexAlgorithmExectionErrorType.NoSolution ?
                              Messages.SIMPLEX_RESULT_NO_SOLUTION :
                              Messages.SIMPLEX_RESULT_NO_LIMIT;
                }
                catch (Exception)
                {
                    message = Messages.GENERAL_ERROR;
                }
            }

            if (message == Messages.GENERAL_ERROR)
            {
                return(StatusCode(500, new { success = false, message = message }));
            }

            var lpTask = new LpTask
            {
                LPModelAsJson  = JsonConvert.SerializeObject(lpModelDto),
                SolutionAsJson = JsonConvert.SerializeObject(new LPTaskResultDto {
                    SolutionFound = solution != null, Message = message, Solution = solution
                }),
                SolvedAt           = DateTimeOffset.Now,
                IntegerProgramming = integerProgramming
            };

            await _lpTaskOperations.Add(lpTask);

            return(Json(new { success = true, taskId = lpTask.Id }));
        }