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 })); }