コード例 #1
0
        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" );
            //}
        }
コード例 #2
0
        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"));
            }
        }
コード例 #3
0
        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");
                            }
                        }
                    }
                }
            }
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: videokojot/GeoHydroSources
        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);
        }