Esempio n. 1
0
        async Task SendUsingNewModel(IPipe<ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            IPipe<ConnectionContext> connectionPipe = Pipe.ExecuteAsync<ConnectionContext>(async connectionContext =>
            {
                IModel model = await connectionContext.CreateModel().ConfigureAwait(false);

                EventHandler<ShutdownEventArgs> modelShutdown = null;
                modelShutdown = (obj, reason) =>
                {
                    model.ModelShutdown -= modelShutdown;

                    Interlocked.CompareExchange(ref _scope, null, scope);

                    scope.Close();
                };

                model.ModelShutdown += modelShutdown;

                var modelContext = new RabbitMqModelContext(connectionContext, model, connectionContext.CancellationToken);

                scope.Connected(modelContext);

                try
                {
                    using (SharedModelContext context = await scope.Attach(cancellationToken).ConfigureAwait(false))
                    {
                        await modelPipe.Send(context).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    if (_log.IsDebugEnabled)
                        _log.Debug("The existing model usage threw an exception", ex);

                    Interlocked.CompareExchange(ref _scope, null, scope);

                    scope.Close();

                    throw;
                }
            });

            try
            {
                await _connectionCache.Send(connectionPipe, new CancellationToken()).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                    _log.Debug("The connection threw an exception", exception);

                Interlocked.CompareExchange(ref _scope, null, scope);

                throw;
            }
        }
Esempio n. 2
0
        async Task SendUsingNewModel(IPipe<ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            IPipe<ConnectionContext> connectionPipe = Pipe.ExecuteAsync<ConnectionContext>(async connectionContext =>
            {
                try
                {
                    if (_log.IsDebugEnabled)
                        _log.DebugFormat("Creating model: {0}", connectionContext.HostSettings.ToDebugString());

                    var model = await connectionContext.CreateModel().ConfigureAwait(false);

                    EventHandler<ShutdownEventArgs> modelShutdown = null;
                    modelShutdown = (obj, reason) =>
                    {
                        model.ModelShutdown -= modelShutdown;

                        Interlocked.CompareExchange(ref _scope, null, scope);

                        scope.Shutdown(reason.ReplyText);
                    };

                    model.ModelShutdown += modelShutdown;

                    var modelContext = new RabbitMqModelContext(connectionContext, model, _cacheTaskScope, _modelSettings);

                    scope.Created(modelContext);
                }
                catch (Exception ex)
                {
                    Interlocked.CompareExchange(ref _scope, null, scope);

                    scope.CreateFaulted(ex);

                    throw;
                }

                await SendUsingExistingModel(modelPipe, scope, cancellationToken).ConfigureAwait(false);
            });

            try
            {
                await _connectionCache.Send(connectionPipe, _cacheTaskScope.StoppedToken).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                    _log.Debug("The connection threw an exception", exception);

                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.CreateFaulted(exception);

                throw;
            }
        }
Esempio n. 3
0
        public Task Send(IPipe<ModelContext> connectionPipe, CancellationToken cancellationToken)
        {
            ModelScope newScope = null;
            ModelScope existingScope;

            lock (_scopeLock)
            {
                existingScope = _scope;
                if (existingScope == null)
                {
                    newScope = new ModelScope(_cacheTaskScope);
                    _scope = newScope;
                }
            }
            if (existingScope != null)
                return SendUsingExistingModel(connectionPipe, existingScope, cancellationToken);

            return SendUsingNewModel(connectionPipe, newScope, cancellationToken);
        }
Esempio n. 4
0
        public EczaneNobetSonucModel Solve(EczaneNobetTekGrupDataModel data)
        {
            var config = new Configuration
            {
                NameHandling            = NameHandlingStyle.UniqueLongNames,
                ComputeRemovedVariables = true
            };

            using (var scope = new ModelScope(config))
            {
                var model = Model(data);
                // Get a solver instance, change your solver
                var solver = new CplexSolver();

                try
                {
                    // solve the model
                    var solution = solver.Solve(model);
                    //var cplexConfiguration = solver.Configuration;

                    var modelStatus    = solution.ModelStatus;
                    var solutionStatus = solution.Status;
                    var modelName      = solution.ModelName;
                    var bestBound      = solution.BestBound;

                    //var confilicts = new ConflictingSet();
                    //confilicts = solution.ConflictingSet;
                    //ConstraintsUB = new IEnumerable<Constraint>();
                    //ConstraintsUB = confilicts.ConstraintsUB;

                    if (modelStatus != ModelStatus.Feasible)
                    {
                        throw new Exception("Uygun çözüm bulunamadı!");
                    }
                    else
                    {
                        // import the results back into the model
                        model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));
                        var objective = solution.ObjectiveValues.Single();
                        var sure      = solution.OverallWallTime;

                        Results = new EczaneNobetSonucModel
                        {
                            CozumSuresi    = sure,
                            ObjectiveValue = objective.Value,
                            ResultModel    = new List <EczaneNobetCozum>()
                        };

                        foreach (var r in data.EczaneNobetTarihAralik.Where(s => _x[s].Value == 1))
                        {
                            Results.ResultModel.Add(new EczaneNobetCozum()
                            {
                                TakvimId          = r.TakvimId,
                                EczaneNobetGrupId = r.EczaneNobetGrupId,
                                NobetGorevTipId   = r.NobetGorevTipId
                            });
                        }
                    }
                }
                catch (Exception ex)
                {
                    var mesaj = ex.Message;
                    Results = _eczaneNobetTekGrupAltOptimization.Solve(data);
                }
            }

            return(Results);
        }
Esempio n. 5
0
        async Task SendUsingExistingModel(IPipe<ModelContext> modelPipe, ModelScope existingScope, CancellationToken cancellationToken)
        {
            try
            {
                using (SharedModelContext context = await existingScope.Attach(cancellationToken).ConfigureAwait(false))
                {
                    await modelPipe.Send(context).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                if (_log.IsDebugEnabled)
                    _log.Debug("The existing model usage threw an exception", ex);

                Interlocked.CompareExchange(ref _scope, null, existingScope);

                existingScope.Close();

                throw;
            }
        }
Esempio n. 6
0
        /// <summary>
        /// The main method
        /// </summary>
        /// <param name="args">
        /// no arguments required
        /// </param>
        static void Main(string[] args)
        {
            // create example elements
            IElement one   = new Element("one", 1);
            IElement two   = new Element("two", 2);
            IElement three = new Element("three", 3);
            IElement four  = new Element("four", 4);
            IElement five  = new Element("five", 5);

            // create full set
            ISet_E fullSet = new Set_E("full_set",
                                       new List <IElement> {
                one, two, three, four, five
            }, 0, true);

            // create subsets
            ISet_E subset_1 = new Set_E("subset_1",
                                        new List <IElement> {
                one, three
            }, 8, false);
            ISet_E subset_2 = new Set_E("subset_2",
                                        new List <IElement> {
                three, five
            }, 16, false);
            ISet_E subset_3 = new Set_E("subset_3",
                                        new List <IElement> {
                three
            }, 6, false);
            ISet_E subset_4 = new Set_E("subset_4",
                                        new List <IElement> {
                one, two, four
            }, 15, false);
            ISet_E subset_5 = new Set_E("subset_5",
                                        new List <IElement> {
                one, five
            }, 7, false);

            var sets = new List <ISet_E> {
                subset_1, subset_2, subset_3, subset_4, subset_5
            };

            // use default settings
            var config = new Configuration();

            config.NameHandling            = NameHandlingStyle.UniqueLongNames;
            config.ComputeRemovedVariables = true;
            using (var scope = new ModelScope(config))
            {
                // create a model, based on given data and the model scope
                var setProblemModel = new SetProblemModel(sets, fullSet);

                // Get a solver instance, change your solver
                var solver = new GurobiSolver();

                // solve the model
                var solution = solver.Solve(setProblemModel.Model);

                // import the results back into the model
                setProblemModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));

                // print objective and variable decisions
                Console.WriteLine($"{solution.ObjectiveValues.Single()}");
                setProblemModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}"));

                setProblemModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory);
            }
        }
Esempio n. 7
0
            public void Should_ThrowException_When_NullExecutionContext()
            {
                var modelScope = new ModelScope <MemberClass>(c => true);

                Assert.Throws <ArgumentNullException>(() => { modelScope.TryGetErrors(new MemberClass(), null, ValidationStrategy.Complete, 0, out _); });
            }
Esempio n. 8
0
        //TODO: make this more pretty
        public static void Main(string[] args)
        {
            var cliApp     = new CommandLineApplication();
            var xivPathOpt = cliApp.Option("-p |--game-path <pathToFFXIV>",
                                           "Path to the FFXIV game install (folder containing boot and game)", CommandOptionType.SingleValue);

            var configOpt = cliApp.Option("-c |--config-path <pathToYaml>",
                                          "Path to configuration YAML file, default to config.yaml", CommandOptionType.SingleValue);

            var excludedOpt = cliApp.Option("-X |--exclude <itemId>",
                                            "Item ids of gear or food to exclude from solving; repeat for non-unique items", CommandOptionType.MultipleValue);

            var requiredOpt = cliApp.Option("-R |--require <itemId>",
                                            "Item ids of items required when solving", CommandOptionType.MultipleValue);

            var minIlvlOpt = cliApp.Option("-m |--min-itemlevel <ilvl>",
                                           "Minimum item level of items to consider. Uses max-20 if not passed.", CommandOptionType.SingleValue);
            var maxIlvlOpt = cliApp.Option("-M |--max-itemlevel <ilvl>",
                                           "Maximum item level of items to consider", CommandOptionType.SingleValue);

            var maxOvermeldTierOpt = cliApp.Option("-T |--max-overmeld-tier <tier>",
                                                   "The max tier of materia allowed for overmelds", CommandOptionType.SingleValue);

            var noMaximizeUnweightedOpt = cliApp.Option("--no-maximize-unweighted",
                                                        "Choose to disable maximizing unweighted stats (usually accuracy). Shouldn't be needed.",
                                                        CommandOptionType.NoValue);

            var noFoodOpt = cliApp.Option("--no-food", "Disable food", CommandOptionType.NoValue);

            var noMateriaOpt = cliApp.Option("--no-materia", "Disable materia", CommandOptionType.NoValue);

            var noRelicOpt = cliApp.Option("--no-relic", "Disable relic", CommandOptionType.NoValue);

            var tiersOpt = cliApp.Option("--use-tiers", "Enable SS tiers. Warning: slow unless using a commercial solver", CommandOptionType.NoValue);

            var outputOpt = cliApp.Option("-o |--output <file>", "Write output to <file>", CommandOptionType.SingleValue);

            var solverOpt = cliApp.Option("-s |--solver <solver>", "Solver to use (default: GLPK)",
                                          CommandOptionType.SingleValue);

            var noSolveOpt = cliApp.Option("--no-solve", "Don't solve the model; only works in conjunction with --debug", CommandOptionType.NoValue);

            var debugOpt = cliApp.Option("-d |--debug", "Print the used models in the current directory as model.lp",
                                         CommandOptionType.NoValue);

            var jobArg = cliApp.Argument("<job>", "Enter the job abbreviation to solve for");

            cliApp.HelpOption("-h |--help");

            cliApp.OnExecute(() =>
            {
                if (jobArg.Value == null)
                {
                    Console.Error.WriteLine("You must provide a job to solve for.");
                    return(1);
                }

                if (!xivPathOpt.HasValue())
                {
                    Console.Error.WriteLine("You must provide a path to FFXIV!");
                    return(1);
                }

                var realm   = new ARealmReversed(xivPathOpt.Value(), Language.English);
                var xivColl = realm.GameData;

                //TODO: can combine those converters
                var deserializer = new DeserializerBuilder()
                                   .WithTypeConverter(new BaseParamConverter(xivColl))
                                   .WithTypeConverter(new ClassJobConverter(xivColl))
                                   .WithTypeConverter(new EquipSlotConverter(xivColl))
                                   .WithTypeConverter(new ItemConverter(xivColl))
                                   .WithTypeConverter(new PiecewiseLinearConverter())
                                   .WithNamingConvention(new CamelCaseNamingConvention())
                                   .Build();

                SolverConfig solverConfig = null;

                using (var s = new FileStream(configOpt.HasValue() ? configOpt.Value() : "config.yaml", FileMode.Open))
                {
                    solverConfig = deserializer.Deserialize <SolverConfig>(new StreamReader(s));
                }

                solverConfig.MaximizeUnweightedValues = !noMaximizeUnweightedOpt.HasValue();
                solverConfig.UseTiers = tiersOpt.HasValue();

                var classJob = xivColl.GetSheet <ClassJob>().Single(x => string.Equals(x.Abbreviation, jobArg.Value, StringComparison.InvariantCultureIgnoreCase));

                var items = xivColl.GetSheet <Item>().ToList();

                if (excludedOpt.HasValue())
                {
                    var excludedIds = new List <int>();
                    foreach (var excluded in excludedOpt.Values)
                    {
                        try
                        {
                            var id   = int.Parse(excluded);
                            var item = xivColl.Items[id];
                            excludedIds.Add(id);
                        }
                        catch (KeyNotFoundException)
                        {
                            Console.Error.WriteLine($"Unknown id {excluded}, ignoring.");
                        }
                        catch (FormatException)
                        {
                            Console.Error.WriteLine($"Not an integer: {excluded}");
                        }
                        catch (OverflowException)
                        {
                            Console.Error.WriteLine($"Too large: {excluded}");
                        }
                    }
                    items = items.Where(k => !excludedIds.Contains(k.Key)).ToList();
                }

                //TODO: duplicated code
                if (requiredOpt.HasValue())
                {
                    solverConfig.RequiredItems = new List <int>();
                    requiredOpt.Values.Select(int.Parse).ForEach(solverConfig.RequiredItems.Add);
                }

                var equip = items.OfType <Equipment>().Where(e => e.ClassJobCategory.ClassJobs.Contains(classJob));

                var maxIlvl = equip.Max(x => x.ItemLevel.Key);
                if (maxIlvlOpt.HasValue())
                {
                    maxIlvl = int.Parse(maxIlvlOpt.Value());
                }

                var minIlvl = maxIlvl - 20;
                if (minIlvlOpt.HasValue())
                {
                    minIlvl = int.Parse(minIlvlOpt.Value());
                }

                equip = equip.Where(e => e.ItemLevel.Key >= minIlvl && e.ItemLevel.Key <= maxIlvl || solverConfig.RequiredItems != null && solverConfig.RequiredItems.Contains(e.Key)).ToList();

                var food = noFoodOpt.HasValue() ? new List <FoodItem>() : items.Where(FoodItem.IsFoodItem).Select(t => new FoodItem(t));

                var maxTier = items.OfType <MateriaItem>().Max(i => i.Tier);
                var materia = noMateriaOpt.HasValue() ? new Dictionary <MateriaItem, bool>() : items.OfType <MateriaItem>()
                              .Where(i => i.Tier == maxTier || (maxOvermeldTierOpt.HasValue() && i.Tier == int.Parse(maxOvermeldTierOpt.Value()) - 1))
                              .ToDictionary(i => i, i => !maxOvermeldTierOpt.HasValue() || i.Tier < int.Parse(maxOvermeldTierOpt.Value()));

                if (noRelicOpt.HasValue())
                {
                    solverConfig.RelicConfigs = new Dictionary <int, RelicConfig>();
                }

                //TODO: improve solver handling
                SolverBase solver = CreateGLPKSolver();
                if (solverOpt.HasValue())
                {
                    switch (solverOpt.Value())
                    {
                    case "Gurobi":
                        solver = new GurobiSolver();
                        solverConfig.SolverSupportsSOS = true;
                        break;
                    }
                }

                var debug    = debugOpt.HasValue();
                var settings = new OptimizationConfigSection();
                //settings.ModelElement.EnableFullNames = debug;

                using (var scope = new ModelScope(settings))
                {
                    var model = new BisModel(solverConfig, classJob,
                                             equip, food, materia);

                    if (debug)
                    {
                        using (var f = new FileStream("model.lp", FileMode.Create))
                        {
                            model.Model.Write(f, FileType.LP);
                        }
                        using (var f = new FileStream("model.mps", FileMode.Create))
                        {
                            model.Model.Write(f, FileType.MPS);
                        }

                        if (noSolveOpt.HasValue())
                        {
                            Console.WriteLine("Printed model, exiting...");
                            return(0);
                        }
                    }

                    var solution = solver.Solve(model.Model);

                    model.ApplySolution(solution);

                    if (outputOpt.HasValue())
                    {
                        using (var fs = new FileStream(outputOpt.Value(), FileMode.Create))
                        {
                            var sw = new StreamWriter(fs);
                            OutputModel(model, sw);
                            sw.Close();
                        }
                    }
                    else
                    {
                        OutputModel(model, Console.Out);
                    }
                    Console.WriteLine(solverConfig.UseTiers ? "SS tiers have been taken into account" : "SS tiers have been ignored; pass --use-tiers to enable (slow)");
                }

                return(0);
            });

            cliApp.Execute(args);
        }
        /// <summary>
        /// The main method
        /// </summary>
        /// <param name="args">
        /// no arguments required
        /// </param>
        static void Main(string[] args)
        {
            var size    = Enumerable.Range(0, 9).ToList();
            var section = size.GroupBy(s => s / 3);

            // you may manipulate the following game, which is the initial state of the Sudoku to your liking
            // note: obviously not observing the rules of Sudoku here makes the problem infeasible
            var game = new int?[, ] {
                //  0    1      2     3     4    5     6     7     8
                { null, 3, null, null, null, null, null, null, null },
                { null, null, null, 1, 9, 5, null, null, null },
                { null, null, 8, null, null, null, null, 6, null },

                { 8, null, null, null, 6, null, null, null, null },
                { 4, null, null, 8, null, null, null, null, 1 },
                { null, null, null, null, 2, null, null, null, null },

                { null, 6, null, null, null, null, 2, 8, null },
                { null, null, null, 4, 1, 9, null, null, 5 },
                { null, null, null, null, null, null, null, 7, null },
            };

            // use default settings
            var config = new Configuration();

            config.NameHandling            = NameHandlingStyle.UniqueLongNames;
            config.ComputeRemovedVariables = true;
            using (var scope = new ModelScope(config))
            {
                // create a model, based on given data and the model scope
                var sudokuModel = new SudokuModel(size, section, game);

                // get a solver instance, change your solver
                var solver = new CplexSolver();

                // solve the model
                var solution = solver.Solve(sudokuModel.Model);

                // print objective and variable decisions
                Console.WriteLine("Result: ");
                foreach (var row in size)
                {
                    foreach (var col in size)
                    {
                        foreach (var value in size)
                        {
                            if (sudokuModel.field[col, row, value].Value > 0)
                            {
                                Console.Write(string.Format("   {0}", value + 1));
                            }
                        }
                        if ((col + 1) % 3 == 0)
                        {
                            Console.Write("  ");
                        }
                    }
                    if ((row + 1) % 3 == 0)
                    {
                        Console.WriteLine();
                    }
                    Console.WriteLine();
                }
            }
        }
        /// <summary>
        /// The main method
        /// </summary>
        /// <param name="args">
        /// no arguments required
        /// </param>
        static void Main(string[] args)
        {
            INode pad = new Node("Paderborn", 0, true); // Starting node (depot)
                                                        // of our vehicle routing problem
            INode nyc = new Node("New York", 1500, false);
            INode bjs = new Node("Beijing", 2000, false);
            INode sao = new Node("São Paulo", 2000, false);
            INode sfo = new Node("San Francisco", 2500, false);

            var nodes = new List <INode> {
                pad, nyc, bjs, sao, sfo
            };

            var edges = new List <IEdge>
            {
                //Paderborn outgoing
                new Edge(pad, nyc, 6130),
                new Edge(pad, bjs, 7660),
                new Edge(pad, sao, 9950),
                new Edge(pad, sfo, 9000),

                // from Beijing
                new Edge(bjs, sfo, 9510),

                // from New York
                new Edge(nyc, bjs, 11000),
                new Edge(nyc, sfo, 4140),

                // from San Francisco
                new Edge(sfo, sao, 10400),

                // from Sao Paulo
                new Edge(sao, nyc, 7680),

                //Paderborn incoming
                new Edge(nyc, pad, 6130),
                new Edge(bjs, pad, 7660),
                new Edge(sao, pad, 9950),
                new Edge(sfo, pad, 9000),
            };

            var vehicles = 3;    // initialize 3 vehicles

            var capacity = 4000; // each vehicle has a capacity of 4000 units

            // use default settings
            var config = new Configuration();

            config.NameHandling            = NameHandlingStyle.UniqueLongNames;
            config.ComputeRemovedVariables = true;
            using (var scope = new ModelScope(config))
            {
                // create a model, based on given data and the modelscope
                var VRPModel = new VehicleRoutingModel(nodes, edges, vehicles, capacity);

                // Get a solver instance, change your solver
                using (var solver = new GurobiSolver())
                {
                    try
                    {
                        // troubleshooting

                        solver.Configuration.TimeLimit = 1;
                        (solver.Configuration as GurobiSolverConfiguration).ComputeIIS = true;

                        // troubleshooting

                        // solve the model
                        var solution = solver.Solve(VRPModel.Model);
                        if (solution.ConflictingSet != null)
                        {
                            var conflicts = solution.ConflictingSet.ToString();
                            Console.WriteLine(conflicts);
                        }

                        // import the results back into the model
                        VRPModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));

                        // print objective and variable decisions
                        Console.WriteLine($"{solution.ObjectiveValues.Single()}");
                        VRPModel.x.Variables.ForEach(x => Console.WriteLine($"{x.ToString().PadRight(36)}: {x.Value}"));
                        VRPModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}"));

                        VRPModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory);
                    }
                    catch (Exception) { }
                }
            }
        }
        //TODO: make this more pretty
        public static void Main(string[] args)
        {
            var cliApp     = new CommandLineApplication();
            var xivPathOpt = cliApp.Option("-p |--game-path <pathToFFXIV>",
                                           "Path to the FFXIV game install (folder containing boot and game)", CommandOptionType.SingleValue);

            var configOpt = cliApp.Option("-c |--config-path <pathToYaml>",
                                          "Path to configuration YAML file, default to config.yaml", CommandOptionType.SingleValue);

            var excludedOpt = cliApp.Option("-X |--exclude <itemId>",
                                            "Item ids of items to exclude from solving", CommandOptionType.MultipleValue);

            var minIlvlOpt = cliApp.Option("-m |--min-itemlevel <ilvl>",
                                           "Minimum item level of items to consider. Uses max-20 if not passed.", CommandOptionType.SingleValue);
            var maxIlvlOpt = cliApp.Option("-M |--max-itemlevel <ilvl>",
                                           "Maximum item level of items to consider", CommandOptionType.SingleValue);

            var maxOvermeldTierOpt = cliApp.Option("-T |--max-overmeld-tier <tier>",
                                                   "The max tier of materia allowed for overmelds", CommandOptionType.SingleValue);

            var noMaximizeUnweightedOpt = cliApp.Option("--no-maximize-unweighted",
                                                        "Choose to disable maximizing unweighted stats (usually accuracy). Shouldn't be needed.",
                                                        CommandOptionType.NoValue);

            var solverOpt = cliApp.Option("-s |--solver <solver>", "Solver to use (default: GLPK)",
                                          CommandOptionType.SingleValue);

            var debugOpt = cliApp.Option("-d |--debug", "Print the used models in the current directory as model.lp",
                                         CommandOptionType.NoValue);

            var jobArg = cliApp.Argument("<job>", "Enter the job abbreviation to solve for");

            cliApp.HelpOption("-h |--help");

            cliApp.OnExecute(() =>
            {
                if (jobArg.Value == null)
                {
                    Console.Error.WriteLine("You must provide a job to solve for.");
                    return(1);
                }

                if (!xivPathOpt.HasValue())
                {
                    Console.Error.WriteLine("You must provide a path to FFXIV!");
                    return(1);
                }

                var realm   = new ARealmReversed(xivPathOpt.Value(), Language.English);
                var xivColl = realm.GameData;

                var deserializer = new DeserializerBuilder()
                                   .WithTypeConverter(new BaseParamConverter(xivColl))
                                   .WithTypeConverter(new ClassJobConverter(xivColl))
                                   .WithNamingConvention(new CamelCaseNamingConvention())
                                   .Build();

                AppConfig config = null;

                using (var s = new FileStream(configOpt.HasValue() ? configOpt.Value() : "config.yaml", FileMode.Open))
                {
                    config = deserializer.Deserialize <AppConfig>(new StreamReader(s));
                }

                var classJob = xivColl.GetSheet <ClassJob>().Single(x => x.Abbreviation == jobArg.Value);

                var jobConfig = config.JobConfigs[classJob];

                var items = xivColl.GetSheet <Item>().ToList();

                if (excludedOpt.HasValue())
                {
                    var excludedIds = new List <int>();
                    foreach (var excluded in excludedOpt.Values)
                    {
                        var id   = int.Parse(excluded);
                        var item = xivColl.Items[id];
                        if (item != null)
                        {
                            Console.WriteLine($"Excluding {item}.");
                            excludedIds.Add(id);
                        }
                        else
                        {
                            Console.Error.WriteLine($"Unknown id {id}, ignoring.");
                        }
                    }
                    items = items.Where(k => !excludedIds.Contains(k.Key)).ToList();
                }

                var equip = items.OfType <Equipment>().Where(e => e.ClassJobCategory.ClassJobs.Contains(classJob));

                var maxIlvl = equip.Max(x => x.ItemLevel.Key);
                if (maxIlvlOpt.HasValue())
                {
                    maxIlvl = int.Parse(maxIlvlOpt.Value());
                }

                var minIlvl = maxIlvl - 20;
                if (minIlvlOpt.HasValue())
                {
                    minIlvl = int.Parse(minIlvlOpt.Value());
                }

                equip = equip.Where(e => e.ItemLevel.Key >= minIlvl && e.ItemLevel.Key <= maxIlvl).ToList();

                var food = items.Where(FoodItem.IsFoodItem).Select(t => new FoodItem(t));

                var materia = items.OfType <MateriaItem>()
                              .ToDictionary(i => i,
                                            i => !maxOvermeldTierOpt.HasValue() || i.Tier < int.Parse(maxOvermeldTierOpt.Value()));

                var relicCaps =
                    equip.Where(e => config.RelicCaps.ContainsKey(e.ItemLevel.Key))
                    .ToDictionary(e => e, e => config.RelicCaps[e.ItemLevel.Key]);

                //TODO: improve solver handling
                SolverBase solver = new GLPKSolver();
                if (solverOpt.HasValue())
                {
                    switch (solverOpt.Value())
                    {
                    case "Gurobi":
                        solver = new GurobiSolver();
                        break;

                    case "Z3":
                        solver = new Z3Solver();
                        break;
                    }
                }


                using (var scope = new ModelScope())
                {
                    var model = new BisModel(jobConfig.Weights, jobConfig.StatRequirements, config.BaseStats,
                                             equip, food, materia, relicCaps, maximizeUnweightedValues: !noMaximizeUnweightedOpt.HasValue());

                    if (debugOpt.HasValue())
                    {
                        using (var f = new FileStream("model.lp", FileMode.Create))
                        {
                            var obj        = model.Model.Objectives.First();
                            obj.Expression = obj.Expression.Normalize();
                            model.Model.Constraints.ForEach(c => c.Expression = c.Expression.Normalize());
                            model.Model.Write(f, FileType.LP);
                        }
                    }

                    var solution = solver.Solve(model.Model);
                    model.ApplySolution(solution);
                    Console.WriteLine("Gear: ");
                    model.ChosenGear.ForEach(Console.WriteLine);
                    Console.WriteLine("Materia: ");
                    model.ChosenMateria.ForEach(Console.WriteLine);
                    if (model.ChosenRelicStats.Any())
                    {
                        Console.WriteLine("Relic stats: ");
                        model.ChosenRelicStats.ForEach(Console.WriteLine);
                    }
                    Console.WriteLine("Food: ");
                    Console.WriteLine(model.ChosenFood);
                    Console.WriteLine("Allocated stats: ");
                    model.ResultAllocatableStats.ForEach(kv => Console.WriteLine(kv));
                    Console.WriteLine("Result stats with food:");
                    model.ResultTotalStats.ForEach(kv => Console.WriteLine(kv));
                    Console.WriteLine($"Result stat weight: {model.ResultWeight}");
                }

                return(0);
            });

            cliApp.Execute(args);
        }
Esempio n. 12
0
        public void Should_RuleSingleError_BeNullAfterInit()
        {
            var modelScope = new ModelScope <MemberClass>(c => true);

            Assert.Null(modelScope.RuleSingleError);
        }
Esempio n. 13
0
        public void Should_Name_MatchCommandInBuilder()
        {
            var modelScope = new ModelScope <MemberClass>(c => true);

            Assert.Equal("Valid", modelScope.Name);
        }
Esempio n. 14
0
            public void Should_ThrowException_When_NullTargetCollection()
            {
                var modelScope = new ModelScope <MemberClass>(c => true);

                Assert.Throws <ArgumentNullException>(() => { modelScope.InsertErrors(null, new ErrorsCollection()); });
            }
Esempio n. 15
0
        async Task SendUsingExistingModel(IPipe<ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            try
            {
                using (var context = await scope.Attach(cancellationToken).ConfigureAwait(false))
                {
//                    if (_log.IsDebugEnabled)
//                        _log.DebugFormat("Using model: {0}", ((ModelContext)context).ConnectionContext.HostSettings.ToDebugString());

                    await modelPipe.Send(context).ConfigureAwait(false);
                }
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                    _log.Debug("The model usage threw an exception", exception);

                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.CreateFaulted(exception);

                throw;
            }
        }
        async Task SendUsingNewModel(IPipe <ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            IPipe <ConnectionContext> connectionPipe = Pipe.ExecuteAsync <ConnectionContext>(async connectionContext =>
            {
                IModel model = null;
                try
                {
                    if (_log.IsDebugEnabled)
                    {
                        _log.DebugFormat("Creating model: {0}", connectionContext.HostSettings.ToDebugString());
                    }

                    model = await connectionContext.CreateModel().ConfigureAwait(false);

                    EventHandler <ShutdownEventArgs> modelShutdown = null;
                    modelShutdown = (obj, reason) =>
                    {
                        model.ModelShutdown -= modelShutdown;

                        Interlocked.CompareExchange(ref _scope, null, scope);

                        scope.Shutdown(reason.ReplyText);
                    };

                    model.ModelShutdown += modelShutdown;

                    var modelContext = new RabbitMqModelContext(connectionContext, model, _cacheTaskScope, _host);

                    scope.Created(modelContext);
                }
                catch (Exception ex)
                {
                    Interlocked.CompareExchange(ref _scope, null, scope);

                    scope.CreateFaulted(ex);

                    model?.Dispose();

                    throw;
                }

                await SendUsingExistingModel(modelPipe, scope, cancellationToken).ConfigureAwait(false);
            });

            try
            {
                await _host.ConnectionCache.Send(connectionPipe, _cacheTaskScope.StoppedToken).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("The connection threw an exception", exception);
                }

                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.CreateFaulted(exception);

                throw;
            }
        }
Esempio n. 17
0
        static async Task SendUsingExistingModel(IPipe<ModelContext> modelPipe, ModelScope existingScope, CancellationToken cancellationToken)
        {
            try
            {
                using (SharedModelContext context = await existingScope.Attach(cancellationToken))
                {
                    await modelPipe.Send(context);
                }
            }
            catch (Exception ex)
            {
                if (_log.IsDebugEnabled)
                    _log.Debug("The existing model usage threw an exception", ex);

                throw;
            }
        }
Esempio n. 18
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");
                            }
                        }
                    }
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// The main method
        /// </summary>
        /// <param name="args">
        /// no arguments required
        /// </param>
        static void Main(string[] args)
        {
            // create jobs with their respective color and due date
            var jobs = new List <Job>
            {
                new Job {
                    Color = Color.White, DueDate = 40
                },
                new Job {
                    Color = Color.Brown, DueDate = 40
                },
                new Job {
                    Color = Color.Green, DueDate = 40
                },
                new Job {
                    Color = Color.Black, DueDate = 40
                },
            };

            // add setup times for the jobs created beforehand
            var setupTimes = new Dictionary <Job, int>()
            {
                { jobs.Single(j => j.Color == Color.White), 4 },
                { jobs.Single(j => j.Color == Color.Brown), 2 },
                { jobs.Single(j => j.Color == Color.Green), 3 },
                { jobs.Single(j => j.Color == Color.Black), 0 },
            };

            // add tasks to the different jobs created beforehand
            var tasks = new List <Task>
            {
                //  white
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.White), StepNumber = 1, Duration = 4
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.White), StepNumber = 2, Duration = 3
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.White), StepNumber = 3, Duration = 4
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.White), StepNumber = 4, Duration = 2
                },

                // brown
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Brown), StepNumber = 1, Duration = 4
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Brown), StepNumber = 2, Duration = 6
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Brown), StepNumber = 3, Duration = 4
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Brown), StepNumber = 4, Duration = 3
                },

                // green
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Green), StepNumber = 1, Duration = 3
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Green), StepNumber = 2, Duration = 4
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Green), StepNumber = 3, Duration = 3
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Green), StepNumber = 4, Duration = 3
                },

                // black
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Black), StepNumber = 1, Duration = 4
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Black), StepNumber = 2, Duration = 8
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Black), StepNumber = 3, Duration = 2
                },
                new Task()
                {
                    Job = jobs.Single(j => j.Color == Color.Black), StepNumber = 4, Duration = 8
                },
            };

            // create a rank for each task
            var ranks = Enumerable.Range(0, tasks.Count).ToList();

            // set up the machines with their name, the beforehand created setup times and the supported tasks as well as their setup cost
            var machines = new List <Machine>
            {
                new Machine
                {
                    MachineId      = "A",
                    SetupTimes     = setupTimes,
                    SupportedTasks = tasks.Where(task => new int[] { 1, 2 }.Contains(task.StepNumber)).ToList(),
                    Cost           = 1
                },
                new Machine
                {
                    MachineId      = "B",
                    SetupTimes     = setupTimes,
                    SupportedTasks = tasks.Where(task => new int[] { 1, 2, 3 }.Contains(task.StepNumber)).ToList(),
                    Cost           = 2
                },
                new Machine
                {
                    MachineId      = "C",
                    SetupTimes     = setupTimes,
                    SupportedTasks = tasks.Where(task => new int[] { 2, 3, 4 }.Contains(task.StepNumber)).ToList(),
                    Cost           = 3
                },
                new Machine
                {
                    MachineId      = "D",
                    SetupTimes     = setupTimes,
                    SupportedTasks = tasks.Where(task => new int[] { 3, 4 }.Contains(task.StepNumber)).ToList(),
                    Cost           = 4
                },
            };

            // register tasks with jobs
            jobs.ForEach(job => job.Tasks.AddRange(tasks.Where(task => task.Job == job).OrderBy(task => task.StepNumber)));

            // Use long names for easier debugging/model understanding.
            var config = new Configuration();

            config.NameHandling            = NameHandlingStyle.UniqueLongNames;
            config.ComputeRemovedVariables = true;
            using (var scope = new ModelScope(config))
            {
                // create a model, based on given data and the model scope
                var jobScheduleModel = new JobScheduleModel(jobs, setupTimes, tasks, ranks, machines);

                // Get a solver instance, change your solver
                var solverConfig = new GurobiSolverConfiguration {
                    TimeLimit = 120
                };
                using (var solver = new GurobiSolver(solverConfig))
                {
                    // solve the model
                    var solution = solver.Solve(jobScheduleModel.Model);

                    // print objective and variable decisions
                    Console.WriteLine(
                        $"Objective: {solution.ObjectiveValues.Single().Key} {(int)Math.Round(solution.ObjectiveValues.Single().Value)}");
                    Console.WriteLine($"Latest End: {(int)jobScheduleModel.LatestEnd.Value}");

                    foreach (var machine in machines)
                    {
                        foreach (var rank in ranks)
                        {
                            foreach (var task in machine.SupportedTasks)
                            {
                                if ((int)Math.Round(jobScheduleModel.taskMachineAssignment[task, machine, rank].Value) > 0)
                                {
                                    Console.WriteLine(
                                        $"Machine {machine}, Rank {rank}: Assigns Task={task}, Start: {(int)Math.Round(jobScheduleModel.startTime[task, machine, rank].Value):####}, Duration: {task.Duration:##}, End: {(int)Math.Round(jobScheduleModel.startTime[task, machine, rank].Value) + task.Duration:####}");
                                }
                            }
                        }

                        Console.WriteLine("---");
                    }

                    foreach (var job in jobs)
                    {
                        foreach (var task in job.Tasks)
                        {
                            foreach (var machine in machines.Where(m => m.SupportedTasks.Contains(task)))
                            {
                                foreach (var rank in ranks)
                                {
                                    if ((int)Math.Round(jobScheduleModel.taskMachineAssignment[task, machine, rank].Value) > 0)
                                    {
                                        Console.WriteLine(
                                            $"Task={task}, Rank {rank}: Assigned Machine {machine}, Start: {(int)Math.Round(jobScheduleModel.startTime[task, machine, rank].Value):####}, Duration: {task.Duration:##}, End: {(int)Math.Round(jobScheduleModel.startTime[task, machine, rank].Value) + task.Duration:####}");
                                    }
                                }
                            }
                        }

                        Console.WriteLine("---");
                    }
                }
            }
        }
Esempio n. 20
0
        public Task <ITPOutputContext> Solve(
            ICalculationsAbstractFactory calculationsAbstractFactory,
            IConstraintElementsAbstractFactory constraintElementsAbstractFactory,
            IConstraintsAbstractFactory constraintsAbstractFactory,
            IContextsAbstractFactory contextsAbstractFactory,
            ICrossJoinElementsAbstractFactory crossJoinElementsAbstractFactory,
            ICrossJoinsAbstractFactory crossJoinsAbstractFactory,
            IDependenciesAbstractFactory dependenciesAbstractFactory,
            IIndexElementsAbstractFactory indexElementsAbstractFactory,
            IIndicesAbstractFactory indicesAbstractFactory,
            IModelsAbstractFactory modelsAbstractFactory,
            IObjectiveFunctionsAbstractFactory objectiveFunctionsAbstractFactory,
            IParameterElementsAbstractFactory parameterElementsAbstractFactory,
            IParametersAbstractFactory parametersAbstractFactory,
            IResultElementsAbstractFactory resultElementsAbstractFactory,
            IResultsAbstractFactory resultsAbstractFactory,
            IVariablesAbstractFactory variablesAbstractFactory,
            ITPConfiguration TPConfiguration,
            ITPInputContext TPInputContext,
            ISolverConfiguration solverConfiguration)
        {
            ITPOutputContext TPOutputContext = null;

            return(Task.Run(() =>
            {
                using (ModelScope modelScope = dependenciesAbstractFactory.CreateModelScopeFactory().Create(TPConfiguration.Value))
                {
                    ITPModel model = modelsAbstractFactory.CreateTPModelFactory().Create(
                        constraintElementsAbstractFactory,
                        constraintsAbstractFactory,
                        crossJoinElementsAbstractFactory,
                        crossJoinsAbstractFactory,
                        dependenciesAbstractFactory,
                        indexElementsAbstractFactory,
                        indicesAbstractFactory,
                        objectiveFunctionsAbstractFactory,
                        parameterElementsAbstractFactory,
                        parametersAbstractFactory,
                        variablesAbstractFactory,
                        TPInputContext);

                    using (ISolver solver = dependenciesAbstractFactory.CreateSolverFactory().Create(solverConfiguration))
                    {
                        Solution solution = solver?.Solve(model?.Model);

                        if (solution?.ModelStatus == OPTANO.Modeling.Optimization.Solver.ModelStatus.Feasible)
                        {
                            model.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));

                            TPOutputContext = contextsAbstractFactory.CreateTPOutputContextFactory().Create(
                                calculationsAbstractFactory,
                                dependenciesAbstractFactory,
                                resultElementsAbstractFactory,
                                resultsAbstractFactory,
                                model,
                                solution);
                        }
                    }
                }

                return TPOutputContext;
            }));
        }
Esempio n. 21
0
        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);
        }