예제 #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);
        }
예제 #2
0
 public static void Remove(this GRBModel model, IEnumerable <GRBSOS> constraints)
 {
     foreach (var constraint in constraints)
     {
         model.Remove(constraint);
     }
 }
예제 #3
0
 public static void Remove(this GRBModel model, IEnumerable <GRBVar> variables)
 {
     foreach (var variable in variables)
     {
         model.Remove(variable);
     }
 }
예제 #4
0
        /// <summary>
        /// Basicly the same as DesiredOverlap but with unavailable
        /// </summary>
        /// <param name="model"></param>
        /// <param name="numberOfRoutes"></param>
        /// <param name="v"></param>
        /// <param name="w"></param>
        /// <param name="c"></param>
        /// <param name="unavailableDuration"></param>
        private void UnavailableOverlap(GRBModel model, int numberOfRoutes, GRBVar[][] v, GRBVar[][] w, GRBVar[][] c, GRBVar[][][] unavailableDuration, bool hardConstraint = false)
        {
            for (int s = 0; s < numberOfRoutes; s++)
            {
                var day = s / input.Santas.Length;
                var(dayStart, dayEnd) = input.Days[day];
                var dayDuration = dayEnd - dayStart;
                for (int i = 1; i < visitDurations.Length; i++)
                {
                    var visit = input.Visits[i - 1];
                    for (int d = 0; d < visit.Unavailable.Length; d++)
                    {
                        // check if unavailable is on this day
                        var(unavailableFrom, unavailableTo) = visit.Unavailable[d];

                        if (unavailableTo < dayStart || unavailableFrom > dayEnd)
                        {
                            model.Remove(unavailableDuration[s][i][d]);
                            unavailableDuration[s][i][d] = null;
                            //model.AddConstr(unavailableDuration[s][i][d] == 0, GurobiVarName($"unavailalbe[{s}][{i}][{d}] == 0, outside of day"));
                            continue;
                        }

                        // temp
                        if (hardConstraint)
                        {
                            model.AddConstr(unavailableDuration[s][i][d] == 0, GurobiVarName($"unavailalbe[{s}][{i}][{d}] == 0, hard constraint"));
                        }

                        var maxUnavailableDuration = Math.Min(visit.Duration, unavailableTo - unavailableFrom);
                        model.AddConstr(unavailableDuration[s][i][d] <= maxUnavailableDuration * v[s][i], GurobiVarName($"unavailable[{s}][{i}][{d}] only possible if v[{s}][{i}]"));

                        var unavailableStart = model.AddVar(unavailableFrom - dayStart, dayDuration, 0, GRB.CONTINUOUS, GurobiVarName($"unavailableStart[{s}][{i}][{d}]"));
                        var binHelperStart   = model.AddVar(0, 1, 0, GRB.BINARY, GurobiVarName($"binHelperUnavailableStart[{s}][{i}][{d}]"));

                        var visitStart = c[s][i];

                        model.AddConstr(unavailableStart >= visitStart, null);
                        model.AddGenConstrIndicator(binHelperStart, 0, unavailableStart <= unavailableFrom - dayStart, null);
                        model.AddGenConstrIndicator(binHelperStart, 1, unavailableStart <= visitStart, null);

                        var unavailableEnd = model.AddVar(0, unavailableTo - dayStart, 0, GRB.CONTINUOUS, GurobiVarName($"unavailableEnd[{s}][{i}][{d}]"));
                        var binHelperEnd   = model.AddVar(0, 1, 0, GRB.BINARY, GurobiVarName($"binHelperUnavailableEnd[{s}][{i}][{d}]"));

                        var visitEnd = visitStart + visit.Duration * v[s][i];

                        model.AddConstr(unavailableEnd <= visitEnd, GurobiVarName($"unavailableEnd[{s}[{i}][{d}] <= visitEnd"));
                        model.AddGenConstrIndicator(binHelperEnd, 0, unavailableEnd >= unavailableTo - dayStart, null);
                        model.AddGenConstrIndicator(binHelperEnd, 1, unavailableEnd >= visitEnd, null);

                        model.AddConstr(
                            unavailableDuration[s][i][d] >= unavailableEnd - unavailableStart,
                            GurobiVarName($"unavailable overlap[{s}][{i}][{d}]"));
                    }
                }
            }
        }
예제 #5
0
        public override bool DelConstraint(object solver, int row)
        {
            GRBModel model = solver as GRBModel;

            if (model == null)
            {
                return(false);
            }
            model.Remove(model.GetConstrs()[row]);
            model.Update();
            return(true);
        }
예제 #6
0
        public override bool DelColumn(object solver, int column)
        {
            GRBModel model = solver as GRBModel;

            if (model == null)
            {
                return(false);
            }
            model.Remove(model.GetVars()[column]);
            model.Update();
            return(true);
        }
예제 #7
0
        private void ChangeNBreaksGurobi(GRBModel pModel, GRBLinExpr pTotalStepsConst, GRBVar[] pDecVar, int intNClasses, int intNFeatures)
        {
            try
            {
                Cs    = new double[intNClasses + 1];
                cbIdx = new int[intNClasses + 1];                         // For Graph
                int intNDecVar = (intNFeatures * (intNFeatures + 1)) / 2; // Add L0_0

                pModel.Remove(pModel.GetConstrByName("Nsteps"));
                pModel.AddConstr(pTotalStepsConst, GRB.EQUAL, intNClasses, "Nsteps");

                //Solving
                pModel.Optimize();

                //Add Results to CS array
                Cs[0] = arrEst[0]; //Estimate Array was sorted
                int intIdxCs = 0;


                if (pModel.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL)
                {
                    for (int i = 0; i < intNDecVar; i++)
                    {
                        if (pDecVar[i].Get(GRB.DoubleAttr.X) == 1)
                        {
                            intIdxCs++;
                            string strName      = pDecVar[i].Get(GRB.StringAttr.VarName);
                            int    intIndexUBar = strName.IndexOf("_");
                            string strTo        = strName.Substring(intIndexUBar + 1);
                            int    intToValue   = Convert.ToInt16(strTo);
                            Cs[intIdxCs]    = arrEst[intToValue - 1]; //Closed
                            cbIdx[intIdxCs] = intToValue - 1;
                        }
                    }
                }

                txtObjValue.Text = pModel.Get(GRB.DoubleAttr.ObjVal).ToString("N5");
            }
            catch (Exception ex)
            {
                MessageBox.Show(this.Handle.ToString() + " Error:" + ex.Message);
                return;
            }
        }
예제 #8
0
        private void DesiredOverlap(GRBModel model, int numberOfRoutes, GRBVar[][] v, GRBVar[][] w, GRBVar[][] c, GRBVar[][][] desiredDuration)
        {
            for (int s = 0; s < numberOfRoutes; s++)
            {
                var day = s / input.Santas.Length;
                var(dayStart, dayEnd) = input.Days[day];
                var dayDuration = dayEnd - dayStart;
                for (int i = 1; i < visitDurations.Length; i++)
                {
                    var visit = input.Visits[i - 1];
                    for (int d = 0; d < visit.Desired.Length; d++)
                    {
                        var(desiredFrom, desiredTo) = visit.Desired[d];
                        // check if desired on day
                        if (desiredTo < dayStart || desiredFrom > dayEnd)
                        {
                            model.Remove(desiredDuration[s][i][d]);
                            desiredDuration[s][i][d] = null; //free up memory
                            //model.AddConstr(desiredDuration[s][i][d] == 0, GurobiVarName($"desiredDuration[{s}][{i}][{d}] == 0, outside of day"));
                            continue;
                        }

                        var maxDesiredDuration = Math.Min(visit.Duration, desiredTo - desiredFrom);
                        model.AddConstr(desiredDuration[s][i][d] <= maxDesiredDuration * v[s][i], GurobiVarName($"desired[{s}][{i}][{d}] only possible if v[{s}][{i}]"));

                        var desiredStart = model.AddVar(Math.Max(desiredFrom - dayStart, 0), dayDuration, 0, GRB.CONTINUOUS, GurobiVarName($"desiredStart[{s}][{i}][{d}]"));

                        model.AddConstr(desiredStart >= c[s][i], GurobiVarName($"desiredStart[{s}[{i}][{d}] >= visitStart"));

                        var desiredEnd = model.AddVar(0, desiredTo - dayStart, 0, GRB.CONTINUOUS, GurobiVarName($"desiredEnd[{s}][{i}][{d}]"));

                        model.AddConstr(desiredEnd <= c[s][i] + visit.Duration * v[s][i], GurobiVarName($"desiredEnd[{s}[{i}][{d}] <= visitEnd"));
                        var binDecisionVariable = model.AddVar(0, 1, 0, GRB.BINARY, GurobiVarName($"binDesiredDecisionVar[{s}][{i}][{d}]"));

                        // if positive, duration = end -start
                        model.AddGenConstrIndicator(binDecisionVariable, 0, desiredEnd - desiredStart >= 0, null);
                        model.AddGenConstrIndicator(binDecisionVariable, 0, desiredDuration[s][i][d] == desiredEnd - desiredStart, null);
                        // if negative, duration = 0
                        model.AddGenConstrIndicator(binDecisionVariable, 1, desiredEnd - desiredStart <= 0, null);
                        model.AddGenConstrIndicator(binDecisionVariable, 1, desiredDuration[s][i][d] == 0, null);
                    }
                }
            }
        }
예제 #9
0
    static void Main()
    {
        try {
            // Create environment

            GRBEnv env = new GRBEnv();

            // Create a new m

            GRBModel m = new GRBModel(env);

            double lb = 0.0, ub = GRB.INFINITY;

            GRBVar x = m.AddVar(lb, ub, 0.0, GRB.CONTINUOUS, "x");
            GRBVar y = m.AddVar(lb, ub, 0.0, GRB.CONTINUOUS, "y");
            GRBVar u = m.AddVar(lb, ub, 0.0, GRB.CONTINUOUS, "u");
            GRBVar v = m.AddVar(lb, ub, 0.0, GRB.CONTINUOUS, "v");

            // Set objective

            m.SetObjective(2 * x + y, GRB.MAXIMIZE);

            // Add linear constraint

            m.AddConstr(u + 4 * v <= 9, "l1");

            // Approach 1) PWL constraint approach

            double   intv = 1e-3;
            double   xmax = Math.Log(9.0);
            int      len  = (int)Math.Ceiling(xmax / intv) + 1;
            double[] xpts = new double[len];
            double[] upts = new double[len];
            for (int i = 0; i < len; i++)
            {
                xpts[i] = i * intv;
                upts[i] = f(i * intv);
            }
            GRBGenConstr gc1 = m.AddGenConstrPWL(x, u, xpts, upts, "gc1");

            double ymax = (9.0 / 4.0) * (9.0 / 4.0);
            len = (int)Math.Ceiling(ymax / intv) + 1;
            double[] ypts = new double[len];
            double[] vpts = new double[len];
            for (int i = 0; i < len; i++)
            {
                ypts[i] = i * intv;
                vpts[i] = g(i * intv);
            }
            GRBGenConstr gc2 = m.AddGenConstrPWL(y, v, ypts, vpts, "gc2");

            // Optimize the model and print solution

            m.Optimize();
            printsol(m, x, y, u, v);

            // Approach 2) General function constraint approach with auto PWL
            //             translation by Gurobi

            // restore unsolved state and get rid of PWL constraints
            m.Reset();
            m.Remove(gc1);
            m.Remove(gc2);
            m.Update();

            GRBGenConstr gcf1 = m.AddGenConstrExp(x, u, "gcf1", "");
            GRBGenConstr gcf2 = m.AddGenConstrPow(y, v, 0.5, "gcf2", "");

            m.Parameters.FuncPieceLength = 1e-3;

            // Optimize the model and print solution

            m.Optimize();
            printsol(m, x, y, u, v);

            // Zoom in, use optimal solution to reduce the ranges and use a smaller
            // pclen=1e-5 to solve it

            x.LB = Math.Max(x.LB, x.X - 0.01);
            x.UB = Math.Min(x.UB, x.X + 0.01);
            y.LB = Math.Max(y.LB, y.X - 0.01);
            y.UB = Math.Min(y.UB, y.X + 0.01);
            m.Update();
            m.Reset();

            m.Parameters.FuncPieceLength = 1e-5;

            // Optimize the model and print solution

            m.Optimize();
            printsol(m, x, y, u, v);

            // Dispose of model and environment

            m.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
        }
    }
    static void Main()
    {
        try {
            // Sample data
            // Sets of days and workers
            string[] Shifts =
                new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6",
                               "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13",
                               "Sun14" };
            string[] Workers =
                new string[] { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" };

            int nShifts  = Shifts.Length;
            int nWorkers = Workers.Length;

            // Number of workers required for each shift
            double[] shiftRequirements =
                new double[] { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 };

            // Amount each worker is paid to work one shift
            double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 };

            // Worker availability: 0 if the worker is unavailable for a shift
            double[,] availability =
                new double[, ] {
                { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
                { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
                { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
                { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
                { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 },
                { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 },
                { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
            };

            // Model
            GRBEnv   env   = new GRBEnv();
            GRBModel model = new GRBModel(env);

            model.ModelName = "assignment";

            // Assignment variables: x[w][s] == 1 if worker w is assigned
            // to shift s. Since an assignment model always produces integer
            // solutions, we use continuous variables and solve as an LP.
            GRBVar[,] x = new GRBVar[nWorkers, nShifts];
            for (int w = 0; w < nWorkers; ++w)
            {
                for (int s = 0; s < nShifts; ++s)
                {
                    x[w, s] =
                        model.AddVar(0, availability[w, s], pay[w], GRB.CONTINUOUS,
                                     Workers[w] + "." + Shifts[s]);
                }
            }

            // The objective is to minimize the total pay costs
            model.ModelSense = GRB.MINIMIZE;

            // Constraint: assign exactly shiftRequirements[s] workers
            // to each shift s
            for (int s = 0; s < nShifts; ++s)
            {
                GRBLinExpr lhs = 0.0;
                for (int w = 0; w < nWorkers; ++w)
                {
                    lhs.AddTerm(1.0, x[w, s]);
                }
                model.AddConstr(lhs == shiftRequirements[s], Shifts[s]);
            }

            // Optimize
            model.Optimize();
            int status = model.Status;
            if (status == GRB.Status.UNBOUNDED)
            {
                Console.WriteLine("The model cannot be solved "
                                  + "because it is unbounded");
                return;
            }
            if (status == GRB.Status.OPTIMAL)
            {
                Console.WriteLine("The optimal objective is " + model.ObjVal);
                return;
            }
            if ((status != GRB.Status.INF_OR_UNBD) &&
                (status != GRB.Status.INFEASIBLE))
            {
                Console.WriteLine("Optimization was stopped with status " + status);
                return;
            }

            // Do IIS
            Console.WriteLine("The model is infeasible; computing IIS");
            LinkedList <string> removed = new LinkedList <string>();

            // Loop until we reduce to a model that can be solved
            while (true)
            {
                model.ComputeIIS();
                Console.WriteLine("\nThe following constraint cannot be satisfied:");
                foreach (GRBConstr c in model.GetConstrs())
                {
                    if (c.IISConstr == 1)
                    {
                        Console.WriteLine(c.ConstrName);
                        // Remove a single constraint from the model
                        removed.AddFirst(c.ConstrName);
                        model.Remove(c);
                        break;
                    }
                }

                Console.WriteLine();
                model.Optimize();
                status = model.Status;

                if (status == GRB.Status.UNBOUNDED)
                {
                    Console.WriteLine("The model cannot be solved "
                                      + "because it is unbounded");
                    return;
                }
                if (status == GRB.Status.OPTIMAL)
                {
                    break;
                }
                if ((status != GRB.Status.INF_OR_UNBD) &&
                    (status != GRB.Status.INFEASIBLE))
                {
                    Console.WriteLine("Optimization was stopped with status " +
                                      status);
                    return;
                }
            }

            Console.WriteLine("\nThe following constraints were removed "
                              + "to get a feasible LP:");
            foreach (string s in removed)
            {
                Console.Write(s + " ");
            }
            Console.WriteLine();

            // Dispose of model and env
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " +
                              e.Message);
        }
    }
예제 #11
0
    static void Main()
    {
        try {

          // Sample data
          // Sets of days and workers
          string[] Shifts =
          new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6",
              "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13",
              "Sun14" };
          string[] Workers =
          new string[] { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" };

          int nShifts = Shifts.Length;
          int nWorkers = Workers.Length;

          // Number of workers required for each shift
          double[] shiftRequirements =
          new double[] { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 };

          // Amount each worker is paid to work one shift
          double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 };

          // Worker availability: 0 if the worker is unavailable for a shift
          double[,] availability =
          new double[,] { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
              { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
              { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
              { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
              { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 },
              { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 },
              { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };

          // Model
          GRBEnv env = new GRBEnv();
          GRBModel model = new GRBModel(env);
          model.Set(GRB.StringAttr.ModelName, "assignment");

          // Assignment variables: x[w][s] == 1 if worker w is assigned
          // to shift s. Since an assignment model always produces integer
          // solutions, we use continuous variables and solve as an LP.
          GRBVar[,] x = new GRBVar[nWorkers,nShifts];
          for (int w = 0; w < nWorkers; ++w) {
        for (int s = 0; s < nShifts; ++s) {
          x[w,s] =
              model.AddVar(0, availability[w,s], pay[w], GRB.CONTINUOUS,
                           Workers[w] + "." + Shifts[s]);
        }
          }

          // The objective is to minimize the total pay costs
          model.Set(GRB.IntAttr.ModelSense, 1);

          // Update model to integrate new variables
          model.Update();

          // Constraint: assign exactly shiftRequirements[s] workers
          // to each shift s
          for (int s = 0; s < nShifts; ++s) {
        GRBLinExpr lhs = 0.0;
        for (int w = 0; w < nWorkers; ++w)
          lhs += x[w, s];
        model.AddConstr(lhs == shiftRequirements[s], Shifts[s]);
          }

          // Optimize
          model.Optimize();
          int status = model.Get(GRB.IntAttr.Status);
          if (status == GRB.Status.UNBOUNDED) {
        Console.WriteLine("The model cannot be solved "
            + "because it is unbounded");
        return;
          }
          if (status == GRB.Status.OPTIMAL) {
        Console.WriteLine("The optimal objective is " +
            model.Get(GRB.DoubleAttr.ObjVal));
        return;
          }
          if ((status != GRB.Status.INF_OR_UNBD) &&
          (status != GRB.Status.INFEASIBLE)) {
        Console.WriteLine("Optimization was stopped with status " + status);
        return;
          }

          // Do IIS
          Console.WriteLine("The model is infeasible; computing IIS");
          LinkedList<string> removed = new LinkedList<string>();

          // Loop until we reduce to a model that can be solved
          while (true) {
        model.ComputeIIS();
        Console.WriteLine("\nThe following constraint cannot be satisfied:");
        foreach (GRBConstr c in model.GetConstrs()) {
          if (c.Get(GRB.IntAttr.IISConstr) == 1) {
            Console.WriteLine(c.Get(GRB.StringAttr.ConstrName));
            // Remove a single constraint from the model
            removed.AddFirst(c.Get(GRB.StringAttr.ConstrName));
            model.Remove(c);
            break;
          }
        }

        Console.WriteLine();
        model.Optimize();
        status = model.Get(GRB.IntAttr.Status);

        if (status == GRB.Status.UNBOUNDED) {
          Console.WriteLine("The model cannot be solved "
              + "because it is unbounded");
          return;
        }
        if (status == GRB.Status.OPTIMAL) {
          break;
        }
        if ((status != GRB.Status.INF_OR_UNBD) &&
            (status != GRB.Status.INFEASIBLE)) {
          Console.WriteLine("Optimization was stopped with status " +
              status);
          return;
        }
          }

          Console.WriteLine("\nThe following constraints were removed "
          + "to get a feasible LP:");
          foreach (string s in removed) {
        Console.Write(s + " ");
          }
          Console.WriteLine();

          // Dispose of model and env
          model.Dispose();
          env.Dispose();

        } catch (GRBException e) {
          Console.WriteLine("Error code: " + e.ErrorCode + ". " +
          e.Message);
        }
    }