コード例 #1
0
        // If the solution space is very large, this method will not return.
        // The most likely result is that it will exceed memory capacity
        // and then fail.  As a result, we shouldn't use this method in
        // any production optimization.
        public IEnumerable <ProductionTarget> GetFeasibleTargets(double claySupply, double glazeSupply)
        {
            List <ProductionTarget> targets = new List <ProductionTarget>();

            // Setup the Gurobi environment & Model
            GRBEnv   env   = new GRBEnv();
            GRBModel model = new GRBModel(env);

            // Setup the decision variables
            GRBVar xS = CreateSmallVasesVariable(claySupply, model);
            GRBVar xL = CreateLargeVasesVariable(glazeSupply, model);

            model.Update();

            // Create Constraints
            CreateConstraints(model, xS, xL, claySupply, glazeSupply);

            // Find the greatest number of small vases we can make
            var maxSmall = System.Math.Min(claySupply, glazeSupply);

            // Find the greatest number of large vases we can make
            var maxLarge = System.Math.Min(claySupply / 4.0, glazeSupply / 2.0);

            // Find all feasible combinations of small and large vases
            // Note: There are probably several better ways of doing this
            // that are more efficient and organic.  For example, we could make
            // a tree that represents all of the possible decisions and let the
            // optimizer find the solutions from within that tree.
            var results = new List <ProductionTarget>();

            for (int nSmall = 0; nSmall <= maxSmall; nSmall++)
            {
                for (int nLarge = 0; nLarge <= maxLarge; nLarge++)
                {
                    // Force the solution to the target set of values
                    var c1 = model.AddConstr(xS == nSmall, $"xS_Equals_{nSmall}");
                    var c2 = model.AddConstr(xL == nLarge, $"xL_Equals_{nLarge}");
                    model.Update();

                    // See if the solution is feasible with those values
                    model.Optimize();
                    if (model.IsFeasible())
                    {
                        results.Add(new ProductionTarget()
                        {
                            Small = nSmall, Large = nLarge
                        });
                    }

                    model.Remove(c1);
                    model.Remove(c2);
                    model.Update();
                }
            }

            return(results);
        }