/// <summary> /// The main method /// </summary> /// <param name="args"> /// no arguments required /// </param> static void Main(string[] args) { // create example Nodes INode pb = new Node("Paderborn", 50); INode ny = new Node("New York", -100); INode b = new Node("Beijing", 50); INode sp = new Node("São Paulo", 50); INode sf = new Node("San Francisco", -50); // assign these nodes to a list of INodes var nodes = new List <INode> { pb, ny, b, sp, sf }; // create example Edges IEdge one = new Edge(ny, pb, null, 3, 6100); IEdge two = new Edge(b, ny, null, 2, 11000); IEdge three = new Edge(sp, b, 75, 1, 17600); IEdge four = new Edge(sf, sp, null, 4, 10500); IEdge five = new Edge(sp, pb, null, 5, 9900); IEdge six = new Edge(pb, b, 50, 1, 7600); // assign these edges to a list of IEdges var edges = new List <IEdge> { one, two, three, four, five, six }; // 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 designModel = new NetworkDesignModel(nodes, edges); // Get a solver instance, change your solver using (var solver = new GurobiSolver()) { // solve the model var solution = solver.Solve(designModel.Model); // import the results back into the model designModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues)); // print objective and variable decisions Console.WriteLine($"{solution.ObjectiveValues.Single()}"); designModel.x.Variables.ForEach(x => Console.WriteLine($"{x.ToString().PadRight(36)}: {x.Value}")); designModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}")); designModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory); } } }
/// <summary> /// Executa a otimização /// </summary> private static void ExecutaOtimizacao() { try { var _solver = new GurobiSolver(); _saidaViewModel = _solver.Run(_entradaViewModel); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
/// <summary> /// The main method /// </summary> /// <param name="args"> /// no arguments required /// </param> static void Main(string[] args) { INode pb = new Node("Paderborn", -100, 1000000); INode ny = new Node("New York", -200, 1750000); INode b = new Node("Beijing", -100, 750000); INode sp = new Node("São Paulo", 100, 0); INode sf = new Node("San Francisco", 100, 0); INode mo = new Node("Moscow", 100, 0); var nodes = new List <INode> { pb, ny, b, sp, sf, mo }; var edges = new List <IEdge> { new Edge(pb, sp, 100, 9900), new Edge(pb, sf, 100, 9500), new Edge(pb, mo, 100, 1900), new Edge(ny, sp, 100, 7600), new Edge(ny, sf, 100, 4100), new Edge(ny, mo, 100, 7500), new Edge(b, sp, 100, 17500), new Edge(b, sf, 100, 9500), new Edge(b, mo, 100, 5800) }; // 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 warehouseModel = new WarehouseLocationModel(nodes, edges); // Get a solver instance, change your solver using (var solver = new GurobiSolver()) { // solve the model var solution = solver.Solve(warehouseModel.Model); // import the results back into the model warehouseModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues)); // print objective and variable decisions Console.WriteLine($"{solution.ObjectiveValues.Single()}"); warehouseModel.x.Variables.ForEach(x => Console.WriteLine($"{x.ToString().PadRight(36)}: {x.Value}")); warehouseModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}")); warehouseModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory); } } }
static void Main(string[] args) { /* * Maximize * obj: x1 + 2 x2 + 3 x3 * Subject To * c1: x2 + x3 <= 20 * c2: x1 - 3 x2 + x3 <= 30 * c3: x1<= 20 * c4: x1>=40 * Bounds * 0 <= x1 <= 40 * Generals * x1 x2 x3 * End * */ var scopeConfig = new Configuration() { NameHandling = NameHandlingStyle.Manual }; using (var scope = new ModelScope(scopeConfig)) { var model = new Model { Name = "model" }; var x1 = new Variable("x1", 0, 40); var x2 = new Variable("x2"); var x3 = new Variable("x3"); model.AddConstraint(x2 + x3 <= 20, "c1"); model.AddConstraint(x1 - 2 * x2 + x3 <= 30, "c2"); var brokenConstraint2 = new Constraint(x1, "c3", upperBound: 20); model.AddConstraint(brokenConstraint2); var brokenConstraint1 = new Constraint(x1, "c4", 40); model.AddConstraint(brokenConstraint1); model.AddObjective(new Objective(x1 + 2 * x2 + 3 * x3, "obj")); var solverConfig = new GurobiSolverConfiguration() { ComputeIIS = true }; using (var solver = new GurobiSolver(solverConfig)) { var solution = solver.Solve(model); Assert.IsTrue(solution.ConflictingSet.ConstraintsLB.Contains(brokenConstraint1)); Assert.IsTrue(solution.ConflictingSet.ConstraintsUB.Contains(brokenConstraint2)); } } }
/// <summary> /// The main method /// </summary> /// <param name="args"> /// no arguments required /// </param> static void Main(string[] args) { INode pb = new Node("Paderborn", true); INode ny = new Node("New York", false); INode b = new Node("Beijing", false); INode sp = new Node("São Paulo", false); INode sf = new Node("San Francisco", false); var nodes = new List <INode> { pb, ny, b, sp, sf }; var edges = new List <IEdge> { new Edge(pb, ny, 6100), new Edge(pb, b, 7600), new Edge(pb, sp, 9900), new Edge(ny, sp, 7600), new Edge(ny, b, 11000), new Edge(b, sf, 9500), new Edge(b, ny, 11000), new Edge(sp, pb, 9900), new Edge(sf, sp, 10500), new Edge(sf, ny, 4100) }; // 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 travelingSalesmanModel = new TravelingSalesmanModel(nodes, edges); // Get a solver instance, change your solver var solver = new GurobiSolver(); // solve the model var solution = solver.Solve(travelingSalesmanModel.Model); // import the results back into the model travelingSalesmanModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues)); // print objective and variable decisions Console.WriteLine($"{solution.ObjectiveValues.Single()}"); travelingSalesmanModel.y.Variables.ForEach(x => Console.WriteLine($"{x.ToString().PadRight(36)}: {x.Value}")); travelingSalesmanModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory); } }
public void Init() { // create example Nodes INode pb = new Node("Paderborn", 50); INode ny = new Node("New York", -100); INode b = new Node("Beijing", 50); INode sp = new Node("São Paulo", 50); INode sf = new Node("San Francisco", -50); // assign these nodes to a list of INodes nodes = new List <INode> { pb, ny, b, sp, sf }; // create example Edges IEdge one = new Edge(ny, pb, null, 3, 6100); IEdge two = new Edge(b, ny, null, 2, 11000); IEdge three = new Edge(sp, b, 75, 1, 17600); IEdge four = new Edge(sf, sp, null, 4, 10500); IEdge five = new Edge(sp, pb, null, 5, 9900); IEdge six = new Edge(pb, b, 50, 1, 7600); // assign these edges to a list of IEdges edges = new List <IEdge> { one, two, three, four, five, six }; // Use long names for easier debugging/model understanding. configuration = new Configuration(); configuration.NameHandling = NameHandlingStyle.UniqueLongNames; configuration.ComputeRemovedVariables = true; using (var scope = new ModelScope(configuration)) { // create a model, based on given data and the model scope designModel = new NetworkDesignModel(nodes, edges); // Get a solver instance, change your solver using (var solver = new GurobiSolver()) { // solve the model // if this fails: check if this project references the solver. Add one and update the using, if required. var solution = solver.Solve(designModel.Model); // import the results back into the model designModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues)); scope.ModelBehavior = OPTANO.Modeling.Optimization.Configuration.ModelBehavior.Manual; } } }
/// <summary> /// The main method /// </summary> /// <param name="args"> /// no arguments required /// </param> static void Main(string[] args) { // create time steps with their "name", demand, setup cost, // production cost per unit, inventory cost per unit var csv = new CsvReader(File.OpenText("timesteps.csv")); csv.Configuration.Delimiter = ";"; csv.Configuration.CultureInfo = new CultureInfo("en-US"); var periodInformation = csv.GetRecords <PeriodInformation>(); // use default settings var config = new Configuration { NameHandling = NameHandlingStyle.Manual, ComputeRemovedVariables = true }; using (var scope = new ModelScope(config)) { // create a model, based on given data and the model scope var clspModel = new CapacitatedLotsizingModel(periodInformation); var solverCfg = new GurobiSolverConfiguration() { ModelOutputFile = new FileInfo("clsp.lp"), }; // Get a solver instance, change your solver var solver = new GurobiSolver(solverCfg); // solve the model var solution = solver.Solve(clspModel.Model); // print objective and variable decisions Console.WriteLine($"{solution.ObjectiveValues.Single()}"); clspModel.y.Variables.ForEach(x => Console.WriteLine($"{x.ToString().PadRight(36)}: {x.Value}")); clspModel.x.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}")); clspModel.s.Variables.ForEach(s => Console.WriteLine($"{s.ToString().PadRight(36)}: {s.Value}")); clspModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory); PlottingUtils.CreateAndExportLotSizingPlot(clspModel); } Console.ReadLine(); }
public LPSolver( int input_dimension, int total_constraint_count, double[] origin, // Just the image, not the epsilon double originbound // Bounding rectangle ) { solver_ = new GurobiSolver(); input_dimension_ = input_dimension; int varCount = LPSTerm.TotalVarCount(); Console.WriteLine("Number of variables: " + varCount); vars_ = new int[varCount]; for (int i = 0; i < varCount; i++) { int vid; solver_.AddVariable("x" + i, out vid); solver_.SetIntegrality(vid, RobustnessOptions.Integrality); if (i < origin.Length) { double lb = Math.Max(Utils.RobustnessOptions.MinValue, origin[i] - originbound); double ub = Math.Min(Utils.RobustnessOptions.MaxValue, origin[i] + originbound); if (lb <= ub) { // Tighter bounds for the image variables! solver_.SetBounds(vid, lb, ub); } else { // Bound validation failed, very weird. Oh well just don't use the bounds. // The programmer got the Min/Max values wrong. solver_.SetBounds(vid, origin[i] - originbound, origin[i] + originbound); } } else { solver_.SetBounds(vid, Utils.RobustnessOptions.MinValue, Utils.RobustnessOptions.MaxValue); } vars_[i] = vid; } }
/// <summary> /// The main method /// </summary> /// <param name="args"> /// no arguments required /// </param> static void Main(string[] args) { // create example Items var csv = new CsvReader(File.OpenText("knapsackItems.csv")); csv.Configuration.Delimiter = ";"; csv.Configuration.CultureInfo = new CultureInfo("en-US"); csv.Configuration.RegisterClassMap <KnapsackItemMap>(); var items = csv.GetRecords <KnapsackItem>().ToList(); // maximum weight of all the items var maxWeight = 10.8; // Use long names for easier debugging/model understanding. var config = new Configuration { NameHandling = NameHandlingStyle.UniqueLongNames, ComputeRemovedVariables = true }; using (var scope = new ModelScope(config)) { // create a model, based on given data and the model scope var knapsackModel = new KnapsackModel(items, maxWeight); // Get a solver instance, change your solver using (var solver = new GurobiSolver()) { // solve the model var solution = solver.Solve(knapsackModel.Model); ExportSolution(solution, knapsackModel); // results from solution are already "synced" with variables in knapsack model. Program.AllowActivationOfAtMost4ActiveVariables(knapsackModel); // re-solve 1 var solutionB = solver.Solve(knapsackModel.Model); ExportSolution(solutionB, knapsackModel); Program.AllowActivationOfAtMost4ActiveVariables(knapsackModel); // re-solve 2 var solutionC = solver.Solve(knapsackModel.Model); ExportSolution(solutionC, knapsackModel); } } }
/// <summary> /// The main method /// </summary> /// <param name="args"> /// no arguments required /// </param> static void Main(string[] args) { // create example Items var csv = new CsvReader(File.OpenText("knapsackItems.csv")); csv.Configuration.Delimiter = ";"; csv.Configuration.CultureInfo = new CultureInfo("en-US"); csv.Configuration.RegisterClassMap <KnapsackItemMap>(); var items = csv.GetRecords <KnapsackItem>().ToList(); // maximum weight of all the items var maxWeight = 10.8; // use default settings var config = new Configuration { NameHandling = NameHandlingStyle.UniqueLongNames, ComputeRemovedVariables = true }; using (var scope = new ModelScope(config)) { // create a model, based on given data and the model scope var knapsackModel = new KnapsackModel(items, maxWeight); // Get a solver instance, change your solver var solver = new GurobiSolver(); // solve the model var solution = solver.Solve(knapsackModel.Model); // import the results back into the model knapsackModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues)); // print objective and variable decisions Console.WriteLine($"{solution.ObjectiveValues.Single()}"); knapsackModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}")); knapsackModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory); } Console.ReadLine(); }
/// <summary> /// The main method /// </summary> /// <param name="args"> /// no arguments required /// </param> static void Main(string[] args) { // set size of the board - board is always a square int dimension = 8; // 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 queensModel = new QueensModel(dimension); // Get a solver instance, change your solver var solver = new GurobiSolver(); // solve the model var solution = solver.Solve(queensModel.Model); // import the results back into the model queensModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues)); // print objective and variable decisions Console.WriteLine($"{solution.ObjectiveValues.Single()}"); //queensModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}")); Console.WriteLine("Result: "); foreach (var row in Enumerable.Range(0, dimension)) { foreach (var col in Enumerable.Range(0, dimension)) { Console.Write(string.Format(queensModel.y[row, col].Value + " ")); } Console.WriteLine(); } } }
public void Initialize() { // create example Items var csv = new CsvReader(File.OpenText("knapsackItems.csv")); csv.Configuration.Delimiter = ";"; csv.Configuration.CultureInfo = new CultureInfo("en-US"); csv.Configuration.RegisterClassMap <KnapsackItemMap>(); _items = csv.GetRecords <KnapsackItem>().ToList(); // maximum weight of all the items _maxWeight = 10.8; // Use long names for easier debugging/model understanding. var config = new Configuration { NameHandling = NameHandlingStyle.UniqueLongNames, ComputeRemovedVariables = true }; using (var scope = new ModelScope(config)) { // create a model, based on given data and the model scope var knapsackModel = new KnapsackModel(_items, _maxWeight); // Get a solver instance, change your solver using (var solver = new GurobiSolver()) { // solve the model var solution = solver.Solve(knapsackModel.Model); // import the results back into the model knapsackModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues)); foreach (var knapsackItem in _items) { knapsackItem.IsPacked = Math.Abs(knapsackModel.y[knapsackItem].Value - 1) < scope.EPSILON; } } } }
/// <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 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 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 e) { Console.WriteLine(e); } } } }
/// <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 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 sudokuModel = new SudokuModel(size, section, game); // get a solver instance, change your solver using (var solver = new GurobiSolver()) { // 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(); } } } }
//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) { // 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); } }
/// <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("---"); } } } }
//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); }