Example #1
0
        static void Main(string[] args)
        {
            GRBEnv   env = new GRBEnv();
            GRBModel m   = new GRBModel(env);
            GRBVar   x1  = m.AddVar(0, GRB.INFINITY, 20, GRB.CONTINUOUS, "food.1");
            GRBVar   x2  = m.AddVar(0, GRB.INFINITY, 10, GRB.CONTINUOUS, "food.2");
            GRBVar   x3  = m.AddVar(0, GRB.INFINITY, 31, GRB.CONTINUOUS, "food.3");
            GRBVar   x4  = m.AddVar(0, GRB.INFINITY, 11, GRB.CONTINUOUS, "food.4");
            GRBVar   x5  = m.AddVar(0, GRB.INFINITY, 12, GRB.CONTINUOUS, "food.5");

            m.Update();
            GRBConstr con1 = m.AddConstr(2 * x1 + 3 * x3 + 1 * x4 + 2 * x5 >= 21, "nutrient.iron");
            GRBConstr con2 = m.AddConstr(1 * x2 + 2 * x3 + 2 * x4 + 1 * x5 >= 12, "nutrient.calcium");

            m.Optimize();
            m.Write("diet.lp");
            foreach (GRBVar var in m.GetVars())
            {
                Console.WriteLine("{0} = {1}, reduced cost = {2}", var.Get(GRB.StringAttr.VarName), var.Get(GRB.DoubleAttr.X), var.Get(GRB.DoubleAttr.RC));
            }
            foreach (GRBConstr constr in m.GetConstrs())
            {
                Console.WriteLine("{0}, slack = {1}, pi = {2}", constr.Get(GRB.StringAttr.ConstrName), constr.Get(GRB.DoubleAttr.Slack), constr.Get(GRB.DoubleAttr.Pi));
            }
            m.Dispose();
            env.Dispose();
        }
        //ADD NEW VARIABLE TO CONSTRAINT
        //Constraint is selected
        private void cmbCon_SelectedIndexChanged(object sender, EventArgs e)
        {
            constraint = ((KeyValuePair <string, GRBConstr>)cmbCon.SelectedItem).Value;

            ///////////////////////////////////////////////////////////////////
            //display variables that are not in constraint already

            /*GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint);
             * GRBVar[] allVar = MyGlobals.model.GetVars();
             *
             * Dictionary<string, GRBVar> D = new Dictionary<string, GRBVar>();
             * for (int i = 0; i < allVar.Length; i++)
             * {
             *  for (int j = 0; j < con_info.Size; j++)
             *  {
             *      if (allVar[i].Get(GRB.StringAttr.VarName) == con_info.GetVar(i).Get(GRB.StringAttr.VarName))
             *          continue;
             *
             *      D.Add(allVar[i].Get(GRB.StringAttr.VarName), allVar[i]);
             *  }
             *
             * }*/
            GRBVar[] allVar = MyGlobals.model.GetVars();
            Dictionary <string, GRBVar> D = new Dictionary <string, GRBVar>();

            for (int i = 0; i < allVar.Length; i++)
            {
                D.Add(allVar[i].Get(GRB.StringAttr.VarName), allVar[i]);
            }
            // Bind combobox(add new var) to dictionary
            cmbAddVar.DataSource    = new BindingSource(D, null);
            cmbAddVar.DisplayMember = "Key";
            cmbAddVar.ValueMember   = "Value";
            ////////////////////////////////////////////////////////////////////
        }
Example #3
0
        static void SolveDual3(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs)
        {
            GRBModel dual = new GRBModel(env);
            Dictionary <string, GRBConstr> flow_balance  = new Dictionary <string, GRBConstr>();
            Dictionary <Arc, GRBVar>       arc_traversed = new Dictionary <Arc, GRBVar>();

            GRBConstr[] constrs = dual.AddConstrs(nodes_set.Count);
            dual.Update();

            int i = 0;

            foreach (string s in nodes_set)
            {
                GRBConstr con = constrs[i];
                con.Set(GRB.StringAttr.ConstrName, "flow_balance." + s);
                con.Set(GRB.CharAttr.Sense, GRB.EQUAL);
                flow_balance[s] = con;
                ++i;
            }
            flow_balance[ORIGIN].Set(GRB.DoubleAttr.RHS, -1);
            flow_balance[DESTINATION].Set(GRB.DoubleAttr.RHS, 1);

            foreach (Arc a in arcs)
            {
                GRBColumn col = new GRBColumn();
                col.AddTerm(1, flow_balance[a.dest]);
                col.AddTerm(-1, flow_balance[a.source]);
                arc_traversed[a] = dual.AddVar(0, 1, a.length, GRB.CONTINUOUS, col, "arc_traversed." + a.source + "." + a.dest);
            }
            dual.Optimize();
            dual.Write("dual3.lp");
            dual.Write("dual3.sol");
            dual.Dispose();
        }
        bool SolveMaster()
        {
            _grbModel.Optimize();
            int status   = _grbModel.Get(GRB.IntAttr.Status);
            int solution = _grbModel.Get(GRB.IntAttr.SolCount);

            if (status == GRB.Status.OPTIMAL || (status == GRB.Status.TIME_LIMIT && solution > 0))
            {
                foreach (Node n in Data.NodeSet)
                {
                    GRBConstr constr = _grbModel.GetConstrByName("ct1_" + n.ID);
                    Dual[n] = constr.Get(GRB.DoubleAttr.Pi);
                    n.ParseSolution(2);
                    n.ParseSolution(1);
                }
                foreach (Arc a in Data.ArcSet)
                {
                    a.ParseSolution();
                }

                double k0 = _grbModel.GetVarByName("k_0").Get(GRB.DoubleAttr.X);
                double k1 = _grbModel.GetVarByName("k_1").Get(GRB.DoubleAttr.X);

                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #5
0
    static void Main(string[] args)
    {
        if (args.Length < 1)
        {
            Console.Out.WriteLine("Usage: feasopt_cs filename");
            return;
        }

        try {
            GRBEnv   env       = new GRBEnv();
            GRBModel feasmodel = new GRBModel(env, args[0]);

            // Create a copy to use FeasRelax feature later */
            GRBModel feasmodel1 = new GRBModel(feasmodel);

            // Clear objective
            feasmodel.SetObjective(new GRBLinExpr());

            // Add slack variables
            GRBConstr[] c = feasmodel.GetConstrs();
            for (int i = 0; i < c.Length; ++i)
            {
                char sense = c[i].Get(GRB.CharAttr.Sense);
                if (sense != '>')
                {
                    GRBConstr[] constrs = new GRBConstr[] { c[i] };
                    double[]    coeffs  = new double[] { -1 };
                    feasmodel.AddVar(0.0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, constrs,
                                     coeffs, "ArtN_" + c[i].Get(GRB.StringAttr.ConstrName));
                }
                if (sense != '<')
                {
                    GRBConstr[] constrs = new GRBConstr[] { c[i] };
                    double[]    coeffs  = new double[] { 1 };
                    feasmodel.AddVar(0.0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, constrs,
                                     coeffs, "ArtP_" +
                                     c[i].Get(GRB.StringAttr.ConstrName));
                }
            }
            feasmodel.Update();

            // Optimize modified model
            feasmodel.Write("feasopt.lp");
            feasmodel.Optimize();

            // Use FeasRelax feature */
            feasmodel1.FeasRelax(GRB.FEASRELAX_LINEAR, true, false, true);
            feasmodel1.Write("feasopt1.lp");
            feasmodel1.Optimize();

            // Dispose of model and env
            feasmodel1.Dispose();
            feasmodel.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
        }
    }
Example #6
0
    static void Main(string[] args)
    {
        if (args.Length < 1) {
          Console.Out.WriteLine("Usage: feasopt_cs filename");
          return;
        }

        try {
          GRBEnv env = new GRBEnv();
          GRBModel feasmodel = new GRBModel(env, args[0]);

          // Create a copy to use FeasRelax feature later */
          GRBModel feasmodel1 = new GRBModel(feasmodel);

          // Clear objective
          feasmodel.SetObjective(new GRBLinExpr());

          // Add slack variables
          GRBConstr[] c = feasmodel.GetConstrs();
          for (int i = 0; i < c.Length; ++i) {
        char sense = c[i].Get(GRB.CharAttr.Sense);
        if (sense != '>') {
          GRBConstr[] constrs = new GRBConstr[] { c[i] };
          double[] coeffs = new double[] { -1 };
          feasmodel.AddVar(0.0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, constrs,
                           coeffs, "ArtN_" + c[i].Get(GRB.StringAttr.ConstrName));
        }
        if (sense != '<') {
          GRBConstr[] constrs = new GRBConstr[] { c[i] };
          double[] coeffs = new double[] { 1 };
          feasmodel.AddVar(0.0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, constrs,
                           coeffs, "ArtP_" +
                               c[i].Get(GRB.StringAttr.ConstrName));
        }
          }
          feasmodel.Update();

          // Optimize modified model
          feasmodel.Write("feasopt.lp");
          feasmodel.Optimize();

          // Use FeasRelax feature */
          feasmodel1.FeasRelax(GRB.FEASRELAX_LINEAR, true, false, true);
          feasmodel1.Write("feasopt1.lp");
          feasmodel1.Optimize();

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

        } catch (GRBException e) {
          Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
        }
    }
Example #7
0
        private void GetDual()
        {
            SchemeDualValue = _grbModelMaster.GetConstrByName("ct1").Pi;
            FADualValue     = _grbModelMaster.GetConstrByName("ct2").Pi;

            DualSolution.Clear();
            foreach (Node n in Data.NodeSet)
            {
                GRBConstr constr    = _grbModelMaster.GetConstrByName("ct3_" + n.ID);
                double    dualValue = constr.Pi;
                DualSolution.Add(n, dualValue);
            }
        }
Example #8
0
 public Column And(Column col)
 {
     if (col.objCoefSet)
     {
         this.objCoef = col.objCoef;
     }
     // for each constraint in col.column, add it to this.column
     double[] coefs = new double[col.column.Size];
     GRBConstr[] constrs = new GRBConstr[col.column.Size];
     for (int i = 0; i < col.column.Size; i++)
     {
         coefs[i] = col.column.GetCoeff(i);
         constrs[i] = col.column.GetConstr(i);
     }
     this.column.AddTerms(coefs, constrs);
     return this;
 }
Example #9
0
        static void SolvePrimal(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs)
        {
            GRBModel m = new GRBModel(env);

            Dictionary <string, GRBVar> distances = new Dictionary <string, GRBVar>(); // pi

            foreach (string node in nodes_set)
            {
                distances[node] = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "distance." + node);
            }
            m.Update();
            distances[ORIGIN].Set(GRB.DoubleAttr.Obj, -1);
            distances[DESTINATION].Set(GRB.DoubleAttr.Obj, 1);
            m.Set(GRB.IntAttr.ModelSense, -1);

            Dictionary <Arc, GRBConstr> constrs = new Dictionary <Arc, GRBConstr>();

            foreach (Arc a in arcs)
            {
                constrs[a] = m.AddConstr(distances[a.dest] <= distances[a.source] + a.length, "distance_con." + a.source + "." + a.dest);
            }

            m.Update();
            m.Write("shortest_path.lp");
            m.Optimize();

            foreach (var pair in distances)
            {
                Console.WriteLine("distance to {0} is {1}", pair.Key, pair.Value.Get(GRB.DoubleAttr.X));
            }

            foreach (var pair in constrs)
            {
                GRBConstr con = pair.Value;
                if (con.Get(GRB.DoubleAttr.Pi) > 0.5)
                {
                    Console.WriteLine("Arc {0}, {1} is in shortest path", pair.Key.source, pair.Key.dest);
                }
            }
            Console.WriteLine("Length of shortest path is {0}", m.Get(GRB.DoubleAttr.ObjVal));
            m.Dispose();
        }
        //DELETE Variable
        private void cmbCon5_SelectedIndexChanged(object sender, EventArgs e)
        {
            constraint = ((KeyValuePair <string, GRBConstr>)cmbCon5.SelectedItem).Value;
            GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint);

            Dictionary <string, GRBVar> D = new Dictionary <string, GRBVar>();
            GRBVar var;

            for (int i = 0; i < con_info.Size; i++)
            {
                var = con_info.GetVar(i);
                D.Add(con_info.GetVar(i).Get(GRB.StringAttr.VarName), var);
            }


            // Bind combobox(delete var) to dictionary
            cmbVarName3.DataSource    = new BindingSource(D, null);
            cmbVarName3.DisplayMember = "Key";
            cmbVarName3.ValueMember   = "Value";
        }
        //Add variable
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            {
                try
                {
                    //change GRBConst into GRBConst[]
                    GRBConstr[] CON = new GRBConstr[1];
                    CON[0] = constraint;

                    double var_coco;
                    double.TryParse(txtAddCon.Text, out var_coco);
                    //change double into double[]
                    Double[] COEFF = new Double[1];
                    COEFF[0] = var_coco;

                    //add variable to constraint
                    MyGlobals.model.ChgCoeff(constraint, variable, var_coco);


                    MyGlobals.model.Update();
                    populate_cmbConstraint();
                    BtnOK.Enabled     = true;
                    BtnCancel.Enabled = false;

                    lblUpdate.Text = "";
                    lblUpdate.Text = constraint.Get(GRB.StringAttr.ConstrName) + ": ";

                    GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint);

                    for (int n = 0; n < con_info.Size; n++)
                    {
                        lblUpdate.Text += " " + con_info.GetCoeff(n) + con_info.GetVar(n).Get(GRB.StringAttr.VarName) + " +";
                    }
                    lblUpdate.Text += " " + constraint.Get(GRB.CharAttr.Sense) + " " + constraint.Get(GRB.DoubleAttr.RHS) + "\n";
                }
                catch (GRBException exc)
                {
                    MessageBox.Show("Error code: " + exc.ErrorCode + ". " + exc.Message, "Error occured", MessageBoxButtons.OK);
                }
            }
        }
Example #12
0
 public void getOldList(GRBModel model, GRBConstr constr)
 {
     model.Update();
     GRBLinExpr linExpr = model.GetRow(constr);
     oldDict = new Dictionary<GRBVar, double>();
     for (int i = 0; i < linExpr.Size; i++)
     {
         GRBVar var = linExpr.GetVar(i);
         double val = linExpr.GetCoeff(i);
         if (oldDict.ContainsKey(var))
         {
             oldDict[var] += val;
         }
         else
         {
             oldDict[var] = val;
         }
     }
     constrs = new GRBConstr[1];
     constrs[0] = constr;
 }
 //EDIT RHS
 private void cmbCon4_SelectedIndexChanged(object sender, EventArgs e)
 {
     constraint = ((KeyValuePair <string, GRBConstr>)cmbCon4.SelectedItem).Value;
 }
        //new variable is added to constraint
        private void btnAdd_Click(object sender, EventArgs e)
        {
            try
            {
                string var_name = txtVarName.Text;
                string var_type = this.cmbVarType.GetItemText(this.cmbVarType.SelectedItem);

                double var_lb, var_ub;
                double var_obco, var_coco;
                double.TryParse(txtlb.Text, out var_lb);
                double.TryParse(txtub.Text, out var_ub);
                double.TryParse(txtObCo.Text, out var_obco);
                double.TryParse(txtCo_coeff.Text, out var_coco);

                //change GRBConst into GRBConst[]
                GRBConstr[] CON = new GRBConstr[1];
                CON[0] = constraint;


                //change double into double[]
                Double[] COEFF = new Double[1];
                COEFF[0] = var_coco;

                GRBVar x;
                switch (var_type)
                {
                case "BINARY":
                    if (use_infinite_ub == false)
                    {
                        x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'B', CON, COEFF, var_name);
                    }
                    else
                    {
                        x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'B', CON, COEFF, var_name);
                    }
                    break;


                case "CONTINUOUS":
                    if (use_infinite_ub == false)
                    {
                        x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'C', CON, COEFF, var_name);
                    }
                    else
                    {
                        x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'C', CON, COEFF, var_name);
                    }
                    break;

                case "INTERGER":
                    if (use_infinite_ub == false)
                    {
                        x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'I', CON, COEFF, var_name);
                    }
                    else
                    {
                        x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'I', CON, COEFF, var_name);
                    }
                    break;

                case "SEMI-CONTINUOUS":
                    if (use_infinite_ub == false)
                    {
                        x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'S', CON, COEFF, var_name);
                    }
                    else
                    {
                        x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'S', CON, COEFF, var_name);
                    }
                    break;

                case "SEMI-INTERGER":
                    if (use_infinite_ub == false)
                    {
                        x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'N', CON, COEFF, var_name);
                    }
                    else
                    {
                        x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'N', CON, COEFF, var_name);
                    }
                    break;
                }
                MyGlobals.model.Update();
                populate_cmbConstraint();
                BtnOK.Enabled     = true;
                BtnCancel.Enabled = false;

                lblUpdate.Text = "";
                lblUpdate.Text = constraint.Get(GRB.StringAttr.ConstrName) + ": ";

                GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint);

                for (int n = 0; n < con_info.Size; n++)
                {
                    lblUpdate.Text += " " + con_info.GetCoeff(n) + con_info.GetVar(n).Get(GRB.StringAttr.VarName) + " +";
                }
                lblUpdate.Text += " " + constraint.Get(GRB.CharAttr.Sense) + " " + constraint.Get(GRB.DoubleAttr.RHS) + "\n";
            }
            catch (GRBException exc)
            {
                MessageBox.Show("Error code: " + exc.ErrorCode + ". " + exc.Message, "Error occured", MessageBoxButtons.OK);
            }
            txtVarName.Clear();
            txtlb.Clear();
            txtub.Clear();
        }
        static void Main(string[] args)
        {
            double[] Demand   = new double[] { 15, 18, 14, 20 };
            double[] Capacity = new double[] { 20, 22, 17, 19, 18 };
            double[,] ShipCosts =
                new double[, ] {
                { 4000, 2500, 1200, 2200 },
                { 2000, 2600, 1800, 2600 },
                { 3000, 3400, 2600, 3100 },
                { 2500, 3000, 4100, 3700 },
                { 4500, 4000, 3000, 3200 }
            };
            int nWarehouses = Capacity.Length;
            int nCustomers  = Demand.Length;

            GRBEnv   env = new GRBEnv();
            GRBModel m   = new GRBModel(env);

            GRBVar[,] Ship = new GRBVar[nWarehouses, nCustomers];
            for (int i = 0; i < nWarehouses; ++i)
            {
                for (int j = 0; j < nCustomers; ++j)
                {
                    Ship[i, j] = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "ship." + i + "." + j);
                }
            }

            GRBVar[] Shortage = new GRBVar[nCustomers];
            for (int j = 0; j < nCustomers; ++j)
            {
                Shortage[j] = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "shortage." + j);
            }

            GRBVar TotalShortage     = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "TotalShortage");
            GRBVar TotalShippingCost = m.AddVar(0, GRB.INFINITY, 1, GRB.CONTINUOUS, "TotalShippingCost");

            m.Update();

            GRBConstr[] DemandCon = new GRBConstr[nCustomers];
            for (int j = 0; j < nCustomers; ++j)
            {
                GRBLinExpr lhs = 0.0;
                for (int i = 0; i < nWarehouses; ++i)
                {
                    lhs += Ship[i, j];
                }
                DemandCon[j] = m.AddConstr(lhs == Demand[j] - Shortage[j], "demand." + j);
            }

            GRBConstr[] CapacityCon = new GRBConstr[nWarehouses];
            for (int i = 0; i < nWarehouses; ++i)
            {
                GRBLinExpr lhs = 0.0;
                for (int j = 0; j < nCustomers; ++j)
                {
                    lhs += Ship[i, j];
                }
                CapacityCon[i] = m.AddConstr(lhs <= Capacity[i], "capacity." + i);
            }

            GRBLinExpr expr = 0.0;

            for (int j = 0; j < nCustomers; ++j)
            {
                expr += Shortage[j];
            }
            GRBConstr TotalShortageCon = m.AddConstr(expr == TotalShortage, "total_shortage");

            expr = 0.0;
            for (int i = 0; i < nWarehouses; ++i)
            {
                for (int j = 0; j < nCustomers; ++j)
                {
                    expr += ShipCosts[i, j] * Ship[i, j];
                }
            }
            GRBConstr TotalShippingCon = m.AddConstr(expr == TotalShippingCost, "total_shipping");

            while (true)
            {
                m.Optimize();
                double OptShortage = TotalShortage.Get(GRB.DoubleAttr.X);
                double OptShipping = TotalShippingCost.Get(GRB.DoubleAttr.X);
                Console.WriteLine("TotalShortage = {0}", OptShortage);
                Console.WriteLine("TotalShippingCost= {0}", OptShipping);
                if (OptShortage < EPS)
                {
                    break;
                }
                double ObjectiveBound = TotalShortage.Get(GRB.DoubleAttr.SAObjUp);
                TotalShortage.Set(GRB.DoubleAttr.Obj, ((1 + EPS) * ObjectiveBound));
            }
        }
Example #16
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
            LinkedList <GRBConstr> reqCts = new LinkedList <GRBConstr>();
            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]);
                }
                GRBConstr newCt =
                    model.AddConstr(lhs == shiftRequirements[s], Shifts[s]);
                reqCts.AddFirst(newCt);
            }

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

            // Add slack variables to make the model feasible
            Console.WriteLine("The model is infeasible; adding slack variables");

            // Set original objective coefficients to zero
            model.SetObjective(new GRBLinExpr());

            // Add a new slack variable to each shift constraint so that the shifts
            // can be satisfied
            LinkedList <GRBVar> slacks = new LinkedList <GRBVar>();
            foreach (GRBConstr c in reqCts)
            {
                GRBColumn col = new GRBColumn();
                col.AddTerm(1.0, c);
                GRBVar newvar =
                    model.AddVar(0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, col,
                                 c.Get(GRB.StringAttr.ConstrName) + "Slack");
                slacks.AddFirst(newvar);
            }

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

            Console.WriteLine("\nSlack values:");
            foreach (GRBVar sv in slacks)
            {
                if (sv.Get(GRB.DoubleAttr.X) > 1e-6)
                {
                    Console.WriteLine(sv.Get(GRB.StringAttr.VarName) + " = " +
                                      sv.Get(GRB.DoubleAttr.X));
                }
            }

            // Dispose of model and env
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " +
                              e.Message);
        }
    }
Example #17
0
 public double GetDual(IRange rng)
 {
     GRBConstr[] grbConstrs = new GRBConstr[1];
     grbConstrs[0] = rng.GetConstr();
     double result = _model.Get(GRB.DoubleAttr.Pi, grbConstrs)[0];
     return result;
 }
Example #18
0
 public double[] GetDuals(IRange[] rng)
 {
     double[] result = new double[rng.Length];
     GRBConstr[] grbConstrs = new GRBConstr[rng.Length];
     for (int i = 0; i < rng.Length; i++)
     {
         grbConstrs[i] = rng[i].GetConstr();
     }
     result = _model.Get(GRB.DoubleAttr.Pi, grbConstrs);
     return result;
 }
Example #19
0
    static void Main()
    {
        try {
            // Warehouse demand in thousands of units
            double[] Demand = new double[] { 15, 18, 14, 20 };

            // Plant capacity in thousands of units
            double[] Capacity = new double[] { 20, 22, 17, 19, 18 };

            // Fixed costs for each plant
            double[] FixedCosts =
                new double[] { 12000, 15000, 17000, 13000, 16000 };

            // Transportation costs per thousand units
            double[,] TransCosts =
                new double[, ] {
                { 4000, 2000, 3000, 2500, 4500 },
                { 2500, 2600, 3400, 3000, 4000 },
                { 1200, 1800, 2600, 4100, 3000 },
                { 2200, 2600, 3100, 3700, 3200 }
            };

            // Number of plants and warehouses
            int nPlants     = Capacity.Length;
            int nWarehouses = Demand.Length;

            double maxFixed = -GRB.INFINITY;
            double minFixed = GRB.INFINITY;
            for (int p = 0; p < nPlants; ++p)
            {
                if (FixedCosts[p] > maxFixed)
                {
                    maxFixed = FixedCosts[p];
                }

                if (FixedCosts[p] < minFixed)
                {
                    minFixed = FixedCosts[p];
                }
            }

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

            model.ModelName = "multiscenario";

            // Plant open decision variables: open[p] == 1 if plant p is open.
            GRBVar[] open = new GRBVar[nPlants];
            for (int p = 0; p < nPlants; ++p)
            {
                open[p] = model.AddVar(0, 1, FixedCosts[p], GRB.BINARY, "Open" + p);
            }

            // Transportation decision variables: how much to transport from
            // a plant p to a warehouse w
            GRBVar[,] transport = new GRBVar[nWarehouses, nPlants];
            for (int w = 0; w < nWarehouses; ++w)
            {
                for (int p = 0; p < nPlants; ++p)
                {
                    transport[w, p] = model.AddVar(0, GRB.INFINITY, TransCosts[w, p],
                                                   GRB.CONTINUOUS, "Trans" + p + "." + w);
                }
            }

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

            // Production constraints
            // Note that the right-hand limit sets the production to zero if
            // the plant is closed
            for (int p = 0; p < nPlants; ++p)
            {
                GRBLinExpr ptot = 0.0;
                for (int w = 0; w < nWarehouses; ++w)
                {
                    ptot.AddTerm(1.0, transport[w, p]);
                }
                model.AddConstr(ptot <= Capacity[p] * open[p], "Capacity" + p);
            }

            // Demand constraints
            GRBConstr[] demandConstr = new GRBConstr[nWarehouses];
            for (int w = 0; w < nWarehouses; ++w)
            {
                GRBLinExpr dtot = 0.0;
                for (int p = 0; p < nPlants; ++p)
                {
                    dtot.AddTerm(1.0, transport[w, p]);
                }
                demandConstr[w] = model.AddConstr(dtot == Demand[w], "Demand" + w);
            }

            // We constructed the base model, now we add 7 scenarios
            //
            // Scenario 0: Represents the base model, hence, no manipulations.
            // Scenario 1: Manipulate the warehouses demands slightly (constraint right
            //             hand sides).
            // Scenario 2: Double the warehouses demands (constraint right hand sides).
            // Scenario 3: Manipulate the plant fixed costs (objective coefficients).
            // Scenario 4: Manipulate the warehouses demands and fixed costs.
            // Scenario 5: Force the plant with the largest fixed cost to stay open
            //             (variable bounds).
            // Scenario 6: Force the plant with the smallest fixed cost to be closed
            //             (variable bounds).

            model.NumScenarios = 7;

            // Scenario 0: Base model, hence, nothing to do except giving the
            //             scenario a name
            model.Parameters.ScenarioNumber = 0;
            model.ScenNName = "Base model";

            // Scenario 1: Increase the warehouse demands by 10%
            model.Parameters.ScenarioNumber = 1;
            model.ScenNName = "Increased warehouse demands";

            for (int w = 0; w < nWarehouses; w++)
            {
                demandConstr[w].ScenNRHS = Demand[w] * 1.1;
            }

            // Scenario 2: Double the warehouse demands
            model.Parameters.ScenarioNumber = 2;
            model.ScenNName = "Double the warehouse demands";

            for (int w = 0; w < nWarehouses; w++)
            {
                demandConstr[w].ScenNRHS = Demand[w] * 2.0;
            }

            // Scenario 3: Decrease the plant fixed costs by 5%
            model.Parameters.ScenarioNumber = 3;
            model.ScenNName = "Decreased plant fixed costs";

            for (int p = 0; p < nPlants; p++)
            {
                open[p].ScenNObj = FixedCosts[p] * 0.95;
            }

            // Scenario 4: Combine scenario 1 and scenario 3 */
            model.Parameters.ScenarioNumber = 4;
            model.ScenNName = "Increased warehouse demands and decreased plant fixed costs";

            for (int w = 0; w < nWarehouses; w++)
            {
                demandConstr[w].ScenNRHS = Demand[w] * 1.1;
            }
            for (int p = 0; p < nPlants; p++)
            {
                open[p].ScenNObj = FixedCosts[p] * 0.95;
            }

            // Scenario 5: Force the plant with the largest fixed cost to stay
            //             open
            model.Parameters.ScenarioNumber = 5;
            model.ScenNName = "Force plant with largest fixed cost to stay open";

            for (int p = 0; p < nPlants; p++)
            {
                if (FixedCosts[p] == maxFixed)
                {
                    open[p].ScenNLB = 1.0;
                    break;
                }
            }

            // Scenario 6: Force the plant with the smallest fixed cost to be
            //             closed
            model.Parameters.ScenarioNumber = 6;
            model.ScenNName = "Force plant with smallest fixed cost to be closed";

            for (int p = 0; p < nPlants; p++)
            {
                if (FixedCosts[p] == minFixed)
                {
                    open[p].ScenNUB = 0.0;
                    break;
                }
            }

            // Guess at the starting point: close the plant with the highest
            // fixed costs; open all others

            // First, open all plants
            for (int p = 0; p < nPlants; ++p)
            {
                open[p].Start = 1.0;
            }

            // Now close the plant with the highest fixed cost
            Console.WriteLine("Initial guess:");
            for (int p = 0; p < nPlants; ++p)
            {
                if (FixedCosts[p] == maxFixed)
                {
                    open[p].Start = 0.0;
                    Console.WriteLine("Closing plant " + p + "\n");
                    break;
                }
            }

            // Use barrier to solve root relaxation
            model.Parameters.Method = GRB.METHOD_BARRIER;

            // Solve multi-scenario model
            model.Optimize();

            int nScenarios = model.NumScenarios;

            for (int s = 0; s < nScenarios; s++)
            {
                int modelSense = GRB.MINIMIZE;

                // Set the scenario number to query the information for this scenario
                model.Parameters.ScenarioNumber = s;

                // collect result for the scenario
                double scenNObjBound = model.ScenNObjBound;
                double scenNObjVal   = model.ScenNObjVal;

                Console.WriteLine("\n\n------ Scenario " + s
                                  + " (" + model.ScenNName + ")");

                // Check if we found a feasible solution for this scenario
                if (scenNObjVal >= modelSense * GRB.INFINITY)
                {
                    if (scenNObjBound >= modelSense * GRB.INFINITY)
                    {
                        // Scenario was proven to be infeasible
                        Console.WriteLine("\nINFEASIBLE");
                    }
                    else
                    {
                        // We did not find any feasible solution - should not happen in
                        // this case, because we did not set any limit (like a time
                        // limit) on the optimization process
                        Console.WriteLine("\nNO SOLUTION");
                    }
                }
                else
                {
                    Console.WriteLine("\nTOTAL COSTS: " + scenNObjVal);
                    Console.WriteLine("SOLUTION:");
                    for (int p = 0; p < nPlants; p++)
                    {
                        double scenNX = open[p].ScenNX;

                        if (scenNX > 0.5)
                        {
                            Console.WriteLine("Plant " + p + " open");
                            for (int w = 0; w < nWarehouses; w++)
                            {
                                scenNX = transport[w, p].ScenNX;

                                if (scenNX > 0.0001)
                                {
                                    Console.WriteLine("  Transport " + scenNX
                                                      + " units to warehouse " + w);
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine("Plant " + p + " closed!");
                        }
                    }
                }
            }

            // Print a summary table: for each scenario we add a single summary
            // line
            Console.WriteLine("\n\nSummary: Closed plants depending on scenario\n");
            Console.WriteLine("{0,8} | {1,17} {2,13}", "", "Plant", "|");

            Console.Write("{0,8} |", "Scenario");
            for (int p = 0; p < nPlants; p++)
            {
                Console.Write("{0,6}", p);
            }
            Console.WriteLine(" | {0,6}  Name", "Costs");

            for (int s = 0; s < nScenarios; s++)
            {
                int modelSense = GRB.MINIMIZE;

                // Set the scenario number to query the information for this scenario
                model.Parameters.ScenarioNumber = s;

                // Collect result for the scenario
                double scenNObjBound = model.ScenNObjBound;
                double scenNObjVal   = model.ScenNObjVal;

                Console.Write("{0,-8} |", s);

                // Check if we found a feasible solution for this scenario
                if (scenNObjVal >= modelSense * GRB.INFINITY)
                {
                    if (scenNObjBound >= modelSense * GRB.INFINITY)
                    {
                        // Scenario was proven to be infeasible
                        Console.WriteLine(" {0,-30}| {1,6}  " + model.ScenNName,
                                          "infeasible", "-");
                    }
                    else
                    {
                        // We did not find any feasible solution - should not happen in
                        // this case, because we did not set any limit (like a time
                        // limit) on the optimization process
                        Console.WriteLine(" {0,-30}| {1,6}  " + model.ScenNName,
                                          "no solution found", "-");
                    }
                }
                else
                {
                    for (int p = 0; p < nPlants; p++)
                    {
                        double scenNX = open[p].ScenNX;
                        if (scenNX > 0.5)
                        {
                            Console.Write("{0,6}", " ");
                        }
                        else
                        {
                            Console.Write("{0,6}", "x");
                        }
                    }

                    Console.WriteLine(" | {0,6}  " + model.ScenNName, scenNObjVal);
                }
            }

            // Dispose of model and env
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
        }
    }
 public static GRBConstr SetLazy(this GRBConstr constr, bool isLazy)
 {
     constr.Lazy = isLazy ? 1 : 0;
     return(constr);
 }