示例#1
0
        /// <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);
     }
 }
示例#3
0
        /// <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);
                }
            }
        }
示例#4
0
        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);
            }
        }
示例#6
0
        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();
        }
示例#8
0
            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;
                }
            }
示例#9
0
        /// <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();
        }
示例#11
0
        /// <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();
                }
            }
        }
示例#12
0
        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;
                    }
                }
            }
        }
示例#13
0
        /// <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);
                    }
                }
            }
        }
示例#14
0
        /// <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();
                    }
                }
            }
        }
示例#15
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);
        }
示例#16
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);
            }
        }
示例#17
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("---");
                    }
                }
            }
        }
        //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);
        }