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; } }
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; } }
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); }
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); }
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; } }
/// <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); } }
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 _); }); }
//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); }
public void Should_RuleSingleError_BeNullAfterInit() { var modelScope = new ModelScope <MemberClass>(c => true); Assert.Null(modelScope.RuleSingleError); }
public void Should_Name_MatchCommandInBuilder() { var modelScope = new ModelScope <MemberClass>(c => true); Assert.Equal("Valid", modelScope.Name); }
public void Should_ThrowException_When_NullTargetCollection() { var modelScope = new ModelScope <MemberClass>(c => true); Assert.Throws <ArgumentNullException>(() => { modelScope.InsertErrors(null, new ErrorsCollection()); }); }
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; } }
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; } }
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"); } } } } } }
/// <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("---"); } } } }
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; })); }
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); }