public IActionResult Solver() { //try { var model = new Model(); var x = new Variable("x"); var y = new Variable("y"); model.AddConstraint(10 * x + 20 * y >= 2); model.AddConstraint(40 * x + 60 * y >= 64); model.AddConstraint(50 * x + 20 * y >= 34); model.AddObjective(new Objective(0.6 * x + 0.8 * y)); var solver = new GLPKSolver(); solver.Solve(model); var solution = solver.Solve(model); return(Ok(solution.ObjectiveValues)); //} catch { // return BadRequest( "It was not possible to calculate the simplex" ); //} }
public IActionResult Solver([FromBody] GLPKInput input) { try { // Cria o modelo e adiciona as variaveis Dictionary <string, string> variableKeyName = new Dictionary <string, string>( ); var model = new Model( ); List <Variable> variables = new List <Variable>( ); foreach (var val in input.Variables) { var variable = new Variable(val, 0); variables.Add(variable); variableKeyName.Add(variable.Name, val); } // Adiciona as restrições ao problema Expression expression = Expression.EmptyExpression; foreach (var val in input.Restrictions) { for (int i = 0; i < val.Values.Count( ); i++) { expression = val.Values.ElementAt(i) * variables.ElementAt(i) + expression; } if (val.Operation == GLPKRestriction.Operator.GreaterOrEqual) { model.AddConstraint(expression >= val.Disponibility); } else { model.AddConstraint(expression <= val.Disponibility); } expression = Expression.EmptyExpression; } // Adiciona a função objetiva ao modelo expression = Expression.EmptyExpression; for (int i = 0; i < input.Objective.Values.Count( ); i++) { expression = input.Objective.Values.ElementAt(i) * variables.ElementAt(i) + expression; } if (input.Objective.Operation == GLPKObjective.Operator.Maximize) { model.AddObjective(new Objective(expression, "Z", OPTANO.Modeling.Optimization.Enums.ObjectiveSense.Maximize)); } else { model.AddObjective(new Objective(expression, "Z", OPTANO.Modeling.Optimization.Enums.ObjectiveSense.Minimize)); } // Resolve o modelo por meio do GLPK var solver = new GLPKSolver( ); solver.Solve(model); var solution = solver.Solve(model); // Renomeia as variaveis para as variaveis do problema recebido var variablesRenamed = new Dictionary <string, double>( ); foreach (var val in solution.VariableValues) { variablesRenamed.Add(variableKeyName[val.Key], val.Value); } var objectiveRenamed = new Dictionary <string, double>( ); foreach (var val in solution.ObjectiveValues) { objectiveRenamed.Add("Z", val.Value); } // Formata a resposta var resp = new GLPKOutput { Objectives = objectiveRenamed, Variables = variablesRenamed, Status = solution.Status }; // Retorna a resposta return(Ok(resp)); } catch { // Para qualquer erro na resolução return(BadRequest("It was not possible to calculate the simplex")); } }
static void Main(string[] args) { var config = new Configuration(); config.NameHandling = NameHandlingStyle.UniqueLongNames; config.ComputeRemovedVariables = true; using (var scope = new ModelScope(config)) { var model = new Model(); // days in crop planning var horizon = Enumerable.Range(1, 9).ToList(); // only 1 crop for demonstration purposes var crops = new List <string>(); crops.Add("Crop A"); crops.Add("Crop B"); // the assignment of a crop planted on a day in the horizon var CropAssignment = new VariableCollection <int, string>( model, horizon, crops, "CropAssignment", (d, c) => $"CropAssignment_{d}_{c}", (d, c) => 0, (d, c) => 1, (d, c) => VariableType.Binary ); foreach (var day in horizon) { // max 1 crop per day model.AddConstraint(Expression.Sum(crops.Select(crop => CropAssignment[day, crop])) <= 1); foreach (var crop in crops) { // let's say a crop grows for 2 days after the day it was planted var cropGrowing = horizon.Where(d => d > day && d <= day + 2); if (cropGrowing.Count() == 2) { // set otherDay to zero, if the crop is planted on day. foreach (var otherDay in cropGrowing) { model.AddConstraint(-CropAssignment[day, crop] + 1 >= Expression.Sum(crops.Select(c => CropAssignment[otherDay, c]))); } } else { // the crop can't finish before end of horizon var cropCantFinishGrowingConstraint = CropAssignment[day, crop] == 0; model.AddConstraint(cropCantFinishGrowingConstraint); } } } var total = Expression.Sum(horizon.SelectMany(day => crops.Select(crop => CropAssignment[day, crop]))); model.AddObjective(new Objective(total, "total", ObjectiveSense.Maximize)); using (var solver = new GLPKSolver()) { var solution = solver.Solve(model); // import values back into the model model.VariableCollections.ToList().ForEach(vc => vc.SetVariableValues(solution.VariableValues)); // print solution foreach (var day in horizon) { foreach (var crop in crops) { if (CropAssignment[day, crop].Value == 1) { Console.WriteLine($"Day {day} {crop} planted"); } } } } } }
GeoHydroSolutionOutput SolveTheModel(HydroSourceValues inputValues, HydroMixModelConfig config, SourceConfiguration sourceConfiguration) { var text = new StringBuilder( $"\n" + $" ===================================\n" + $"Result for target: '{inputValues.Target.Source.Name}' and configuration: '{config.ConfigAlias}' and source conf: '{sourceConfiguration.Alias}' :" + $"\n\n"); var optanoConfig = new Configuration(); optanoConfig.NameHandling = NameHandlingStyle.UniqueLongNames; optanoConfig.ComputeRemovedVariables = true; GeoHydroSolutionOutput geoHydroSolutionOutput; using (var scope = new ModelScope(optanoConfig)) { var problem = new HydroMixProblem(inputValues, config, inputValues.Target, sourceConfiguration); using (var solver = new GLPKSolver()) { // solve the model var solution = solver.Solve(problem.Model); // import the results back into the model foreach (var vc in problem.Model.VariableCollections) { vc.SetVariableValues(solution.VariableValues); } var TOLERANCE = 0.001; var sourcesContributions = problem.Sources.Select(s => (Source: s, Contribution: problem.SourceContribution[s].Value)).ToList(); var resultingMix = inputValues.MarkerInfos().Select(x => x.MarkerName).ToDictionary(x => x, x => 0.0); foreach (var source in sourcesContributions.Where(x => x.Contribution > 0.01).OrderByDescending(x => x.Contribution)) { var array = source.Source.Name.Take(25).ToArray(); var sourceContribution = problem.SourceUsed[source.Source].Value; var formattableString = $"Source({sourceContribution:F0}): {new string(array),25} | Contribution: {source.Contribution * 100:F1} "; text.AppendLine(formattableString); foreach (var markerVal in source.Source.MarkerValues) { resultingMix[markerVal.MarkerInfo.MarkerName] += markerVal.Value * markerVal.MarkerInfo.NormalizationCoefficient * source.Contribution; } } text.AppendLine(); var totalError = 0.0; var optimizedError = 0.0; foreach (var markerInfo in inputValues.MarkerInfos() //.Where(x => x.Weight > 0) ) { var epsilonMarkerErrorPos = problem.PositiveErrors[markerInfo].Value; var epsilonMarkerErrorNeg = problem.NegativeErrors[markerInfo].Value; totalError += Math.Abs(epsilonMarkerErrorNeg) + Math.Abs(epsilonMarkerErrorPos); if (markerInfo.Weight > 0) { optimizedError += Math.Abs(epsilonMarkerErrorNeg) + Math.Abs(epsilonMarkerErrorPos); } var originalTargetValue = inputValues.Target.Source[markerInfo].OriginalValue.Value; var computedValue = resultingMix[markerInfo.MarkerName] - (epsilonMarkerErrorPos * markerInfo.NormalizationCoefficient) + (epsilonMarkerErrorNeg * markerInfo.NormalizationCoefficient); string diffInfo = null; if (Math.Abs(computedValue - originalTargetValue) > TOLERANCE) { diffInfo = $"| diffComputed/Target: ({computedValue,6:F3}/{originalTargetValue,6:F3})"; } var realDiff = resultingMix[markerInfo.MarkerName] - originalTargetValue; var formattableString = $"Marker({markerInfo.Weight:F0}) {markerInfo.MarkerName,10} | targetVal: {originalTargetValue,6:F2} | diff: ({realDiff,6:F2}) | mixValue: {resultingMix[markerInfo.MarkerName],6:F2} {diffInfo}"; text.AppendLine(formattableString); } geoHydroSolutionOutput = new GeoHydroSolutionOutput() { TextOutput = text + $" ===================================\n" + '\n', ConfigALias = config.ConfigAlias, Target = inputValues.Target, SourcesConfigAlias = sourceConfiguration.Alias, UsedSources = sourcesContributions.Where(x => x.Contribution > 0.01).OrderByDescending(x => x.Contribution), NormalizedError = totalError, ResultingMix = resultingMix, OptimalizedError = optimizedError }; } } return(geoHydroSolutionOutput); }