protected override void AddGRBConstrPowerBalance()
 {
     this.NodalPowerBalance = new GRBConstr[MyPowerSystem.Nodes.Count];
     int load_shed_counter = 0;
     for (int i = 0; i < MyPowerSystem.Nodes.Count; i++)
     {
         Node node = MyPowerSystem.Nodes[i];
         GRBLinExpr powerBalanceLHS = new GRBLinExpr();
         foreach (GeneratingUnit gen in node.GeneratingUnits)
         {
             powerBalanceLHS.AddTerm(1, this.PGen[gen.Id]);
         }
         foreach (TransmissionLine tl in node.IncomingTransmissionLines)
         {
             powerBalanceLHS.AddTerm(+1, PFlow[PFlow_TLsIDs[tl.Id]]); //incoming power flow
         }
         foreach (TransmissionLine tl in node.OutgoingTransmissionLines)
         {
             powerBalanceLHS.AddTerm(-1, PFlow[PFlow_TLsIDs[tl.Id]]); //outgoing power flow
         }
         GRBLinExpr powerBalanceRHS = new GRBLinExpr();
         powerBalanceRHS.AddConstant(node.TotalLoad * LoadBlock.LoadMultiplier);
         if (node.TotalLoad > 0)
         {
             powerBalanceRHS.AddTerm(-1, LoadShed[load_shed_counter]);
             load_shed_counter++;
         }
         this.NodalPowerBalance[i] = MyGrbModel.AddConstr(powerBalanceLHS, GRB.EQUAL, powerBalanceRHS, "PowerBalanceNode" + i);
     }
 }
        private void btnModelo2_Click(object sender, EventArgs e)
        {
            GRBEnv   Ambinte   = new GRBEnv();
            GRBModel Modelo    = new GRBModel(Ambinte);
            Random   Aleatorio = new Random(4);
            int      m         = 1600;

            GRBVar[,] X = new GRBVar[m, m];
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    X[i, j] = Modelo.AddVar(0, 1, Aleatorio.Next(1, 20), GRB.BINARY, "x_" + i.ToString() + "_" + j.ToString());
                }
            }
            Modelo.ModelSense = GRB.MAXIMIZE;
            GRBLinExpr Expressao = new GRBLinExpr();

            for (int i = 0; i < m; i++)
            {
                Expressao.Clear();
                for (int j = 0; j < m; j++)
                {
                    Expressao.AddTerm(1, X[i, j]);
                }
                Modelo.AddConstr(Expressao == 1, "Vendedor_" + i);
            }

            for (int j = 0; j < m; j++)
            {
                Expressao.Clear();
                for (int i = 0; i < m; i++)
                {
                    Expressao.AddTerm(1, X[i, j]);
                }
                Modelo.AddConstr(Expressao == 1, "Regiao_" + j);
            }
            Stopwatch Cronometro = new Stopwatch();

            Cronometro.Start();
            Modelo.Optimize();
            Cronometro.Stop();
            MessageBox.Show("O valor do lucro é: " + Modelo.ObjVal.ToString());
            MessageBox.Show("O tempo para resolver foi de: " + Cronometro.ElapsedMilliseconds.ToString() + " ms");
            MessageBox.Show("Se quiser saber a alocação que gera esse lucro é só me pagar");
            //for (int j = 0; j < m; j++)
            //{
            //    for (int i = 0; i < m; i++)
            //    {
            //        if(X[i,j].X>0)
            //        {
            //            MessageBox.Show("O vendedor " + i + " é alocado para a região " + j);
            //        }
            //    }
            //}
            Modelo.Write("C:\\Teste\\Modelo2.lp");
        }
Esempio n. 3
0
 private void CreateConstraintSessionsMustBeInDifferentTimeslots(int session1Index, int session2Index, int timeslotCount, int roomCount)
 {
     for (int t = 0; t < timeslotCount; t++)
     {
         GRBLinExpr expr = 0.0;
         for (int r = 0; r < roomCount; r++)
         {
             expr.AddTerm(1.0, _v[session1Index, r, t]);
             expr.AddTerm(1.0, _v[session2Index, r, t]);
         }
         _model.AddConstr(expr <= 1.0, $"x[{session1Index},*,{t}]_NotEqual_x[{session2Index},*,{t}]");
         Console.WriteLine($"x[{session1Index},*,{t}]_NotEqual_x[{session2Index},*,{t}]");
     }
 }
Esempio n. 4
0
        static void SolveDual(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs)
        {
            GRBModel dual          = new GRBModel(env);
            Star     forward_stars = new Star();
            Star     reverse_stars = new Star();

            GetStars(nodes_set, arcs, forward_stars, reverse_stars);
            Dictionary <Arc, GRBVar> arc_traversed = new Dictionary <Arc, GRBVar>();

            foreach (Arc a in arcs)
            {
                arc_traversed[a] = dual.AddVar(0, 1, a.length, GRB.CONTINUOUS, "arc_traversed." + a.source + "." + a.dest);
            }
            dual.Update();

            Dictionary <string, GRBConstr> flow_balance = new Dictionary <string, GRBConstr>();

            foreach (string node in nodes_set)
            {
                GRBLinExpr lhs          = new GRBLinExpr();
                List <Arc> forward_star = forward_stars[node];
                List <Arc> reverse_star = reverse_stars[node];
                Console.WriteLine("node " + node);
                Console.Write("Forward star: ");
                foreach (Arc a in forward_star)
                {
                    Console.Write(a.dest + ' ');
                    //                    lhs -= arc_traversed[a];
                    lhs.AddTerm(-1, arc_traversed[a]);
                }
                Console.Write("\nReverse star: ");
                foreach (Arc a in reverse_star)
                {
                    Console.Write(a.source + ' ');
                    lhs.AddTerm(1, arc_traversed[a]);
                }
                Console.WriteLine("");
                flow_balance[node] = dual.AddConstr(lhs, 'E', 0, "flow_balance." + node);
            }
            dual.Update();
            flow_balance[ORIGIN].Set(GRB.DoubleAttr.RHS, -1);
            flow_balance[DESTINATION].Set(GRB.DoubleAttr.RHS, 1);
            dual.Optimize();
            foreach (var pair in arc_traversed)
            {
                Console.WriteLine("Arc {0}:{1} traversed = {2}", pair.Key.source, pair.Key.dest, pair.Value.Get(GRB.DoubleAttr.X));
            }
            Console.WriteLine("length of shortest path = " + dual.Get(GRB.DoubleAttr.ObjVal));
            dual.Dispose();
        }
Esempio n. 5
0
    // Subtour elimination callback.  Whenever a feasible solution is found,
    // find the smallest subtour, and add a subtour elimination
    // constraint if the tour doesn't visit every node.

    protected override void Callback()
    {
        try {
            if (where == GRB.Callback.MIPSOL)
            {
                // Found an integer feasible solution - does it visit every node?

                int   n    = vars.GetLength(0);
                int[] tour = findsubtour(GetSolution(vars));

                if (tour.Length < n)
                {
                    // Add subtour elimination constraint
                    GRBLinExpr expr = 0;
                    for (int i = 0; i < tour.Length; i++)
                    {
                        for (int j = i + 1; j < tour.Length; j++)
                        {
                            expr.AddTerm(1.0, vars[tour[i], tour[j]]);
                        }
                    }
                    AddLazy(expr <= tour.Length - 1);
                }
            }
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
            Console.WriteLine(e.StackTrace);
        }
    }
        /// <summary>
        /// Cria todas as restrições relativas às horas regulares de trabalho disponíveis
        /// </summary>
        /// <param name="entrada">Instância de <see cref="EntradaViewModel"/> contendo os dados informados na planilha de dados</param>
        private void CriaRestricaoHE(EntradaViewModel entrada)
        {
            foreach (var diaSemana in Enum.GetValues(typeof(DiaDaSemana)))
            {
                var diaSemanaEnum = (DiaDaSemana)diaSemana;

                var expressaoLinear = new GRBLinExpr();

                var cargaHorariaExtraDisponivelDiaria = entrada.CargaHorariaExtraDisponivel[diaSemanaEnum];

                entrada.Produtos.ForEach(produto =>
                {
                    var taxaProducao    = produto.GetTaxaUnidadeHora();
                    var variavelProduto = _varArray[produto.GetNomeVariavel(diaSemanaEnum, true)];

                    expressaoLinear.AddTerm(taxaProducao, variavelProduto);
                });

                _grbModel.AddConstr(
                    expressaoLinear,
                    GRB.LESS_EQUAL,
                    cargaHorariaExtraDisponivelDiaria,
                    $"HorasExtrasDisponiveis[{diaSemana}]"
                    );
            }
        }
Esempio n. 7
0
        GRBLinExpr SumOfVars(GRBVar[] vars)
        {
            GRBLinExpr sum = 0.0;

            for (int person = 0; person < vars.Length; person++)
            {
                sum.AddTerm(1, vars[person]);
            }
            return(sum);
        }
        public static GRBLinExpr Quicksum(this IEnumerable <GRBVar> varsToAdd)
        {
            GRBLinExpr expr = new GRBLinExpr();

            foreach (var varToAdd in varsToAdd)
            {
                expr.AddTerm(1.0, varToAdd);
            }

            return(expr);
        }
Esempio n. 9
0
        private void CreateObjective(IEnumerable <MenuItem> items)
        {
            // Minimize the cost of the items that have been selected
            GRBLinExpr expr = 0.0;

            foreach (var item in items)
            {
                expr.AddTerm(item.Cost, _v[item.Id]);
            }

            _model.SetObjective(expr, GRB.MINIMIZE);
        }
Esempio n. 10
0
 private void AllVehiclesMustEndAtTheDepot()
 {
     for (int v = 0; v < _vehicles.Count; v++)
     {
         var vehicleEnd = new GRBLinExpr();
         for (int s = 0; s < _vertices.Count; s++)
         {
             vehicleEnd.AddTerm(1.0, _vehicleTraverse[v][s][_vertices.Count - 1]);
         }
         _model.AddConstr(vehicleEnd, GRB.EQUAL, 1.0, "_AllVehiclesMustEndAtTheDepot");
     }
 }
Esempio n. 11
0
 private void AllVehiclesMustStartFromTheDepot()
 {
     for (int v = 0; v < _vehicles.Count; v++)
     {
         var vehicleStart = new GRBLinExpr();
         for (int e = 0; e < _vertices.Count; e++)
         {
             vehicleStart.AddTerm(1.0, _vehicleTraverse[v][0][e]);
         }
         _model.AddConstr(vehicleStart, GRB.EQUAL, 1.0, "_AllVehiclesMustStartFromTheDepot");
     }
 }
Esempio n. 12
0
        public override bool SetObj(object solver, int Column, double Value)
        {
            GRBModel grbSolver = solver as GRBModel;

            if (grbSolver == null)
            {
                return(false);
            }
            GRBLinExpr exp = grbSolver.GetObjective() as GRBLinExpr;

            exp.AddTerm(Value, exp.GetVar(Column));
            return(true);
        }
Esempio n. 13
0
        GRBLinExpr SumOfAllVars(GRBVar[,] vars)
        {
            GRBLinExpr sum = 0.0;

            for (int person = 0; person < vars.GetLength(0); person++)
            {
                for (int i = 0; i < vars.GetLength(1); i++)
                {
                    sum.AddTerm(1, vars[person, i]);
                }
            }
            return(sum);
        }
Esempio n. 14
0
        private void CreateConstraints(double totalPrice, IEnumerable <MenuItem> items)
        {
            // Total price of items selected, must be exactly 15.05
            GRBLinExpr expr = 0.0;

            foreach (var item in items)
            {
                expr.AddTerm(item.Price, _v[item.Id]);
            }

            _model.AddConstr(expr == totalPrice, $"Sum_Prices_Equal_{totalPrice}");
            Console.WriteLine($"Sum_Prices_Equals_{totalPrice}");

            _model.Update();
        }
        /// <summary>
        /// Cria função objetivo
        /// </summary>
        /// <param name="entrada">Instância de <see cref="EntradaViewModel"/> contendo os dados informados na planilha de dados</param>
        private void CriaFuncaoObjetivo(EntradaViewModel entrada)
        {
            //Cria objeto de expressão linear para podermos gerar uma expressão linear de forma dinâmica
            var expressaoObjetivo = new GRBLinExpr();

            entrada.Produtos.ForEach(produto =>
            {
                var custoHR = produto.CustoRegular;
                var custoHE = produto.CustoHoraExtra;

                foreach (var diaSemana in Enum.GetValues(typeof(DiaDaSemana)))
                {
                    var diaSemanaEnum = (DiaDaSemana)diaSemana;

                    var qtdeProdutoHR = _varArray[produto.GetNomeVariavel(diaSemanaEnum)];
                    expressaoObjetivo.AddTerm(custoHR, qtdeProdutoHR);

                    var qtdeProdutoHE = _varArray[produto.GetNomeVariavel(diaSemanaEnum, true)];
                    expressaoObjetivo.AddTerm(custoHE, qtdeProdutoHE);
                }
            });

            _grbModel.SetObjective(expressaoObjetivo, GRB.MINIMIZE);
        }
Esempio n. 16
0
 private void VehiclesLoadUpCapacity()
 {
     for (int v = 0; v < _vehicles.Count; v++)
     {
         var vehicleCapacity = new GRBLinExpr();
         for (int s = 1; s <= _vertices.Count - 2; s++)
         {
             for (int e = 0; e < _vertices.Count; e++)
             {
                 vehicleCapacity.AddTerm(_vertices[s].Demand, _vehicleTraverse[v][s][e]);
             }
         }
         _model.AddConstr(vehicleCapacity, GRB.LESS_EQUAL, _vehicles[v].Capacity, "_VehiclesLoadUpCapacity");
     }
 }
Esempio n. 17
0
 private void EachCustomerMustBeVisitedOnce()
 {
     for (int s = 1; s <= _vertices.Count - 2; s++)
     {
         var customerVisit = new GRBLinExpr();
         for (int v = 0; v < _vehicles.Count; v++)
         {
             for (int e = 0; e < _vertices.Count; e++)
             {
                 customerVisit.AddTerm(1.0, _vehicleTraverse[v][s][e]);
             }
         }
         _model.AddConstr(customerVisit, GRB.EQUAL, 1.0, "_EachCustomerMustVisitedOnce");
     }
 }
Esempio n. 18
0
 private void CreateObjective()
 {
     _cost = new GRBLinExpr();
     for (int v = 0; v < _vehicles.Count; v++)
     {
         for (int s = 0; s < _vertices.Count; s++)
         {
             for (int e = 0; e < _vertices.Count; e++)
             {
                 var distance = Helpers.CalculateDistance(_vertices[s], _vertices[e]);
                 _cost.AddTerm(distance, _vehicleTraverse[v][s][e]);
             }
         }
     }
     _model.SetObjective(_cost, GRB.MINIMIZE);
 }
Esempio n. 19
0
        private void AddObjective(GRBModel model, GRBVar[,,] seated)
        {
            var expr = new GRBLinExpr();

            for (int x = 0; x < Cinema.Width; x++)
            {
                for (int y = 0; y < Cinema.Height; y++)
                {
                    for (int g = 0; g < Cinema.TotalNumberOfGroups; g++)
                    {
                        expr.AddTerm(Cinema.GroupSizes[g], seated[x, y, g]);
                    }
                }
            }

            model.SetObjective(expr, GRB.MAXIMIZE);
        }
Esempio n. 20
0
        // availabilities of instructors
        GRBLinExpr SumProduct(GRBVar[,] vars, Instructor[] instructors)
        {
            GRBLinExpr result = 0.0;

            for (int person = 0; person < vars.GetLength(0); person++)
            {
                for (int i = 0; i < vars.GetLength(1); i++)
                {
                    double coefficient = 0.0;
                    if (instructors[person].Availability[i] == false)
                    {
                        coefficient = Scores.SupervisorNotAvailable;
                    }
                    result.AddTerm(coefficient, vars[person, i]);
                }
            }
            return(result);
        }
        //model y=x1+x2
        static public void AddCons2Vars(GRBModel m, List <GRBVar> pickvars)
        {
            double[,] coeff = new double[4, 4] {
                { 1, 1, -1, 0 }, { 1, -1, 1, 0 }, { -1, 1, 1, 0 }, { -1, -1, -1, 2 }
            };
            GRBLinExpr lincon = new GRBLinExpr();
            int        i = 0, j = 0;

            for (i = 0; i < 4; i++)
            {
                lincon.Clear();
                for (j = 0; j < 3; j++)
                {
                    lincon.AddTerm(coeff[i, j], pickvars[j]);
                }
                lincon.AddConstant(coeff[i, 3]);
                m.AddConstr(lincon >= 0, "conslin2");
            }
        }
Esempio n. 22
0
 protected void AddGRBConstrDCPowerFlow()
 {
     this.DCPowerFlow = new GRBConstr[MyPowerSystem.TransmissionLines.Count];
     for (int t = 0; t < MyPowerSystem.TransmissionLines.Count; t++)
     {
         TransmissionLine tl = MyPowerSystem.TransmissionLines[t];
         GRBLinExpr powerFlowLHS = new GRBLinExpr();
         powerFlowLHS.AddTerm(1, this.PFlow[t]);
         GRBLinExpr powerFlowRHS = new GRBLinExpr();
         powerFlowRHS.AddTerm(+tl.SusceptanceMho, this.BusAngle[tl.NodeFromID]);
         powerFlowRHS.AddTerm(-tl.SusceptanceMho, this.BusAngle[tl.NodeToID]);
         this.DCPowerFlow[t] = MyGrbModel.AddConstr(powerFlowLHS, GRB.EQUAL, powerFlowRHS, "PowerFlowTL" + t);
     }
 }
    static void Main()
    {
        try {
            // Example data:
            //   e.g. {0, n+1, 2} means clause (x0 or ~x1 or x2)
            int[,] Clauses = new int[, ]
            {
                { 0, n + 1, 2 }, { 1, n + 2, 3 },
                { 2, n + 3, 0 }, { 3, n + 0, 1 },
                { n + 0, n + 1, 2 }, { n + 1, n + 2, 3 },
                { n + 2, n + 3, 0 }, { n + 3, n + 0, 1 }
            };

            int i, status;

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

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

            // Initialize decision variables and objective

            GRBVar[] Lit    = new GRBVar[NLITERALS];
            GRBVar[] NotLit = new GRBVar[NLITERALS];
            for (i = 0; i < NLITERALS; i++)
            {
                Lit[i]    = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, string.Format("X{0}", i));
                NotLit[i] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, string.Format("notX{0}", i));
            }

            GRBVar[] Cla = new GRBVar[NCLAUSES];
            for (i = 0; i < NCLAUSES; i++)
            {
                Cla[i] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, string.Format("Clause{0}", i));
            }

            GRBVar[] Obj = new GRBVar[NOBJ];
            for (i = 0; i < NOBJ; i++)
            {
                Obj[i] = model.AddVar(0.0, 1.0, 1.0, GRB.BINARY, string.Format("Obj{0}", i));
            }

            // Link Xi and notXi
            GRBLinExpr lhs;
            for (i = 0; i < NLITERALS; i++)
            {
                lhs = new GRBLinExpr();
                lhs.AddTerm(1.0, Lit[i]);
                lhs.AddTerm(1.0, NotLit[i]);
                model.AddConstr(lhs, GRB.EQUAL, 1.0, string.Format("CNSTR_X{0}", i));
            }

            // Link clauses and literals
            for (i = 0; i < NCLAUSES; i++)
            {
                GRBVar[] clause = new GRBVar[3];
                for (int j = 0; j < 3; j++)
                {
                    if (Clauses[i, j] >= n)
                    {
                        clause[j] = NotLit[Clauses[i, j] - n];
                    }
                    else
                    {
                        clause[j] = Lit[Clauses[i, j]];
                    }
                }
                model.AddGenConstrOr(Cla[i], clause, string.Format("CNSTR_Clause{0}", i));
            }

            // Link objs with clauses
            model.AddGenConstrMin(Obj[0], Cla, GRB.INFINITY, "CNSTR_Obj0");
            lhs = new GRBLinExpr();
            for (i = 0; i < NCLAUSES; i++)
            {
                lhs.AddTerm(1.0, Cla[i]);
            }
            model.AddGenConstrIndicator(Obj[1], 1, lhs, GRB.GREATER_EQUAL, 4.0, "CNSTR_Obj1");

            // Set global objective sense
            model.ModelSense = GRB.MAXIMIZE;

            // Save problem
            model.Write("genconstr_cs.mps");
            model.Write("genconstr_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 result
            double objval = model.ObjVal;

            if (objval > 1.9)
            {
                Console.WriteLine("Logical expression is satisfiable");
            }
            else if (objval > 0.9)
            {
                Console.WriteLine("At least four clauses can be satisfied");
            }
            else
            {
                Console.WriteLine("Not even three clauses can be satisfied");
            }

            // Dispose of model and environment
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: {0}. {1}", e.ErrorCode, e.Message);
        }
    }
Esempio n. 24
0
        private void RunOptimization()
        {
            GRBEnv   env   = new GRBEnv();
            GRBModel model = new GRBModel(env);

            List <List <GRBVar> > varsFromElements = new List <List <GRBVar> >();

            //Variables: LoD for each element with their respective utility value
            for (var i = 0; i < _model.Elements.Count; i++)
            {
                var element  = _model.Elements[i];
                var allLoads = CalcUtil.GetAllCognitiveLoadsForElement(element);

                List <GRBVar> varsCurrentElement = new List <GRBVar>();

                for (var j = 0; j < allLoads.Count; j++)
                {
                    //Fix element and current LoD if flag is set, i.e. lower and upper bound are 1.0
                    var lowerBound = element.FixateElement && (j + 1) == element.CurrentLevelOfDetail ? 1.0 : 0.0;

                    //Omit element if omit-flag is set, ie lower and upper bound are 0.0
                    var upperBound = !element.OmitElement ? 1.0 : 0.0;

                    //Disable changing the LoD by more than 1, ie set upper bound to 0.0 (except if element is fixated)
                    var absLoDDifference = Math.Abs(element.CurrentLevelOfDetail - 1 - j);
                    if (lowerBound < 1.0 && absLoDDifference > 1)
                    {
                        upperBound = 0.0;
                    }

                    GRBVar eLod = model.AddVar(lowerBound, upperBound, CalcUtil.GetObjectiveForElement(element, j + 1, _model), GRB.BINARY, "e_" + i + "_lod_" + j);
                    varsCurrentElement.Add(eLod);
                }

                varsFromElements.Add(varsCurrentElement);
            }

            //Constraint: overall cognitive load must be below user's cognitive capacity
            GRBLinExpr lhs = 0.0;

            for (var i = 0; i < _model.Elements.Count; i++)
            {
                var element  = _model.Elements[i];
                var allLoads = CalcUtil.GetAllCognitiveLoadsForElement(element);

                for (var j = 0; j < allLoads.Count; j++)
                {
                    var load = allLoads[j] + CalcUtil.GetTimeDependentCognitiveLoadOnsetPenalty(element, _model);
                    lhs.AddTerm(load, varsFromElements[i][j]);
                }
            }
            model.AddConstr(lhs, GRB.LESS_EQUAL, _model.UserModel.CognitiveCapacity, "c_cog");

            //Constraint: constraints to number of available slots
            lhs = 0.0;
            for (var i = 0; i < _model.Elements.Count; i++)
            {
                for (var j = 0; j < _model.Elements[i].MaxLevelOfDetail; j++)
                {
                    lhs.AddTerm(1.0, varsFromElements[i][j]);
                }
            }

            model.AddConstr(lhs, GRB.GREATER_EQUAL, _model.NumMinPlacementSlots, "c_slots_min");
            model.AddConstr(lhs, GRB.LESS_EQUAL, _model.NumMaxPlacementSlots, "c_slots_max");

            //Constraint: only 1 LoD per Element
            for (var i = 0; i < _model.Elements.Count; i++)
            {
                lhs = 0.0;

                for (var j = 0; j < _model.Elements[i].MaxLevelOfDetail; j++)
                {
                    lhs.AddTerm(1.0, varsFromElements[i][j]);
                }

                model.AddConstr(lhs, GRB.LESS_EQUAL, 1.0, "c" + i + "_lod");
            }

            model.ModelSense = GRB.MAXIMIZE;

            model.Optimize();

            var status = model.Status;

            _model.IsFeasible = !(status == GRB.Status.INF_OR_UNBD || status == GRB.Status.INFEASIBLE || status == GRB.Status.UNBOUNDED);

            if (_model.IsFeasible)
            {
                UpdateModels(model, varsFromElements);
                StoreAllSolutions(model);
            }
            else
            {
                Console.WriteLine(@"The model cannot be solved because it is infeasible or unbounded");
            }

            model.Dispose();
            env.Dispose();
        }
Esempio n. 25
0
    static void Main()
    {
        try {
            // Nutrition guidelines, based on
            // USDA Dietary Guidelines for Americans, 2005
            // http://www.health.gov/DietaryGuidelines/dga2005/
            string[] Categories =
                new string[] { "calories", "protein", "fat", "sodium" };
            int      nCategories  = Categories.Length;
            double[] minNutrition = new double[] { 1800, 91, 0, 0 };
            double[] maxNutrition = new double[] { 2200, GRB.INFINITY, 65, 1779 };

            // Set of foods
            string[] Foods =
                new string[] { "hamburger", "chicken", "hot dog", "fries",
                               "macaroni", "pizza", "salad", "milk", "ice cream" };
            int      nFoods = Foods.Length;
            double[] cost   =
                new double[] { 2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89,
                               1.59 };

            // Nutrition values for the foods
            double[,] nutritionValues = new double[, ] {
                { 410, 24, 26, 730 },  // hamburger
                { 420, 32, 10, 1190 }, // chicken
                { 560, 20, 32, 1800 }, // hot dog
                { 380, 4, 19, 270 },   // fries
                { 320, 12, 10, 930 },  // macaroni
                { 320, 15, 12, 820 },  // pizza
                { 320, 31, 12, 1230 }, // salad
                { 100, 8, 2.5, 125 },  // milk
                { 330, 8, 10, 180 } // ice cream
            };

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

            model.ModelName = "diet";

            // Create decision variables for the nutrition information,
            // which we limit via bounds
            GRBVar[] nutrition = new GRBVar[nCategories];
            for (int i = 0; i < nCategories; ++i)
            {
                nutrition[i] =
                    model.AddVar(minNutrition[i], maxNutrition[i], 0, GRB.CONTINUOUS,
                                 Categories[i]);
            }

            // Create decision variables for the foods to buy
            GRBVar[] buy = new GRBVar[nFoods];
            for (int j = 0; j < nFoods; ++j)
            {
                buy[j] =
                    model.AddVar(0, GRB.INFINITY, cost[j], GRB.CONTINUOUS, Foods[j]);
            }

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

            // Nutrition constraints
            for (int i = 0; i < nCategories; ++i)
            {
                GRBLinExpr ntot = 0.0;
                for (int j = 0; j < nFoods; ++j)
                {
                    ntot.AddTerm(nutritionValues[j, i], buy[j]);
                }
                model.AddConstr(ntot == nutrition[i], Categories[i]);
            }

            // Solve
            model.Optimize();
            PrintSolution(model, buy, nutrition);

            Console.WriteLine("\nAdding constraint: at most 6 servings of dairy");
            model.AddConstr(buy[7] + buy[8] <= 6.0, "limit_dairy");

            // Solve
            model.Optimize();
            PrintSolution(model, buy, nutrition);

            // Dispose of model and env
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " +
                              e.Message);
        }
    }
Esempio n. 26
0
        static void Main(string[] args)
        {
            //for (int i = 0; i < 26; i++)
            //    Console.Write(3*i + ",");
            //Console.ReadKey();
            GRBEnv env = new GRBEnv("Kreyium.log");

            int round = 892;

            GRBModel model = new GRBModel(env);

            int[] pos = new int[7] {
                65, 92, 161, 176, 242, 287, 415
            };                                                       //7个输出位置
            GRBVar[] s = model.AddVars(544, GRB.BINARY);
            for (int i = 0; i < 544; i++)
            {
                s[i].VarName = "var" + i.ToString(); //288个寄存器,命名为var0-var288
            }
            char[]   FlagS   = new char[544];        //288个寄存器的Flag
            GRBVar[] NewVars = model.AddVars(34 * round, GRB.BINARY);
            for (int i = 0; i < NewVars.Length; i++)
            {
                NewVars[i].VarName = "y" + i.ToString(); //每过一次更新许需要加30个变量,总共为30*round,命名为y0-y300*round
            }
            char[]   FlagNewVars = new char[34 * round]; //新加变量的Flag
            GRBVar[] IV          = model.AddVars(128, GRB.BINARY);
            for (int i = 0; i < 128; i++)
            {
                IV[i].VarName = "IV" + i.ToString();//128个IV变量
            }
            GRBVar[] Key = model.AddVars(128, GRB.BINARY);
            for (int i = 0; i < 128; i++)
            {
                Key[i].VarName = "Key" + i.ToString();//128个Key变量
            }
            // List<uint> cube = new List<uint>() { 1, 3, 5, 7, 9, 11, 13, 16, 18, 20, 22, 24, 26, 28, 31, 33, 35, 37, 39, 41, 43, 46,
            //                                      48, 50, 52, 54, 61, 63, 65, 67, 69, 71, 73, 76, 78, 80, 82, 84, 86, 88, 90, 92, 95,
            //                                      97, 99, 101, 103, 106, 108, 110, 112, 114, 116, 118, 120, 125, 127};//cube变量
            //dcc19
            // List<uint> cube = new List<uint>() { 0,2,4,6,8,10,12,15,17,19,21,24,26,28,30,32,34,36,39,41,43,45,47,49,52,54,56,58,
            //                                      60,62,67,69,71,73,75,80,82,84,86,89,91,93,95,97,99,102,104,106,108,110,112,114,
            //                                      117,119,121,123};//cube变量
            //List<uint> cube = new List<uint>() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41, 43, 45, 46, 47, 48, 49, 50, 51, 52, 54, 56, 59, 61, 63, 65, 67, 69, 71, 74, 76, 78, 80, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127};
            //dis880 try 892
            //List<uint> cube =new List<uint>(){0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,29,31,33,35,37,39,41,44,46,48,50,52,54,56,59,61,63,65,67,69,72,74,76,78,80,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127};
            List <uint> cube = new List <uint>()
            {
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 37, 39, 41, 43, 44, 45, 46, 47, 48, 49, 50, 52, 54, 57, 59, 61, 63, 65, 67, 69, 72, 74, 76, 78, 80, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127
            };
            List <int> keyset = new List <int>()
            {
            };

            for (int i = 0; i < 128; i++)
            {
                keyset.Add(i);
            }
            for (int i = 0; i < cube.Count(); i++)
            {
                Console.Write(cube[i] + " ");
            }
            Console.WriteLine();
            List <UInt32> Noncube = new List <uint>()
            {
                0x0, 0x0, 0x0, 0x0
            };
            GRBLinExpr ChooseKey = new GRBLinExpr();//超多项式中可能含有的密钥变量集合
            int        VarNumber = 0;

            initial(model, s, FlagS, cube, Noncube, keyset, ChooseKey, IV, Key);//初始化设置
            for (int i = 1; i <= round; i++)
            {
                Triviumcore(model, s, FlagS, NewVars, FlagNewVars, ref VarNumber);
            }

            for (int i = 0; i < 544; i++)
            {
                if (!pos.Contains(i))
                {
                    model.AddConstr(s[i] == 0, "a" + i.ToString());
                }
            }
            GRBLinExpr expr = new GRBLinExpr();

            for (int i = 0; i < 7; i++)
            {
                expr.AddTerm(1.0, s[pos[i]]);
            }
            model.AddConstr(expr == 1, "t1");
            model.Optimize();

            if (model.SolCount > 0)
            {
                Console.WriteLine(model.ObjVal);
            }
            else
            {
                Console.WriteLine("************************************");
                Console.WriteLine("Model is infeasible!!!");
                Console.WriteLine("************************************");
            }
            model.Dispose();
            env.Dispose();
            Console.ReadKey();
        }
Esempio n. 27
0
        private void CreateConstraints(IEnumerable <Session> sessions, IEnumerable <Room> rooms, int timeslotCount)
        {
            int sessionCount = sessions.Count();
            int roomCount    = rooms.Count();

            // Each room can have no more than 1 session per timeslot
            for (int r = 0; r < roomCount; r++)
            {
                for (int t = 0; t < timeslotCount; t++)
                {
                    GRBLinExpr expr = 0.0;
                    for (int s = 0; s < sessionCount; s++)
                    {
                        expr.AddTerm(1.0, _v[s, r, t]);
                    }

                    _model.AddConstr(expr <= 1.0, $"x[*,{r},{t}]_LessEqual_1");
                    Console.WriteLine($"x[*,{r},{t}]_LessEqual_1");
                }
            }

            // Each session must be assigned to exactly 1 room/timeslot combination
            for (int s = 0; s < sessionCount; s++)
            {
                GRBLinExpr expr = 0.0;
                for (int r = 0; r < roomCount; r++)
                {
                    for (int t = 0; t < timeslotCount; t++)
                    {
                        expr.AddTerm(1.0, _v[s, r, t]);
                    }
                }

                _model.AddConstr(expr == 1.0, $"x[{s},*,*]_Equals_1");
                Console.WriteLine($"x[{s},*,*]_Equals_1");
            }

            // No room can be assigned to a session in a timeslot
            // during which it is not available
            foreach (var room in rooms)
            {
                int roomIndex = _roomIds.IndexOfValue(room.Id).Value;
                foreach (var uts in room.UnavailableForTimeslots)
                {
                    int        utsi = _timeslotIds.IndexOfValue(uts).Value;
                    GRBLinExpr expr = 0.0;
                    for (int s = 0; s < sessionCount; s++)
                    {
                        expr.AddTerm(1.0, _v[s, roomIndex, utsi]);
                    }
                    _model.AddConstr(expr == 0.0, $"x[*,{roomIndex},{utsi}]_Equals_0");
                    Console.WriteLine($"x[*,{roomIndex},{utsi}]_Equals_0");
                }
            }

            // Sessions cannot be assigned to a timeslot during which
            // any presenter is unavailable
            foreach (var session in sessions)
            {
                int sessionIndex = _sessionIds.IndexOfValue(session.Id).Value;

                List <int> unavailableTimeslotIndexes = new List <int>();
                foreach (var presenter in session.Presenters)
                {
                    foreach (var unavailableTimeslot in presenter.UnavailableForTimeslots)
                    {
                        int timeslotIndex = _timeslotIds.IndexOfValue(unavailableTimeslot).Value;
                        unavailableTimeslotIndexes.Add(timeslotIndex);
                    }
                }

                if (unavailableTimeslotIndexes.Any())
                {
                    GRBLinExpr expr = 0.0;
                    foreach (var utsi in unavailableTimeslotIndexes.Distinct())
                    {
                        for (int r = 0; r < roomCount; r++)
                        {
                            expr.AddTerm(1.0, _v[sessionIndex, r, utsi]);
                        }
                    }
                    _model.AddConstr(expr == 0, $"PresentersUnavailable_Session[{sessionIndex}");
                    Console.WriteLine($"PresentersUnavailable_Session[{sessionIndex}");
                }
            }

            // A speaker can only be involved with 1 session per timeslot
            var speakerIds = sessions.SelectMany(s => s.Presenters.Select(p => p.Id)).Distinct();

            foreach (int speakerId in speakerIds)
            {
                var pIds = sessions.Where(s => s.Presenters.Select(p => p.Id).Contains(speakerId)).Select(s => s.Id).ToArray();
                for (int i = 0; i < pIds.Length - 1; i++)
                {
                    for (int j = i + 1; j < pIds.Length; j++)
                    {
                        int session1Index = _sessionIds.IndexOfValue(pIds[i]).Value;
                        int session2Index = _sessionIds.IndexOfValue(pIds[j]).Value;
                        CreateConstraintSessionsMustBeInDifferentTimeslots(session1Index, session2Index, timeslotCount, roomCount);
                    }
                }
            }

            // The value of s[i] must be equal to the index of the timeslot
            // that session i is assigned to
            for (int i = 0; i < sessionCount; i++)
            {
                GRBLinExpr expr = 0.0;
                for (int t = 0; t < timeslotCount; t++)
                {
                    for (int r = 0; r < roomCount; r++)
                    {
                        expr.AddTerm(t, _v[i, r, t]);
                    }
                }
                _model.AddConstr(_s[i] == expr, $"s[{i}]_Equals_Timeslot_x[{i},*,*]");
                Console.WriteLine($"s[{i}]_Equals_Timeslot");
            }

            // All sessions with dependencies on session S must be scheduled
            // later (with a higher index value) than session S
            foreach (var session in sessions)
            {
                int sessionIndex = _sessionIds.IndexOfValue(session.Id).Value;
                foreach (var dependentSession in session.Dependencies)
                {
                    int dependentSessionIndex = _sessionIds.IndexOfValue(dependentSession.Id).Value;
                    _model.AddConstr((_s[dependentSessionIndex] + 1) <= _s[sessionIndex], $"s[{dependentSessionIndex}]_GreaterThan_s[{sessionIndex}]");
                    Console.WriteLine($"s[{dependentSessionIndex}]_GreaterThan_s[{sessionIndex}]");
                }
            }

            _model.Update();
        }
Esempio n. 28
0
        public static Graph RunSolver(Graph graph)
        {
            GRBEnv env = new GRBEnv();
            env.Set(GRB.IntParam.OutputFlag, 0);
            env.Set(GRB.IntParam.LogToConsole, 0);
            env.Set(GRB.IntParam.Presolve, 2);
            env.Set(GRB.DoubleParam.Heuristics, 0.0);
            GRBModel model = new GRBModel(env);
            GRBVar[] variables = new GRBVar[graph.NumberOfEdges];
            model.SetCallback(new LPSolverCallback());
            Dictionary<Edge, GRBVar> edgeVars = new Dictionary<Edge, GRBVar>();

            // Add variables to the LP model
            for (int i = 0; i < graph.NumberOfEdges; i++)
            {
                variables[i] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x_" + i);
                edgeVars.Add(graph.Edges[i], variables[i]);
            }
            model.Update();

            // Add constraints to the LP model
            Console.Write("\rRunning LP. Creating constraints...\r");
            //var nonTerminals = graph.Vertices.Except(graph.Terminals).ToList();
            ulong conNr = 0;
            //var terminalCombinations = new List<List<Vertex>>();

            // Assume, without loss of generality, that Terminals[0] is the root, and thus is always included
            int rootNr = 1;
            foreach (var rootTerminal in graph.Terminals)
            //var rootTerminal = graph.Terminals[0];
            {
                Console.Write("\rRunning LP. Creating constraints... {0}/{1}\r", rootNr, graph.Terminals.Count);
                foreach (var combination in GetBFS(graph, rootTerminal))
                {
                    var nodes = combination.ToList(); //new HashSet<Vertex>(combination);
                    if (nodes.Count == graph.NumberOfVertices || graph.Terminals.All(nodes.Contains))
                        continue;
                    //Debug.WriteLine("Combination: {0}", string.Join(" ", nodes));
                    //for (int i = 1; i <= nodes.Count; i++)
                    {
                        var edges = nodes//.Take(i)
                                         .SelectMany(graph.GetEdgesForVertex)
                                         .Distinct()
                                         .Where(x => x.WhereOne(y => !nodes.Contains(y)));
                        GRBLinExpr expression = 0;
                        foreach (var edge in edges)
                            expression.AddTerm(1, edgeVars[edge]);
                        model.AddConstr(expression >= 1.0, "subset_" + conNr);
                        conNr++;

                        if (conNr % 100000 == 0)
                        {
                            //model = model.Presolve(); //Pre-solve the model every 1000 constraints.
                            int constrBefore = model.GetConstrs().Length, varsBefore = model.GetVars().Length;
                            Debug.WriteLine("Presolve called.");
                            var presolved = model.Presolve();
                            Debug.WriteLine("Model has {0} constraints, {1} variables. Presolve has {2} constraints, {3} variables",
                                constrBefore, varsBefore, presolved.GetConstrs().Length, presolved.GetVars().Length);
                        }
                    }
                }

                //Debug.WriteLine("   ");
                //Debug.WriteLine("   ");
                rootNr++;
            }

            //terminalCombinations.Add(new List<Vertex>(new[] { graph.Terminals[0] }));
            //for (int j = 1; j < graph.Terminals.Count - 1; j++)
            //    terminalCombinations.AddRange(new Combinations<Vertex>(graph.Terminals.Skip(1), j).Select(combination => combination.Union(new[] { graph.Terminals[0] }).ToList()));

            //long nonTerminalSetsDone = 0;
            //long nonTerminalSets = 0;
            //for (int i = 0; i <= nonTerminals.Count; i++)
            //    nonTerminalSets += Combinations<Vertex>.NumberOfCombinations(nonTerminals.Count, i);

            //for (int i = 0; i <= nonTerminals.Count; i++)
            //{
            //    foreach (var nonTerminalSet in new Combinations<Vertex>(nonTerminals, i))
            //    {
            //        foreach (var nodes in (from a in terminalCombinations
            //                               select new HashSet<Vertex>(a.Union(nonTerminalSet))))
            //        {
            //            var edges = nodes.SelectMany(graph.GetEdgesForVertex)
            //                             .Distinct()
            //                             .Where(x => x.WhereOne(y => !nodes.Contains(y)));
            //            GRBLinExpr expression = 0;
            //            foreach (var edge in edges)
            //                expression.AddTerm(1, edgeVars[edge]);
            //            model.AddConstr(expression >= 1.0, "subset_" + conNr);
            //            conNr++;
            //        }
            //        nonTerminalSetsDone++;
            //        if (nonTerminalSetsDone % 100 == 0)
            //            Console.Write("\rRunning LP. Creating constraints... {0}/{1} ({2:0.000}%)\r", nonTerminalSetsDone, nonTerminalSets, nonTerminalSetsDone * 100.0 / nonTerminalSets);
            //    }
            //}

            // Solve the LP model
            Console.Write("\rRunning LP. Creating objective & updating...                                   \r");
            GRBLinExpr objective = new GRBLinExpr();
            for (int i = 0; i < graph.NumberOfEdges; i++)
                objective.AddTerm(graph.Edges[i].Cost, variables[i]);
            model.SetObjective(objective, GRB.MINIMIZE);
            Console.Write("\rRunning LP. Tuning...                                   \r");
            model.Tune();
            Debug.WriteLine("Presolve called.");
            model.Presolve();
            Console.Write("\rRunning LP. Solving...                               \r");
            Debug.WriteLine("Optimize called.");
            model.Optimize();

            Graph solution = graph.Clone();
            HashSet<Edge> includedEdges = new HashSet<Edge>();
            for (int i = 0; i < solution.NumberOfEdges; i++)
            {
                var value = variables[i].Get(GRB.DoubleAttr.X);
                if (value == 1)
                    includedEdges.Add(solution.Edges[i]);
            }

            foreach (var edge in solution.Edges.ToList())
                if (!includedEdges.Contains(edge))
                    solution.RemoveEdge(edge);

            Console.Write("\r                                                  \r");

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

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

            model.ModelName = "facility";

            // 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
            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]);
                }
                model.AddConstr(dtot == Demand[w], "Demand" + w);
            }

            // 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:");
            double maxFixed = -GRB.INFINITY;
            for (int p = 0; p < nPlants; ++p)
            {
                if (FixedCosts[p] > maxFixed)
                {
                    maxFixed = FixedCosts[p];
                }
            }
            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
            model.Optimize();

            // Print solution
            Console.WriteLine("\nTOTAL COSTS: " + model.ObjVal);
            Console.WriteLine("SOLUTION:");
            for (int p = 0; p < nPlants; ++p)
            {
                if (open[p].X > 0.99)
                {
                    Console.WriteLine("Plant " + p + " open:");
                    for (int w = 0; w < nWarehouses; ++w)
                    {
                        if (transport[w, p].X > 0.0001)
                        {
                            Console.WriteLine("  Transport " +
                                              transport[w, p].X + " units to warehouse " + w);
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Plant " + p + " closed!");
                }
            }

            // Dispose of model and env
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
        }
    }
        static void Main(string[] args)
        {
            GRBEnv   env   = new GRBEnv("TJLinearCharacter.log");
            GRBModel model = new GRBModel(env);

            //declare the iv variables and key variables
            GRBVar[] keyvar = model.AddVars(80, GRB.BINARY);    //declare the assignment variables of key variables
            GRBVar[] ivvar  = model.AddVars(80, GRB.BINARY);    //declare the assignment variables of iv variables
            GRBVar[] kvf    = model.AddVars(80, GRB.BINARY);    //declare the flag variables of key variables
            GRBVar[] vvf    = model.AddVars(80, GRB.BINARY);    //declare the flag variables of iv variables

            GRBVar[] Uvar = model.AddVars(8000, GRB.BINARY);    //interval assignment variables used to long XOR expression into short ones y=k1+k2+k3+k4--> u1=k1+k2, u2=k3+k4, y=u1+u2
            GRBVar[] Vvar = model.AddVars(8000, GRB.INTEGER);   //interval variables
            GRBVar[] Wvar = model.AddVars(8000, GRB.BINARY);    //interval variables

            GRBVar[] UFvar = model.AddVars(8000, GRB.BINARY);   //UFvar[i] is the flag variables corresponding to Uvar[i]
            GRBVar[] NUvar = model.AddVars(8000, GRB.BINARY);   //NUvar[i]= 1-Uvar[i]
            GRBVar[] NUFvar = model.AddVars(8000, GRB.BINARY);  //NUFvar[i]= 1-UFvar[i]
            GRBVar[] Consvar = model.AddVars(8000, GRB.BINARY); //constant variables
            GRBVar[] bvar = model.AddVars(8000, GRB.BINARY);    //b variables
            int      i, j, k;
            int      loc0 = 0, loc1 = 0, loc2 = 0, loc3 = 0, loc4 = 0, locb = 0;
            int      locf = 0;
            int      con  = 0;

            // name all the variables used in this MILP model
            for (i = 0; i < keyvar.Length; i++)
            {
                keyvar[i].VarName = "k" + i.ToString();
                ivvar[i].VarName  = "v" + i.ToString();
                kvf[i].VarName    = "kf" + i.ToString();
                vvf[i].VarName    = "vf" + i.ToString();
            }
            for (i = 0; i < Uvar.Length; i++)
            {
                Uvar[i].VarName    = "U" + i.ToString();
                Wvar[i].VarName    = "W" + i.ToString();
                UFvar[i].VarName   = "UF" + i.ToString();
                Vvar[i].VarName    = "V" + i.ToString();
                NUvar[i].VarName   = "NU" + i.ToString();
                NUFvar[i].VarName  = "NUF" + i.ToString();
                bvar[i].VarName    = "b" + i.ToString();
                Consvar[i].VarName = "cons" + i.ToString();
            }

            UInt32[, ,] ConS = new UInt32[1000, 200, 6];//used to store the conditions derived to control the propagation of difference
            int[] conlen   = new int[1000];
            int[] consflag = new int[1000];
            int[] rec_loc1 = new int[1000];
            int[] rec_locf = new int[1000];

            //the number of the conditions
            int consnum = 652;

            int[] loc        = new int[2];
            int[] locw       = new int[1];
            int[] condiassig = new int[consnum];
            int[] condiflag  = new int[consnum];

            GRBLinExpr Tar     = new GRBLinExpr();//declare the target linear expression, which is used as the objective function
            List <int> indlist = new List <int>()
            {
            };
            List <GRBVar> Varlist = new List <GRBVar>()
            {
            };
            List <GRBVar> VarlistCopy = new List <GRBVar>()
            {
            };
            List <GRBVar> VarFlaglist = new List <GRBVar>()
            {
            };
            //List<GRBVar> VarFlaglistCopy = new List<GRBVar>() { };
            StreamWriter sw = new StreamWriter("FinalCons.txt");
            //the index of cube variables
            List <int> cube = new List <int>()
            {
                0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78
            };

            //set the state of cube variables to \delta
            for (i = 0; i < cube.Count; i++)
            {
                model.AddConstr(vvf[cube[i]] == 1, "iniiv" + (cube[i]).ToString());
            }

            //set the contraints between an assigment variable and the corresponding flag variable
            for (i = 0; i < 80; i++)
            {
                model.AddConstr(keyvar[i] <= 1 - kvf[i], "keyflagrel");
                model.AddConstr(ivvar[i] <= 1 - vvf[i], "ivflagrel");
            }
            model.Update();

            //read the derived constraints from the file
            ReadCondition(ConS, conlen, consflag);
            Console.Write("ReadConditionDone\n");

            //model each condition
            for (i = 0; i < consnum; i++)
            {
                loc[0] = loc1;
                loc[1] = locf;
                VarFlaglist.Clear();
                Varlist.Clear();
                //linearize a condition and return a list of involved variables.

                //In this condition, for condition f, it would linearize it and would return the assignment/flag variable of each monomial in f;
                //In paticular, Uvar[0],Uvar[1],...,Uvar[m-1] are the assignment variables of the linearized monomials
                //UFvar[0],UFvar[1],...,UFvar[m-1] are the flag variables of the linearized monomials
                //For eaxmple, for a condition f=k1+k2*k3+k4, it can be linearized as f=u1+u2+u3 where u2=k2k3.
                //Then, Varlist[0],Varlist[1],Varlist[2] are assignment variables of u1,u2,u3
                //and VarFlaglist[0],VarFlaglist[1],...,VarFlaglist[2] are the flag variables of u1,u2,u3
                Varlist = LinearConstrain(model, Uvar, UFvar, ConS, conlen, i, keyvar, ivvar, loc, kvf, vvf, Wvar, locw, VarFlaglist);
                loc1    = loc[0];
                locf    = loc[1];
                //here a condition f is linearized and so it is the XOR of several variables.
                //in the following, we would determine the assigment varible and flag variable of f
                // and we denote the assigment variable and flag variable of f by f_av and f_fv respectively for short.

                //The target expression 'Tar' is determined according to the assigment variable and flag variable of each condition f
                //In particular, Tar= sum(f in Conset) f_av +(-10000)*f_fv, where Conset is the set of conditions.

                //If the size of f is 1(excluding the constant), namely f consists of only one variable, then we do not need extra operations.
                if (Varlist.Count == 1)
                {
                    //if consflag[i]=1, then it means that there is a constant 1 in f.
                    //In this case, we add (-1.0*f_av) to Tar and increase con by 1 which is added to Tar in the end.
                    if (consflag[i] == 1)
                    {
                        Tar.AddTerm(-1.0, Varlist[0]);
                        con++;
                    }
                    else
                    {
                        Tar.AddTerm(1.0, Varlist[0]);
                    }
                    //add -10000*f_fv to Tar
                    Tar.AddTerm(-10000, VarFlaglist[0]);
                    rec_loc1[i] = loc1;
                    rec_locf[i] = locf;
                }

                //If f is the XOR of two variables(assumin that f=u1+u2+c), where c is a constant in {0,1}.
                //then we shoule calclate f_av and f_fv according to (u1_av, u2_av) and (u1_fv, u2_fv).
                if (Varlist.Count == 2)
                {
                    VarlistCopy.Clear();
                    GRBVar[] VarFlaglistCopy = new GRBVar[3];
                    GRBVar[] Vartemplist     = new GRBVar[4];
                    //copy Varlist/VarFlaglist to VarlistCopy/VarFlaglistCopy
                    for (j = 0; j < Varlist.Count(); j++)
                    {
                        VarlistCopy.Add(Varlist[j]);
                        VarFlaglistCopy[j] = VarFlaglist[j];
                    }
                    VarlistCopy.Add(Uvar[loc1]);

                    //model u1_av+u2_av. Here, VarlistCopy[0]and VarlistCoyp[1] are u1_av and u2_av respectively.
                    AddCons2Vars(model, VarlistCopy);
                    //model u1_av+u2_av+c. if consflag[i]=1, then c is 1. In this case, we add an constant variable Consvar[loc0] to the model
                    //and model u1_av+u2_av+c.
                    if (consflag[i] == 1)
                    {
                        model.AddConstr(Consvar[loc0++] == 1, "Flip" + j.ToString());
                        VarlistCopy[0] = Uvar[loc1];
                        VarlistCopy[1] = Consvar[loc0 - 1];
                        VarlistCopy[2] = Uvar[loc1 + 1];
                        //Console.WriteLine("*****\n" + loc1 + "\n******\n" + loc0 + "\n*****\n");
                        loc1++;
                        AddCons2Vars(model, VarlistCopy);
                    }

                    //until now, Uvar[loc1] is corresponding to beta_d in Proposition 2 of our paper.
                    //Then, we shall show how to obtain the final assignment/flag variable of f.

                    //UF flip the variables
                    model.AddConstr(NUvar[loc3++] == 1 - VarFlaglist[0], "Flip1" + (loc3).ToString());
                    model.AddConstr(NUvar[loc3++] == 1 - VarFlaglist[1], "Flip2" + (loc3).ToString());
                    VarFlaglistCopy[0] = NUvar[loc3 - 1];
                    VarFlaglistCopy[1] = VarFlaglist[0];
                    //Vvar[loc2++]=min(1 - VarFlaglist[1], VarFlaglist[0]). Vvar[loc2] corresponds to T_j in Proposition 2.
                    model.AddGenConstrMin(Vvar[loc2++], VarFlaglistCopy, 1000, "FlagTransOxr1" + loc2.ToString());
                    VarFlaglistCopy[0] = NUvar[loc3 - 2];
                    VarFlaglistCopy[1] = VarFlaglist[1];
                    //Vvar[loc2++]=min(1 - VarFlaglist[0], VarFlaglist[1]). Vvar[loc2] corresponds to T_j in Proposition 2.
                    model.AddGenConstrMin(Vvar[loc2++], VarFlaglistCopy, 1000, "FlagTransOxr2" + loc2.ToString());
                    //UFvar[loc1]=Vvar[loc2-1]+Vvar[loc2-2], UFvar[loc1] is the flag variable of f
                    // model.AddConstr(UFvar[loc1] == Vvar[loc2 - 1] + Vvar[loc2 - 2], "FlagTransOxr3" + loc2.ToString());
                    for (j = 0; j < Varlist.Count; j++)
                    {
                        Vartemplist[j] = Vvar[loc2 - 1 - j];
                    }
                    //UFvar[locf]=max(Vvar[loc2],Vvar[loc2-1],...,). is equivalent to UFvar[locf]= Vvar[loc2]+Vvar[loc2-1]+...+
                    //since only one of Vvar[loc2],Vvar[loc2-1],..., is equal to 1.
                    //UFvar[locf] is the flag variable of f, corresponding to F_d in Proposition 2.
                    model.AddGenConstrMax(UFvar[locf], Vartemplist, 0, "FlagTransXor-2" + loc2.ToString());

                    //NUFvar[loc4] =1-UFvar[loc1] and increase loc4 by 1. NUFvar[loc4] corresponds to 1-F_d in Proposition 2.
                    model.AddConstr(NUFvar[loc4++] == 1 - UFvar[locf], "Flip3" + loc4.ToString());
                    //max(u1_fv,u2_fv). bvar[locb] corresponds to b_d in Proposition 2.
                    VarFlaglistCopy[0] = VarFlaglist[0];
                    VarFlaglistCopy[1] = VarFlaglist[1];
                    model.AddGenConstrMax(bvar[locb++], VarFlaglistCopy, 0, "maxfv" + locb.ToString());

                    //NUFvar[loc4] =1-bvar[locb++] and increase loc4 by 1. NUFvar[loc4] corresponds to 1-b_d in Proposition 2.
                    model.AddConstr(NUFvar[loc4++] == 1 - bvar[locb - 1], "Flip3" + loc4.ToString());

                    VarFlaglistCopy[0] = NUFvar[loc4 - 1]; //corresponding to 1-F_d
                    VarFlaglistCopy[1] = NUFvar[loc4 - 2]; //corresponding to 1-b_d
                    VarFlaglistCopy[2] = Uvar[loc1];       //corresponding to beta_d
                    loc1++;
                    //Uvar[loc1]=min(NUFvar[loc4-1],NUFvar[loc4-2],loc1), is the  assigment variable of f.
                    model.AddGenConstrMin(Uvar[loc1], VarFlaglistCopy, 1000, "minav" + loc1.ToString());
                    //model.Update();
                    Tar.AddTerm(1.0, Uvar[loc1]);

                    Tar.AddTerm(-10000, UFvar[locf]);
                    rec_loc1[i] = loc1;
                    rec_locf[i] = locf;
                    loc1++;
                    locf++;
                }
                //in this case, assume that f=u1+u2+u3+c
                if (Varlist.Count == 3)
                {
                    VarlistCopy.Clear();
                    GRBVar[] VarFlaglistCopy  = new GRBVar[4];
                    GRBVar[] VarFlaglistCopy2 = new GRBVar[4];
                    GRBVar[] Vartemplist      = new GRBVar[4];
                    for (j = 0; j < Varlist.Count(); j++)
                    {
                        VarlistCopy.Add(Varlist[j]);
                        VarFlaglistCopy[j] = VarFlaglist[j];
                    }
                    VarlistCopy.Add(Uvar[loc1]);
                    //Uvar[loc1]=u1+u2+u3
                    AddCons3Vars(model, VarlistCopy);
                    //model.AddGenConstrMax(UFvar[loc1], VarFlaglistCopy, 0, "TransFlagXor" + loc1.ToString());

                    //if c==1, namely f has the constant term 1, U[loc1+1]=Uvar[loc]+1
                    if (consflag[i] == 1)
                    {
                        model.AddConstr(Consvar[loc0++] == 1, "Flip" + j.ToString());
                        VarlistCopy[0] = Uvar[loc1];
                        VarlistCopy[1] = Consvar[loc0 - 1];
                        VarlistCopy[2] = Uvar[loc1 + 1];
                        loc1++;
                        AddCons2Vars(model, VarlistCopy);
                    }

                    //filp every variable,
                    for (j = 0; j < Varlist.Count; j++)
                    {
                        model.AddConstr(NUvar[loc3++] == 1 - VarFlaglistCopy[j], "Flip" + j.ToString());
                    }
                    //
                    for (j = 0; j < Varlist.Count; j++)
                    {
                        for (k = 0; k < Varlist.Count; k++)
                        {
                            if (k != j)
                            {
                                Vartemplist[k] = NUvar[loc3 - 1 - (Varlist.Count - 1 - k)];
                            }
                            else
                            {
                                Vartemplist[k] = VarFlaglistCopy[k];
                            }
                        }
                        //Vvar[loc2]=min(1-VarFlaglistCopy[0],1-VarFlaglistCopy[2],...,VarFlaglistCopy[j],1-VarFlaglistCopy[j],...)
                        model.AddGenConstrMin(Vvar[loc2++], Vartemplist, 1000, "FlagTransOxr1" + loc2.ToString());
                    }

                    for (j = 0; j < Varlist.Count; j++)
                    {
                        Vartemplist[j] = Vvar[loc2 - 1 - j];
                    }
                    //Since only one of Vvar[loc2 - 1],Vvar[loc2 - 2],..., is equal to 0 and the remainings are equal to 0s,
                    //UFvar[loc1]=max(Vvar[loc2 - 1],Vvar[loc2 - 2],...,) is equivalently to UFvar[loc1]=Vvar[loc2 - 1]+Vvar[loc2 - 2]+...+
                    //UFvar[loc1]is the fianl flag variable of f
                    model.AddGenConstrMax(UFvar[locf], Vartemplist, 0, "FlagTransXor-2" + loc2.ToString());


                    //NUFvar[loc4] =1-UFvar[loc1] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4++] == 1 - UFvar[locf], "Flip3" + loc4.ToString());
                    //max(u1_fv,u2_fv,u3_fv)
                    VarFlaglistCopy[0] = VarFlaglist[0];
                    VarFlaglistCopy[1] = VarFlaglist[1];
                    VarFlaglistCopy[2] = VarFlaglist[2];
                    model.AddGenConstrMax(bvar[locb++], VarFlaglistCopy, 0, "maxfv" + locb.ToString());

                    //NUFvar[loc4] =1-bvar[locb++] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4++] == 1 - bvar[locb - 1], "Flip3" + loc4.ToString());

                    VarFlaglistCopy2[0] = NUFvar[loc4 - 1];
                    VarFlaglistCopy2[1] = NUFvar[loc4 - 2];
                    VarFlaglistCopy2[2] = Uvar[loc1];
                    loc1++;
                    //Uvar[loc1]=min(NUFvar[loc4-1],NUFvar[loc4-2],loc1), is the  assigment variable of f.
                    model.AddGenConstrMin(Uvar[loc1], VarFlaglistCopy2, 1000, "min_av" + loc1.ToString());


                    Tar.AddTerm(1.0, Uvar[loc1]);
                    Tar.AddTerm(-10000, UFvar[locf]);
                    rec_loc1[i] = loc1;
                    rec_locf[i] = locf;
                    loc1++;
                    locf++;
                }
                //assuming f=u1+u2+u3+u4+c
                if (Varlist.Count == 4)
                {
                    List <GRBVar> templist = new List <GRBVar>()
                    {
                    };
                    GRBVar[] VarFlaglistCopy  = new GRBVar[5];
                    GRBVar[] VarFlaglistCopy2 = new GRBVar[5];
                    GRBVar[] Vartemplist      = new GRBVar[5];

                    for (j = 0; j < Varlist.Count(); j++)
                    {
                        VarFlaglistCopy[j] = VarFlaglist[j];
                    }

                    templist.Add(Varlist[0]);
                    templist.Add(Varlist[1]);
                    templist.Add(Uvar[loc1]);
                    AddCons2Vars(model, templist);

                    templist.Clear();
                    loc1++;
                    templist.Add(Varlist[2]);
                    templist.Add(Varlist[3]);
                    templist.Add(Uvar[loc1]);
                    AddCons2Vars(model, templist);


                    templist.Clear();
                    loc1++;
                    templist.Add(Uvar[loc1 - 2]);
                    templist.Add(Uvar[loc1 - 1]);
                    templist.Add(Uvar[loc1]);
                    AddCons2Vars(model, templist);

                    //if c==1
                    if (consflag[i] == 1)
                    {
                        model.AddConstr(Consvar[loc0++] == 1, "Flip" + j.ToString());
                        VarlistCopy[0] = Uvar[loc1];
                        VarlistCopy[1] = Consvar[loc0 - 1];
                        VarlistCopy[2] = Uvar[loc1 + 1];
                        loc1++;
                        AddCons2Vars(model, VarlistCopy);
                    }


                    for (j = 0; j < Varlist.Count; j++)
                    {
                        model.AddConstr(NUvar[loc3++] == 1 - VarFlaglistCopy[j], "Flip" + j.ToString());
                    }

                    for (j = 0; j < Varlist.Count; j++)
                    {
                        for (k = 0; k < Varlist.Count; k++)
                        {
                            if (k != j)
                            {
                                Vartemplist[k] = NUvar[loc3 - 1 - (Varlist.Count - 1 - k)];
                            }
                            else
                            {
                                Vartemplist[k] = VarFlaglistCopy[k];
                            }
                        }
                        model.AddGenConstrMin(Vvar[loc2++], Vartemplist, 1000, "FlagTransOxr1" + loc2.ToString());
                    }

                    for (j = 0; j < Varlist.Count; j++)
                    {
                        Vartemplist[j] = Vvar[loc2 - 1 - j];
                    }
                    model.AddGenConstrMax(UFvar[locf], Vartemplist, 0, "FlagTransXor-2" + loc2.ToString());

                    //NUFvar[loc4] =1-UFvar[loc1] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4] == 1 - UFvar[locf], "Flip3" + loc4.ToString());
                    loc4++;
                    //max(u1_fv,u2_fv,u3_fv,u4_fv)
                    VarFlaglistCopy[0] = VarFlaglist[0];
                    VarFlaglistCopy[1] = VarFlaglist[1];
                    VarFlaglistCopy[2] = VarFlaglist[2];
                    VarFlaglistCopy[3] = VarFlaglist[3];
                    model.AddGenConstrMax(bvar[locb++], VarFlaglistCopy, 0, "maxfv" + locb.ToString());

                    //NUFvar[loc4] =1-bvar[locb++] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4] == 1 - bvar[locb - 1], "Flip4" + loc4.ToString());
                    loc4++;
                    //VarFlaglistCopy.Initialize();

                    VarFlaglistCopy2[0] = NUFvar[loc4 - 1];
                    VarFlaglistCopy2[1] = NUFvar[loc4 - 2];
                    VarFlaglistCopy2[2] = Uvar[loc1];
                    loc1++;

                    //Uvar[loc1]=min(NUFvar[loc4-1],NUFvar[loc4-2],loc1), is the  assigment variable of f.
                    model.AddGenConstrMin(Uvar[loc1], VarFlaglistCopy2, 1000, "min_av" + loc1.ToString());

                    //Tar=Tar+assigment variable +(-10000)*flag variable
                    Tar.AddTerm(1.0, Uvar[loc1]);
                    Tar.AddTerm(-10000, UFvar[locf]);
                    rec_loc1[i] = loc1;
                    rec_locf[i] = locf;
                    loc1++;
                    locf++;
                }
                //assuming f=u1+u2+u3+u4+u5+c
                if (Varlist.Count == 5)
                {
                    List <GRBVar> templist = new List <GRBVar>()
                    {
                    };
                    GRBVar[] VarFlaglistCopy  = new GRBVar[6];
                    GRBVar[] VarFlaglistCopy2 = new GRBVar[6];
                    GRBVar[] Vartemplist      = new GRBVar[6];

                    for (j = 0; j < Varlist.Count(); j++)
                    {
                        VarFlaglistCopy[j] = VarFlaglist[j];
                    }

                    templist.Add(Varlist[0]);
                    templist.Add(Varlist[1]);
                    templist.Add(Uvar[loc1]);
                    AddCons2Vars(model, templist);

                    templist.Clear();
                    loc1++;
                    templist.Add(Varlist[2]);
                    templist.Add(Varlist[3]);
                    templist.Add(Varlist[4]);
                    templist.Add(Uvar[loc1]);
                    AddCons3Vars(model, templist);


                    templist.Clear();
                    loc1++;
                    templist.Add(Uvar[loc1 - 2]);
                    templist.Add(Uvar[loc1 - 1]);
                    templist.Add(Uvar[loc1]);
                    AddCons2Vars(model, templist);


                    if (consflag[i] == 1)
                    {
                        model.AddConstr(Consvar[loc0++] == 1, "Flip" + j.ToString());
                        VarlistCopy[0] = Uvar[loc1];
                        VarlistCopy[1] = Consvar[loc0 - 1];
                        VarlistCopy[2] = Uvar[loc1 + 1];
                        loc1++;
                        AddCons2Vars(model, VarlistCopy);
                    }

                    for (j = 0; j < Varlist.Count; j++)
                    {
                        model.AddConstr(NUvar[loc3++] == 1 - VarFlaglistCopy[j], "Flip" + j.ToString());
                    }
                    //flip and calculate Tj
                    for (j = 0; j < Varlist.Count; j++)
                    {
                        for (k = 0; k < Varlist.Count; k++)
                        {
                            if (k != j)
                            {
                                Vartemplist[k] = NUvar[loc3 - 1 - (Varlist.Count - 1 - k)];
                            }
                            else
                            {
                                Vartemplist[k] = VarFlaglistCopy[k];
                            }
                        }
                        model.AddGenConstrMin(Vvar[loc2++], Vartemplist, 1000, "FlagTransOxr1" + loc2.ToString());
                    }
                    //
                    for (j = 0; j < Varlist.Count; j++)
                    {
                        Vartemplist[j] = Vvar[loc2 - 1 - j];
                    }
                    model.AddGenConstrMax(UFvar[locf], Vartemplist, 0, "FlagTransXor-2" + loc2.ToString());


                    //NUFvar[loc4] =1-UFvar[loc1] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4++] == 1 - UFvar[locf], "Flip3" + loc4.ToString());
                    //max(u1_fv,u2_fv,u3_fv,u4_fv,u5_fv)
                    VarFlaglistCopy[0] = VarFlaglist[0];
                    VarFlaglistCopy[1] = VarFlaglist[1];
                    VarFlaglistCopy[2] = VarFlaglist[2];
                    VarFlaglistCopy[3] = VarFlaglist[3];
                    VarFlaglistCopy[4] = VarFlaglist[4];
                    model.AddGenConstrMax(bvar[locb++], VarFlaglistCopy, 0, "maxfv" + locb.ToString());

                    //NUFvar[loc4] =1-bvar[locb++] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4++] == 1 - bvar[locb - 1], "Flip4" + loc4.ToString());

                    VarFlaglistCopy2[0] = NUFvar[loc4 - 1];
                    VarFlaglistCopy2[1] = NUFvar[loc4 - 2];
                    VarFlaglistCopy2[2] = Uvar[loc1];
                    loc1++;

                    //Uvar[loc1]=min(NUFvar[loc4-1],NUFvar[loc4-2],loc1), is the  assigment variable of f.
                    model.AddGenConstrMin(Uvar[loc1], VarFlaglistCopy2, 1000, "min_av" + loc1.ToString());
                    Tar.AddTerm(1.0, Uvar[loc1]);

                    Tar.AddTerm(-10000, UFvar[locf]);
                    rec_loc1[i] = loc1;
                    rec_locf[i] = locf;
                    loc1++;
                    locf++;
                }
                //Console.WriteLine("5: " +loc1);
                //assuming that f=u1+u2+u3+u4+u5...+um+c, where m>5.
                if (Varlist.Count > 5)
                {
                    int length;
                    length = Varlist.Count;
                    List <GRBVar> curvarlist = new List <GRBVar>()
                    {
                    };
                    GRBVar[] VarFlaglistCopy  = new GRBVar[Varlist.Count + 1];
                    GRBVar[] VarFlaglistCopy2 = new GRBVar[Varlist.Count + 1];
                    GRBVar[] Vartemplist      = new GRBVar[Varlist.Count + 1];

                    for (j = 0; j < Varlist.Count; j++)
                    {
                        curvarlist.Add(Varlist[j]);
                        VarFlaglistCopy[j] = VarFlaglist[j];
                    }

                    //model f=u1+u2+...+un. The method used here is a slight differnt from that presented in the paper.
                    //The method used here is more convenient for coding.
                    while (length > 3)
                    {
                        List <GRBVar> nextvarlist = new List <GRBVar>()
                        {
                        };
                        List <GRBVar> templist = new List <GRBVar>()
                        {
                        };
                        //
                        templist.Add(curvarlist[0]);
                        templist.Add(curvarlist[1]);
                        templist.Add(curvarlist[2]);
                        templist.Add(Uvar[loc1]);
                        AddCons3Vars(model, templist);

                        for (j = 3; j < curvarlist.Count; j++)
                        {
                            nextvarlist.Add(curvarlist[j]);
                        }
                        nextvarlist.Add(Uvar[loc1]);
                        curvarlist.Clear();
                        for (j = 0; j < nextvarlist.Count; j++)
                        {
                            curvarlist.Add(nextvarlist[j]);
                        }
                        length = curvarlist.Count;
                        loc1++;
                    }

                    if (length == 2)
                    {
                        curvarlist.Add(Uvar[loc1]);
                        AddCons2Vars(model, curvarlist);
                        //if c==1, then we need xor one more constant
                        if (consflag[i] == 1)
                        {
                            model.AddConstr(Consvar[loc0++] == 1, "Flip" + j.ToString());
                            VarlistCopy[0] = Uvar[loc1];
                            VarlistCopy[1] = Consvar[loc0 - 1];
                            VarlistCopy[2] = Uvar[loc1 + 1];
                            loc1++;
                            AddCons2Vars(model, VarlistCopy);
                        }
                    }

                    if (length == 3)
                    {
                        curvarlist.Add(Uvar[loc1]);
                        AddCons3Vars(model, curvarlist);
                        //if c==1, then we need xor one more constant
                        if (consflag[i] == 1)
                        {
                            model.AddConstr(Consvar[loc0++] == 1, "Flip" + j.ToString());
                            VarlistCopy[0] = Uvar[loc1];
                            VarlistCopy[1] = Consvar[loc0 - 1];
                            VarlistCopy[2] = Uvar[loc1 + 1];
                            loc1++;
                            AddCons2Vars(model, VarlistCopy);
                        }
                    }



                    for (j = 0; j < Varlist.Count; j++)
                    {
                        model.AddConstr(NUvar[loc3++] == 1 - VarFlaglistCopy[j], "Flip" + j.ToString());
                    }

                    for (j = 0; j < Varlist.Count; j++)
                    {
                        for (k = 0; k < Varlist.Count; k++)
                        {
                            if (k != j)
                            {
                                Vartemplist[k] = NUvar[loc3 - 1 - (Varlist.Count - 1 - k)];
                            }
                            else
                            {
                                Vartemplist[k] = VarFlaglistCopy[k];
                            }
                        }
                        model.AddGenConstrMin(Vvar[loc2++], Vartemplist, 1000, "FlagTransOxr1" + loc2.ToString());
                    }
                    for (j = 0; j < Varlist.Count; j++)
                    {
                        Vartemplist[j] = Vvar[loc2 - 1 - j];
                    }
                    model.AddGenConstrMax(UFvar[locf], Vartemplist, 0, "FlagTransXor-2" + loc2.ToString());

                    //NUFvar[loc4] =1-UFvar[loc1] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4++] == 1 - UFvar[locf], "Flip3" + loc4.ToString());
                    //bvar[locb]=max(u1_fv,u2_fv,u3_fv,u4_fv,...,un_fv) and increase locb by 1
                    for (j = 0; j < VarFlaglist.Count; j++)
                    {
                        VarFlaglistCopy[j] = VarFlaglist[j];
                    }
                    model.AddGenConstrMax(bvar[locb++], VarFlaglistCopy, 0, "maxfv" + locb.ToString());

                    //NUFvar[loc4] =1-bvar[locb++] and increase loc4 by 1
                    model.AddConstr(NUFvar[loc4++] == 1 - bvar[locb - 1], "Flip4" + loc4.ToString());

                    VarFlaglistCopy2[0] = NUFvar[loc4 - 1];
                    VarFlaglistCopy2[1] = NUFvar[loc4 - 2];
                    VarFlaglistCopy2[2] = Uvar[loc1];
                    loc1++;
                    //Uvar[loc1]=min(NUFvar[loc4-1],NUFvar[loc4-2],loc1), is the  assigment variable of f.
                    model.AddGenConstrMin(Uvar[loc1], VarFlaglistCopy2, 1000, "min_av" + loc1.ToString());

                    Tar.AddTerm(1.0, Uvar[loc1]);
                    Tar.AddTerm(-10000, UFvar[locf]);
                    rec_loc1[i] = loc1;
                    rec_locf[i] = locf;
                    loc1++;
                    locf++;
                }
            }

            //
            GRBLinExpr keyspace = new GRBLinExpr();

            for (i = 0; i < 80; i++)
            {
                keyspace.AddTerm(1.0, kvf[i]);
            }
            Tar.AddConstant((double)con);

            //Add the condition that Tar>=0. It gurantees that there is not any condition whose flag variable is equal to 1.
            model.AddConstr(Tar == 3, "finalcons");
            model.SetObjective(keyspace, GRB.MAXIMIZE);
            //Set the objective function of the model.
            //model.SetObjective(Tar, GRB.MINIMIZE);
            model.Optimize();

            //output the states of key variables and iv variables
            if (model.SolCount > 0)
            {
                sw.WriteLine("****************************Conditions on single key/iv variables***************************\n");
                Console.Write("Free Key bits:\n");
                sw.Write("Free Key bits:\n");
                for (i = 0; i < 80; i++)
                {
                    if ((keyvar[i].X == 0) && (kvf[i].X == 1))
                    {
                        Console.Write(i + ",");
                        sw.Write(i + ",");
                    }
                }
                Console.WriteLine();
                sw.WriteLine();

                Console.Write("Key bits set to 1:\n");
                sw.Write("Key bits set to 1:\n");
                for (i = 0; i < 80; i++)
                {
                    if ((keyvar[i].X == 1) && (kvf[i].X == 0))
                    {
                        Console.Write(i + ",");
                        sw.Write(i + ",");
                    }
                }
                Console.WriteLine();
                sw.WriteLine();

                Console.Write("Key bits set 0:\n");
                sw.Write("Key bits set 0:\n");
                for (i = 0; i < 80; i++)
                {
                    if ((keyvar[i].X == 0) && (kvf[i].X == 0))
                    {
                        Console.Write(i + ",");
                        sw.Write(i + ",");
                    }
                }
                Console.WriteLine();
                sw.WriteLine();

                //for (i = 0; i < loc2; i++)
                //{
                //    if (Vvar[i].X > 1)
                //    {
                //        Console.Write(Vvar[i].VarName + " " + Vvar[i].X + "\n");
                //    }

                //}

                Console.WriteLine("*******************************************************\n");
                sw.WriteLine("*******************************************************\n");

                Console.Write("Free Iv bits:\n");
                sw.Write("Free Iv bits:\n");
                for (i = 0; i < 80; i++)
                {
                    if ((ivvar[i].X == 0) && (vvf[i].X == 1))
                    {
                        Console.Write(i + ",");
                        sw.Write(i + ",");
                    }
                }
                Console.WriteLine();
                sw.WriteLine();

                Console.Write("Iv bits set to 1:\n");
                sw.Write("Iv bits set to 1:\n");
                for (i = 0; i < 80; i++)
                {
                    if ((ivvar[i].X == 1) && (vvf[i].X == 0))
                    {
                        Console.Write(i + ",");
                        sw.Write(i + ",");
                    }
                }
                Console.WriteLine();
                sw.WriteLine();

                Console.Write("Iv bits set to 0:\n");
                sw.Write("Iv bits set to 0:\n");
                for (i = 0; i < 80; i++)
                {
                    if ((ivvar[i].X == 0) && (vvf[i].X == 0))
                    {
                        Console.Write(i + ",");
                        sw.Write(i + ",");
                    }
                }
                Console.WriteLine();
                sw.WriteLine();

                double aa = Tar.Value;
                Console.WriteLine("*****************The number of 1's*****************");
                Console.WriteLine(aa);
                Console.WriteLine("***************************************************");
                sw.WriteLine("***********************The assigment/flag variable of key and iv variables***********************");
                for (i = 0; i < 80; i++)
                {
                    Console.Write(keyvar[i].VarName + "= " + keyvar[i].X + " " + kvf[i].VarName + "= " + kvf[i].X + "\n");
                    sw.Write(keyvar[i].VarName + "= " + keyvar[i].X + " " + kvf[i].VarName + "= " + kvf[i].X + "\n");
                }
                Console.WriteLine("*******************************");
                for (i = 0; i < 80; i++)
                {
                    Console.Write(ivvar[i].VarName + "= " + ivvar[i].X + " " + vvf[i].VarName + "= " + vvf[i].X + "\n");
                    sw.Write(ivvar[i].VarName + "= " + ivvar[i].X + " " + vvf[i].VarName + "= " + vvf[i].X + "\n");
                }
                Console.WriteLine();
                //
                StreamReader rw = new StreamReader("ConSet.txt");
                sw.WriteLine("***************The concrete conditions****************");
                for (j = 0; j < consnum; j++)
                {
                    string onecon = rw.ReadLine();
                    sw.WriteLine(onecon + "=" + Uvar[rec_loc1[j]].X);
                }

                sw.Close();
            }
        }
        public HttpResponseMessage Optimize(string RunName)
        {
            using (var dbConn = new ApplicationDbContext())
            {
                //Variables for students, semesters, courses, and course/semester offerings
                students = dbConn.StudentPreferences.Where(m => m.IsActive == true).Include(m => m.Courses).Include(m => m.Student.CompletedCourses).OrderByDescending(m => m.Student.CompletedCourses.Count()).ToArray();
                crssems = dbConn.CourseSemesters.Where(m => m.IsActive == true).Include(m => m.Course).Include(m => m.Semester).ToArray();
                courses = crssems.Select(m => m.Course).Distinct().ToArray();
                sems = crssems.Select(m => m.Semester).Distinct().OrderBy(m => m.Type).OrderBy(m => m.Year).ToArray();

                var completed = dbConn.CompletedCourses.ToList();
                try
                {
                    GRBEnv env = new GRBEnv("mip1.log");
                    GRBModel model = new GRBModel(env);
                    model.Set(GRB.StringAttr.ModelName, "Course Optimizer");
                    GRBVar[,] slacks = new GRBVar[courses.Length, sems.Length];

                    //Assignment of student, course, and semester.  Student must have a desire to take the coure, has not taken the course, and the course is offered to be included
                    GRBVar[,,] CourseAllocation = new GRBVar[students.Length, courses.Length, sems.Length];
                    for (int i = 0; i < students.Length; i++)
                    {
                        for (int j = 0; j < courses.Length; j++)
                        {
                            for (int k = 0; k < sems.Length; k++)
                            {
                                if (students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID) && crssems.Contains(crssems.SingleOrDefault(m => m.Course == courses[j] && m.Semester == sems[k])))
                                    CourseAllocation[i, j, k] = model.AddVar(0, 1, 1, GRB.BINARY, "students." + (i + 1).ToString() + "_Course." + (j + 1).ToString() + "_Semester." + (k + 1).ToString());
                                else
                                    CourseAllocation[i, j, k] = model.AddVar(0, 0, 1, GRB.BINARY, "students." + (i + 1).ToString() + "_Course." + (j + 1).ToString() + "_Semester." + (k + 1).ToString());
                            }
                        }
                    }
                    model.Set(GRB.IntAttr.ModelSense, 1);
                    model.Update();

                    //MUST TAKE DESIRED COURSE ONLY ONCE
                    //Constrains the students to only take courses they desire once and for when the course is offered and does not allow a repeat of a course in another semester
                    for (int i = 0; i < students.Length; i++)
                    {
                        for (int j = 0; j < courses.Length; j++)
                        {
                            if (students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID))
                            {
                                GRBLinExpr constStudentDesiredCourses = 0.0;
                                for (int k = 0; k < sems.Length; k++)
                                {
                                    if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year))
                                        constStudentDesiredCourses.AddTerm(1.0, CourseAllocation[i, j, k]);
                                }
                                String sStudentDesiredCourses = "DesiredCourse." + j + 1 + "_Student." + i + 1;
                                model.AddConstr(constStudentDesiredCourses == 1, sStudentDesiredCourses);
                            }
                        }

                        //MAX COURSES PER SEMESTER
                        //Constrains the students to only have a maximum number of 2 courses per semester.
                        for (int k = 0; k < sems.Length; k++)
                        {
                            GRBLinExpr constMaxPerSem = 0.0;
                            for (int j = 0; j < courses.Length; j++)
                            {
                                if (!completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID) && (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year)))
                                    constMaxPerSem.AddTerm(1, CourseAllocation[i, j, k]);
                            }
                            String sCourseSem = "maxCourseStudent." + i + 1 + "_Semester." + k + 1;
                            model.AddConstr(constMaxPerSem <= MAX_COURSES_PER_SEMESTER, sCourseSem);
                        }

                        //PREREQUISITES
                        //Constrains the students to take prerequisite courses prior to taking a course that needs the prerequisite
                        for (int j = 0; j < courses.Length; j++)
                        {
                            if (courses[j].Prerequisites.Any() && students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID))
                            {

                                foreach (var prereq in courses[j].Prerequisites)
                                {
                                    int prereqIndex = Array.IndexOf(courses, prereq);
                                    GRBLinExpr coursePrereqConst1 = 0.0;
                                    GRBLinExpr coursePrereqConst2 = 0.0;
                                    if (!completed.Any(m => m.GaTechId == students[i].GaTechId && m.Course.ID == prereq.ID))
                                    {

                                        for (int k = 0; k < sems.Length; k++)
                                        {

                                            if (prereqIndex >= 0)
                                            {
                                                coursePrereqConst1.AddTerm(k + 1, CourseAllocation[i, prereqIndex, k]);
                                                coursePrereqConst2.AddTerm(k, CourseAllocation[i, j, k]);
                                            }
                                        }
                                    }
                                    model.AddConstr(coursePrereqConst1, GRB.LESS_EQUAL, coursePrereqConst2, "PREREQ_Student" + i + "_Course+" + j + "_Prereq" + prereqIndex);

                                }

                            }
                        }
                    }

                    //SENIORITY
                    //Students are already ordered from dB query by seniority in descending order and puts a preference to senior students over the next student that desires that
                    //same course with less seniority.
                    for (int j = 0; j < courses.Length; j++)
                    {
                        for (int i = 0; i < students.Length - 1; i++)
                        {
                            if (students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID))
                            {
                                int SemsRemain = (students[i].Courses.Count - students[i].Student.CompletedCourses.Count) / 2 + (students[i].Courses.Count - students[i].Student.CompletedCourses.Count) % 2;
                                for (int n = i + 1; n < students.Length; n++)
                                {
                                    if (students[n].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[n].GaTechId && courses[j].ID == m.Course_ID))
                                    {
                                        GRBLinExpr​ seniority = 0.0;
                                        for (int k = 0; k < sems.Length; k++)
                                        {
                                            if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year))
                                            {
                                                if (k <= SemsRemain)
                                                {
                                                    seniority​.AddTerm(1.0, CourseAllocation[i, j, k]);
                                                    seniority​.AddTerm(-1.0, CourseAllocation​[n, j, k]);
                                                }
                                                else
                                                {
                                                    seniority​.AddTerm(-1.0, CourseAllocation[i, j, k]);
                                                    seniority​.AddTerm(1.0, CourseAllocation​[n, j, k]);
                                                }
                                            }
                                        }
                                        model.AddConstr(seniority, GRB.GREATER_EQUAL, 0, "Seniority for Student." + students[i] + "_Course." + courses[j]);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    //Add the slack variable for all semester & course offerings then constrain the maximum number of students
                    //to take a couse in a semester.
                    for (int k = 0; k < sems.Length; k++)
                    {
                        for (int j = 0; j < courses.Length; j++)
                        {
                            if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year))
                            {
                                slacks[j, k] = model.AddVar(0, GRB.INFINITY, 0, GRB.INTEGER, sems[k].Type.ToString() + "." + sems[k].Year.ToString() + "." + courses[j].Name + ".Slacks");
                                GRBLinExpr constMaxStudCrsSem = 0.0;
                                for (int i = 0; i < students.Length; i++)
                                {
                                    if (!completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID))
                                        constMaxStudCrsSem.AddTerm(1.0, CourseAllocation[i, j, k]);
                                }
                                model.Update();
                                constMaxStudCrsSem.AddTerm(-1.0, slacks[j, k]);
                                model.AddConstr(constMaxStudCrsSem <= crssems.Single(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year).StudentLimit, sems[k].Type.ToString() + "." + sems[k].Year.ToString() + "." + courses[j].Name);
                            }
                        }
                    }

                    //Add total slack to the optimization model for all courses in the semesters they are offered.
                    GRBVar totSlack = model.AddVar(0, GRB.INFINITY, 0, GRB.INTEGER, "totSlack");
                    GRBLinExpr lhs = new GRBLinExpr();
                    lhs.AddTerm(-1.0, totSlack);
                    for (int j = 0; j < courses.Length; j++)
                    {
                        for (int k = 0; k < sems.Length; k++)
                        {
                            if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year))
                                lhs.AddTerm(1.0, slacks[j, k]);
                        }
                    }
                    model.Update();
                    model.AddConstr(lhs, GRB.EQUAL, 0, "totSlack");

                    // Objective: minimize the total slack
                    GRBLinExpr obj = new GRBLinExpr();
                    obj.AddTerm(1.0, totSlack);
                    model.SetObjective(obj);

                    //Optimize the model to minimize the total slack and maximize students to course offerings based on input variables and constraints.
                    model.Optimize();

                    //Write Results optimization results to database
                    writeResults(CourseAllocation, students, courses, sems, crssems, dbConn, Convert.ToInt32(model.Get(GRB.DoubleAttr.ObjVal)), RunName);

                    //Clean-Up
                    model.Dispose();
                    env.Dispose();
            }
                catch (Exception e)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "An Error occured while running the optimization.");
            }
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        }
Esempio n. 32
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 };

            // 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. 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,
                                     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,
                                 Shifts[s] + "Slack");
            }

            // 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,
                                            Workers[w] + "TotShifts");
            }

            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 == shiftRequirements[s], Shifts[s]);
            }

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

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

            // Objective: minimize the total slack
            model.SetObjective(1.0 * totSlack);

            // Optimize
            int status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts);
            if (status != GRB.Status.OPTIMAL)
            {
                return;
            }

            // Constrain the slack by setting its upper and lower bounds
            totSlack.UB = totSlack.X;
            totSlack.LB = totSlack.X;

            // Variable to count the average number of shifts worked
            GRBVar avgShifts =
                model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "avgShifts");

            // Variables to count the difference from average for each worker;
            // note that these variables can take negative values.
            GRBVar[] diffShifts = new GRBVar[nWorkers];
            for (int w = 0; w < nWorkers; ++w)
            {
                diffShifts[w] = model.AddVar(-GRB.INFINITY, GRB.INFINITY, 0,
                                             GRB.CONTINUOUS, Workers[w] + "Diff");
            }

            // Constraint: compute the average number of shifts worked
            lhs = new GRBLinExpr();
            for (int w = 0; w < nWorkers; ++w)
            {
                lhs.AddTerm(1.0, totShifts[w]);
            }
            model.AddConstr(lhs == nWorkers * avgShifts, "avgShifts");

            // Constraint: compute the difference from the average number of shifts
            for (int w = 0; w < nWorkers; ++w)
            {
                model.AddConstr(totShifts[w] - avgShifts == diffShifts[w],
                                Workers[w] + "Diff");
            }

            // Objective: minimize the sum of the square of the difference from the
            // average number of shifts worked
            GRBQuadExpr qobj = new GRBQuadExpr();
            for (int w = 0; w < nWorkers; ++w)
            {
                qobj.AddTerm(1.0, diffShifts[w], diffShifts[w]);
            }
            model.SetObjective(qobj);

            // Optimize
            status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts);
            if (status != GRB.Status.OPTIMAL)
            {
                return;
            }

            // Dispose of model and env
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " +
                              e.Message);
        }
    }
Esempio n. 33
0
    protected static bool dense_optimize(GRBEnv    env,
                   int       rows,
                   int       cols,
                   double[]  c,      // linear portion of objective function
                   double[,] Q,      // quadratic portion of objective function
                   double[,] A,      // constraint matrix
                   char[]    sense,  // constraint senses
                   double[]  rhs,    // RHS vector
                   double[]  lb,     // variable lower bounds
                   double[]  ub,     // variable upper bounds
                   char[]    vtype,  // variable types (continuous, binary, etc.)
                   double[]  solution)
    {
        bool success = false;

        try {
          GRBModel model = new GRBModel(env);

          // Add variables to the model

          GRBVar[] vars = model.AddVars(lb, ub, null, vtype, null);
          model.Update();

          // Populate A matrix

          for (int i = 0; i < rows; i++) {
        GRBLinExpr expr = new GRBLinExpr();
        for (int j = 0; j < cols; j++)
          if (A[i,j] != 0)
            expr.AddTerm(A[i,j], vars[j]); // Note: '+=' would be much slower
        model.AddConstr(expr, sense[i], rhs[i], "");
          }

          // Populate objective

          GRBQuadExpr obj = new GRBQuadExpr();
          if (Q != null) {
        for (int i = 0; i < cols; i++)
          for (int j = 0; j < cols; j++)
            if (Q[i,j] != 0)
              obj.AddTerm(Q[i,j], vars[i], vars[j]); // Note: '+=' would be much slower
        for (int j = 0; j < cols; j++)
          if (c[j] != 0)
            obj.AddTerm(c[j], vars[j]); // Note: '+=' would be much slower
        model.SetObjective(obj);
          }

          // Solve model

          model.Optimize();

          // Extract solution

          if (model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) {
        success = true;

        for (int j = 0; j < cols; j++)
          solution[j] = vars[j].Get(GRB.DoubleAttr.X);
          }

          model.Dispose();

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

        return success;
    }
    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");
            model.ComputeIIS();
            Console.WriteLine("\nThe following constraint(s) "
                              + "cannot be satisfied:");
            foreach (GRBConstr c in model.GetConstrs())
            {
                if (c.IISConstr == 1)
                {
                    Console.WriteLine(c.ConstrName);
                }
            }

            // Dispose of model and env
            model.Dispose();
            env.Dispose();
        } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " +
                              e.Message);
        }
    }
    static void Main()
    {
        try{
            // Sample data
            int      groundSetSize = 10;
            double[] objCoef = new double[] { 32, 32, 15, 15, 6, 6, 1, 1, 1, 1 };
            double[] knapsackCoef = new double[] { 16, 16, 8, 8, 4, 4, 2, 2, 1, 1 };
            double   Budget = 33;
            int      e, status, nSolutions;

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

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

            // Initialize decision variables for ground set:
            // x[e] == 1 if element e is chosen
            GRBVar[] Elem = model.AddVars(groundSetSize, GRB.BINARY);
            model.Set(GRB.DoubleAttr.Obj, Elem, objCoef, 0, groundSetSize);

            for (e = 0; e < groundSetSize; e++)
            {
                Elem[e].VarName = string.Format("El{0}", e);
            }

            // 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(knapsackCoef[e], 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 = 1024;

            // Limit the search space by setting a gap for the worst possible solution that will be accepted
            model.Parameters.PoolGap = 0.10;

            // do a systematic search for the k-best solutions
            model.Parameters.PoolSearchMode = 2;

            // save problem
            model.Write("poolsearch_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
            for (e = 0; e < nSolutions; e++)
            {
                model.Parameters.SolutionNumber = e;
                Console.Write("{0} ", model.PoolObjVal);
                if (e % 15 == 14)
                {
                    Console.WriteLine();
                }
            }
            Console.WriteLine();

            // Print fourth best set if available
            if (nSolutions >= 4)
            {
                model.Parameters.SolutionNumber = 3;

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

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