Example #1
0
    static void Main()
    {
        try {
            // Sample data
            int groundSetSize = 20;
            int nSubsets      = 4;
            int Budget        = 12;
            double[,] Set = new double[, ]
            {
                { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
                { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0 },
                { 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 }
            };
            int[]    SetObjPriority = new int[] { 3, 2, 2, 1 };
            double[] SetObjWeight = new double[] { 1.0, 0.25, 1.25, 1.0 };
            int      e, i, status, nSolutions;

            // Create environment
            GRBEnv env = new GRBEnv("multiobj_cs.log");

            // Create initial model
            GRBModel model = new GRBModel(env);
            model.ModelName = "multiobj_cs";

            // Initialize decision variables for ground set:
            // x[e] == 1 if element e is chosen for the covering.
            GRBVar[] Elem = model.AddVars(groundSetSize, GRB.BINARY);
            for (e = 0; e < groundSetSize; e++)
            {
                string vname = string.Format("El{0}", e);
                Elem[e].VarName = vname;
            }

            // Constraint: limit total number of elements to be picked to be at most
            // Budget
            GRBLinExpr lhs = new GRBLinExpr();
            for (e = 0; e < groundSetSize; e++)
            {
                lhs.AddTerm(1.0, Elem[e]);
            }
            model.AddConstr(lhs, GRB.LESS_EQUAL, Budget, "Budget");

            // Set global sense for ALL objectives
            model.ModelSense = GRB.MAXIMIZE;

            // Limit how many solutions to collect
            model.Parameters.PoolSolutions = 100;

            // Set and configure i-th objective
            for (i = 0; i < nSubsets; i++)
            {
                string     vname = string.Format("Set{0}", i);
                GRBLinExpr objn  = new GRBLinExpr();
                for (e = 0; e < groundSetSize; e++)
                {
                    objn.AddTerm(Set[i, e], Elem[e]);
                }

                model.SetObjectiveN(objn, i, SetObjPriority[i], SetObjWeight[i],
                                    1.0 + i, 0.01, vname);
            }

            // Save problem
            model.Write("multiobj_cs.lp");

            // Optimize
            model.Optimize();

            // Status checking
            status = model.Status;

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

            // Print best selected set
            Console.WriteLine("Selected elements in best solution:");
            Console.Write("\t");
            for (e = 0; e < groundSetSize; e++)
            {
                if (Elem[e].X < .9)
                {
                    continue;
                }
                Console.Write("El{0} ", e);
            }
            Console.WriteLine();

            // Print number of solutions stored
            nSolutions = model.SolCount;
            Console.WriteLine("Number of solutions found: {0}", nSolutions);

            // Print objective values of solutions
            if (nSolutions > 10)
            {
                nSolutions = 10;
            }
            Console.WriteLine("Objective values for first {0} solutions:", nSolutions);
            for (i = 0; i < nSubsets; i++)
            {
                model.Parameters.ObjNumber = i;

                Console.Write("\tSet" + i);
                for (e = 0; e < nSolutions; e++)
                {
                    model.Parameters.SolutionNumber = e;
                    Console.Write("{0,8}", model.ObjNVal);
                }
                Console.WriteLine();
            }
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code = {0}", e);
            Console.WriteLine(e.Message);
        }
    }
Example #2
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", "Tobi" };

            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 };

            // 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 },
                { 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1 },
                { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
            };

            // Create environment
            GRBEnv env = new GRBEnv();

            // Create initial model
            GRBModel model = new GRBModel(env);
            model.ModelName = "workforce5_cs";

            // Initialize assignment decision variables:
            // x[w][s] == 1 if worker w is assigned to shift s.
            // This is no longer a pure assignment model, so we must
            // use binary variables.
            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], 0, GRB.BINARY,
                                     string.Format("{0}.{1}", Workers[w], Shifts[s]));
                }
            }

            // Slack variables for each shift constraint so that the shifts can
            // be satisfied
            GRBVar[] slacks = new GRBVar[nShifts];
            for (int s = 0; s < nShifts; ++s)
            {
                slacks[s] =
                    model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS,
                                 string.Format("{0}Slack", Shifts[s]));
            }

            // Variable to represent the total slack
            GRBVar totSlack = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS,
                                           "totSlack");

            // Variables to count the total shifts worked by each worker
            GRBVar[] totShifts = new GRBVar[nWorkers];
            for (int w = 0; w < nWorkers; ++w)
            {
                totShifts[w] = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS,
                                            string.Format("{0}TotShifts", Workers[w]));
            }

            GRBLinExpr lhs;

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

            // Constraint: set totSlack equal to the total slack
            lhs = new GRBLinExpr();
            lhs.AddTerm(-1.0, totSlack);
            for (int s = 0; s < nShifts; ++s)
            {
                lhs.AddTerm(1.0, slacks[s]);
            }
            model.AddConstr(lhs, GRB.EQUAL, 0, "totSlack");

            // Constraint: compute the total number of shifts for each worker
            for (int w = 0; w < nWorkers; ++w)
            {
                lhs = new GRBLinExpr();
                lhs.AddTerm(-1.0, totShifts[w]);
                for (int s = 0; s < nShifts; ++s)
                {
                    lhs.AddTerm(1.0, x[w, s]);
                }
                model.AddConstr(lhs, GRB.EQUAL, 0, string.Format("totShifts{0}", Workers[w]));
            }

            // Constraint: set minShift/maxShift variable to less <=/>= to the
            // number of shifts among all workers
            GRBVar minShift = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS,
                                           "minShift");
            GRBVar maxShift = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS,
                                           "maxShift");
            model.AddGenConstrMin(minShift, totShifts, GRB.INFINITY, "minShift");
            model.AddGenConstrMax(maxShift, totShifts, -GRB.INFINITY, "maxShift");

            // Set global sense for ALL objectives
            model.ModelSense = GRB.MINIMIZE;

            // Set primary objective
            model.SetObjectiveN(totSlack, 0, 2, 1.0, 2.0, 0.1, "TotalSlack");

            // Set secondary objective
            model.SetObjectiveN(maxShift - minShift, 1, 1, 1.0, 0, 0, "Fairness");

            // Save problem
            model.Write("workforce5_cs.lp");

            // Optimize
            int status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts);

            if (status != GRB.Status.OPTIMAL)
            {
                return;
            }

            // Dispose of model and environment
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: {0}. {1}", e.ErrorCode, e.Message);
        }
    }