private void SetupGurobiEnvironmentAndModel() { // Model env = new GRBEnv(); model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "diet"); }
///<summary>Create a batch request for given problem file</summary> static string newbatchrequest(string filename) { string batchID = ""; // Start environment, create Model object from file GRBEnv env = setupbatchenv(); env.Start(); GRBModel model = new GRBModel(env, filename); try { // Set some parameters model.Set(GRB.DoubleParam.MIPGap, 0.01); model.Set(GRB.IntParam.JSONSolDetail, 1); // Define tags for some variables to access their values later int count = 0; foreach (GRBVar v in model.GetVars()) { v.VTag = "Variable" + count; count += 1; if (count >= 10) { break; } } // Submit batch request batchID = model.OptimizeBatch(); // Dispose of model and env } finally { model.Dispose(); env.Dispose(); } return(batchID); }
static void SolvePrimal(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs) { GRBModel m = new GRBModel(env); Dictionary <string, GRBVar> distances = new Dictionary <string, GRBVar>(); // pi foreach (string node in nodes_set) { distances[node] = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "distance." + node); } m.Update(); distances[ORIGIN].Set(GRB.DoubleAttr.Obj, -1); distances[DESTINATION].Set(GRB.DoubleAttr.Obj, 1); m.Set(GRB.IntAttr.ModelSense, -1); Dictionary <Arc, GRBConstr> constrs = new Dictionary <Arc, GRBConstr>(); foreach (Arc a in arcs) { constrs[a] = m.AddConstr(distances[a.dest] <= distances[a.source] + a.length, "distance_con." + a.source + "." + a.dest); } m.Update(); m.Write("shortest_path.lp"); m.Optimize(); foreach (var pair in distances) { Console.WriteLine("distance to {0} is {1}", pair.Key, pair.Value.Get(GRB.DoubleAttr.X)); } foreach (var pair in constrs) { GRBConstr con = pair.Value; if (con.Get(GRB.DoubleAttr.Pi) > 0.5) { Console.WriteLine("Arc {0}, {1} is in shortest path", pair.Key.source, pair.Key.dest); } } Console.WriteLine("Length of shortest path is {0}", m.Get(GRB.DoubleAttr.ObjVal)); m.Dispose(); }
private GRBVar[,] _x; // starting time of job j on machine a #endregion Fields #region Constructors public GurobiJspModel(ProblemInstance prob, string name, int tmlim_min) { _n = prob.NumJobs; _m = prob.NumMachines; Info = "Starting gurobi optimisation"; _fileName = String.Format("jssp.{0}.log", name); // Model try { _env = new GRBEnv(_fileName); if (tmlim_min > 0) _env.Set(GRB.DoubleParam.TimeLimit, tmlim_min*60); // time limit is set to seconds! _env.Set(GRB.IntParam.LogToConsole, 0); _model = new GRBModel(_env); _model.Set(GRB.StringAttr.ModelName, "jsp"); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } DecisionVariables(); ProcessingOrder(prob.Procs, prob.Sigma); DisjunctiveCondition(prob.Procs); Objective(prob.Procs, prob.Sigma); //TrueOptimumDecVars = Optimise(out TrueOptimum); //if (TrueOptimum > 0) // Objective cutoff // _model.GetEnv().Set(GRB.DoubleParam.Cutoff, TrueOptimum + 0.5); /* Indicates that you aren't interested in solutions whose objective values * are worse than the specified value. If the objective value for the optimal * solution is better than the specified cutoff, the solver will return the * optimal solution. Otherwise, it will terminate with a CUTOFF status. */ // seems to be only for LP relaxation, not MIP objective }
public void BuildAndSolveDietLp() { DietLpProblem = new DietLpProblem(); SetupGurobiEnvironmentAndModel(); DietLpProblem.SetupDecisionVariables(model); // The objective is to minimize the costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); DietLpProblem.AddNutritionConstraints(model); OptimizeAndPrintSolution(); AddLimitDiaryConstraint(); OptimizeAndPrintSolution(); DisposeModelAndEnvironment(); }
public void SetRuntimeOptions() { model.Set(GRB.DoubleParam.TimeLimit, parameters.time_limit); model.Set(GRB.IntParam.SolutionLimit, parameters.max_solutions); }
static void Main() { try { // Sample data // Sets of days and workers string[] Shifts = new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string[] Workers = new string[] { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" }; int nShifts = Shifts.Length; int nWorkers = Workers.Length; // Number of workers required for each shift double[] shiftRequirements = new double[] { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 }; // Amount each worker is paid to work one shift double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 }; // Worker availability: 0 if the worker is unavailable for a shift double[,] availability = new double[, ] { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "assignment"); // Assignment variables: x[w][s] == 1 if worker w is assigned // to shift s. Since an assignment model always produces integer // solutions, we use continuous variables and solve as an LP. GRBVar[,] x = new GRBVar[nWorkers, nShifts]; for (int w = 0; w < nWorkers; ++w) { for (int s = 0; s < nShifts; ++s) { x[w, s] = model.AddVar(0, availability[w, s], pay[w], GRB.CONTINUOUS, Workers[w] + "." + Shifts[s]); } } // The objective is to minimize the total pay costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Constraint: assign exactly shiftRequirements[s] workers // to each shift s for (int s = 0; s < nShifts; ++s) { GRBLinExpr lhs = 0.0; for (int w = 0; w < nWorkers; ++w) { lhs.AddTerm(1.0, x[w, s]); } model.AddConstr(lhs == shiftRequirements[s], Shifts[s]); } // Optimize model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { Console.WriteLine("The optimal objective is " + model.Get(GRB.DoubleAttr.ObjVal)); return; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } // Do IIS Console.WriteLine("The model is infeasible; computing IIS"); model.ComputeIIS(); Console.WriteLine("\nThe following constraint(s) " + "cannot be satisfied:"); foreach (GRBConstr c in model.GetConstrs()) { if (c.Get(GRB.IntAttr.IISConstr) == 1) { Console.WriteLine(c.Get(GRB.StringAttr.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 // 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.Set(GRB.StringAttr.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"); } // Update model to integrate new variables model.Update(); 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.Set(GRB.DoubleAttr.UB, totSlack.Get(GRB.DoubleAttr.X)); totSlack.Set(GRB.DoubleAttr.LB, totSlack.Get(GRB.DoubleAttr.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"); } // Update model to integrate new variables model.Update(); // 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); } }
public void ModeloDARP() { string Agora = Convert.ToString(DateTime.Now); string[] a = Agora.Split(' '); string[] a0 = a[0].Split('/'); string[] a1 = a[1].Split(':'); Agora = a0[0] + "_" + a0[1] + "_" + a0[2] + "_" + a1[0] + "_" + a1[1] + "_" + a1[2]; /// Calcundo algumas constantes que usamos na linearização da carga e janela de tempo double[,,] M = new double[problema.NumeroDeCarros, problema.TamanhoMaximo, problema.TamanhoMaximo]; double[,,] U = new double[problema.NumeroDeCarros, problema.TamanhoMaximo, problema.TamanhoMaximo]; for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { M[k, i, j] = Math.Max(0, problema.usuario[i].InstanteSaida + problema.usuario[i].Duracao + +problema.Distancias[i, j] - problema.usuario[j].InstanteChegada); U[k, i, j] = Math.Min(frota.Capacidade, frota.Capacidade + problema.usuario[i].Carga); } } } /////////////// /////////////// string nome = Convert.ToString(problema.NumeroDeClientes) + '_' + Convert.ToString(problema.NumeroDeCarros) + "_" + Convert.ToString(frota.Capacidade); string caminho = @"C:\Users\hcspe\Documents\Doutorado\TeseUberPool\Classe_Rotas_SARP\MSCordeau\saidas\"; // Model GRBEnv env = new GRBEnv(caminho + "outputSARPTeste(" + Agora + "_" + nome + ").log"); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "SARPTeste"); model.Set(GRB.DoubleParam.TimeLimit, 3600); ///// Declaração de variáveis // Variável x GRBVar[,,] x = new GRBVar[problema.NumeroDeCarros, problema.TamanhoMaximo, problema.TamanhoMaximo]; for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { for (int k = 0; k < problema.NumeroDeCarros; k++) { x[k, i, j] = model.AddVar(0, 1, problema.Distancias[i, j], GRB.BINARY, "x" + k + "_" + i + "_" + j); if (i == problema.TamanhoMaximo) { x[k, i, j].UB = 0.0; } } } } // Variável B do tempo no nó i GRBVar[,] B = new GRBVar[problema.NumeroDeCarros, problema.TamanhoMaximo]; for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int k = 0; k < problema.NumeroDeCarros; k++) { B[k, i] = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "B" + i + "_" + k); } } // Variavel Q da carga no nó i GRBVar[,] Q = new GRBVar[problema.NumeroDeCarros, problema.TamanhoMaximo]; for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int k = 0; k < problema.NumeroDeCarros; k++) { Q[k, i] = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "Q" + i + "_" + k); } } // Varivavel L tempo de viagem do usuario quando passa por i GRBVar[,] L = new GRBVar[problema.NumeroDeCarros, problema.TamanhoMaximo]; for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int k = 0; k < problema.NumeroDeCarros; k++) { L[k, i] = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "L" + i + "_" + k); } } ///////////////////////// Senso do modelo model.Set(GRB.IntAttr.ModelSense, GRB.MINIMIZE); ///////////////////////// Restrições // Add constraints // Restrição 2 GRBLinExpr soma2; GRBLinExpr soma3; for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 1; i <= problema.NumeroDeClientes; i++) { soma2 = 0; soma3 = 0; for (int j = 0; j < problema.TamanhoMaximo; j++) { soma2.AddTerm(1, x[k, i, j]); soma3.AddTerm(1, x[k, problema.NumeroDeClientes + i, j]); } string st = "Rt2" + i + k; model.AddConstr(soma2 - soma3 == 0, st); soma2.Clear(); soma3.Clear(); } } // Restrição 1 GRBLinExpr soma = 0.0; for (int i = 1; i <= problema.NumeroDeClientes; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { for (int k = 0; k < problema.NumeroDeCarros; k++) { soma.AddTerm(1, x[k, i, j]); } } model.AddConstr(soma == 1, "Rt1" + "_" + i); soma.Clear(); } // Restrição 3; GRBLinExpr soma4 = 0; for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { soma4.AddTerm(1, x[k, 0, j]); } model.AddConstr(soma4 == 1, "Rt3" + "_" + k); soma4.Clear(); } // Restrição 4; GRBLinExpr soma5 = 0; GRBLinExpr soma6 = 0; for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo - 1; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { soma5.AddTerm(1, x[k, j, i]); soma6.AddTerm(1, x[k, i, j]); } model.AddConstr(soma5 - soma6 == 0, "Rt4" + i + k); soma5.Clear(); soma6.Clear(); } } // Restrição 5 GRBLinExpr soma7 = 0; for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo; i++) { soma7.AddTerm(1, x[k, i, problema.TamanhoMaximo - 1]); } model.AddConstr(soma7 == 1, "Rt5" + k); soma7.Clear(); } // Restrição 7 Atualizar Q for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { model.AddConstr(Q[k, j] >= Q[k, i] + problema.usuario[j].Carga - U[k, i, j] * (1 - x[k, i, j]), "Rt7_" + k + "_" + i + "_" + j); } } } // Restrição 8 Atualizar B for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { model.AddConstr(B[k, j] >= B[k, i] + problema.usuario[i].Duracao + problema.Distancias[i, j] - M[k, i, j] * (1 - x[k, i, j]), "Rt6_" + k + "_" + i + "_" + j); } } } // Restrição 9 atualizar L for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 1; i <= problema.NumeroDeClientes; i++) { model.AddConstr(L[k, i] == B[k, problema.NumeroDeClientes + i] - B[k, i] - problema.usuario[i].Duracao, "Rt8_" + k + "_" + i); } } // Restrição 10 Intervalo do B limitado por T for (int k = 0; k < problema.NumeroDeCarros; k++) { model.AddConstr(B[k, problema.TamanhoMaximo - 1] - B[k, 0] <= problema.LarguraHorizonte, "Rt9_" + k); } // Restrição 11 janela de B for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo; i++) { model.AddConstr(problema.usuario[i].InstanteChegada <= B[k, i], "RtjanelaBe_" + k + "_" + i); model.AddConstr(B[k, i] <= problema.usuario[i].InstanteSaida, "RtjanelaBl_" + k + "_" + i); } } // Restrição 12 janela de L for (int i = 1; i <= problema.NumeroDeClientes; i++) { for (int k = 0; k < problema.NumeroDeCarros; k++) { model.AddConstr(problema.Distancias[i, problema.NumeroDeClientes + i] <= L[k, i], "Rt10e_" + i + "_" + k); model.AddConstr(L[k, i] <= problema.TempoMaximoViagemUsuario, "Rt10l_" + i + "_" + k); } } // Restrição 12 janela Q for (int i = 1; i < problema.TamanhoMaximo; i++) { for (int k = 0; k < problema.NumeroDeCarros; k++) { model.AddConstr(Math.Max(0, problema.usuario[i].Carga) <= Q[k, i], "Rt11e_" + i + "_" + k); model.AddConstr(Q[k, i] <= Math.Min(problema.frota[0].Capacidade, problema.frota[0].Capacidade + problema.usuario[i].Carga), "Rt11l_" + i + "_" + k); } } string Str = Convert.ToString(problema.NumeroDeClientes) + "_" + Convert.ToString(problema.NumeroDeCarros) + Convert.ToString(problema.frota[0].Capacidade); // Escrever o modelo lp string caminho1 = @"C:\Users\hcspe\Documents\Doutorado\TeseUberPool\Classe_Rotas_SARP\MSCordeau\modelos\Modelo"; model.Write(Str + "_" + Agora + ".lp"); // Otimizar o modelo model.Optimize(); // Arquivos // modelo.Write("C:\Users\hellen\Dropbox\DNA sequencing\codes\DNA_Sequencing_2\Modelos\modelo.lp") // modelo.Write("C:\Users\hellen\Dropbox\DNA sequencing\codes\DNA_Sequencing_2\Modelos\modelo.mps") string caminho2 = @"C:\Users\hcspe\Documents\Doutorado\TeseUberPool\Classe_Rotas_SARP\MSCordeau\solucoes\modelo.ilp"; if (model.Get(GRB.IntAttr.Status) == GRB.Status.INFEASIBLE) { model.ComputeIIS(); //computa o modelo ilp, infactível linear problem; model.Write(caminho2); } string caminho3 = @"C:\Users\hcspe\Documents\Doutorado\TeseUberPool\Classe_Rotas_SARP\MSCordeau\solucoes\solucaoModelo"; // procurar infactibilidade if (model.Get(GRB.IntAttr.Status) != GRB.Status.INFEASIBLE) { if (model.SolCount != 0) { model.Write(caminho3 + Str + "_" + Agora + ".sol"); // modelo.Write("C:\Users\hellen\Dropbox\DNA sequencing\codes\DNA_Sequencing_2\Solucoes\solucao.mst") problema.SolucaoExata = new int[problema.NumeroDeCarros - 1, problema.TamanhoMaximo, problema.TamanhoMaximo]; int qtdnNula = 0; for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { problema.SolucaoExata[k, i, j] = Convert.ToInt32(x[k, i, j].X); if (x[k, i, j].X != 0) { qtdnNula += 1; } } } } problema.SolucaoExataNaoNula = new int[qtdnNula, 3]; int cont = 0; int[] QtdAtendimentosCarro = new int[problema.NumeroDeCarros - 1]; for (int k = 0; k < problema.NumeroDeCarros; k++) { for (int i = 0; i < problema.TamanhoMaximo; i++) { for (int j = 0; j < problema.TamanhoMaximo; j++) { if (x[k, i, j].X != 0) { problema.SolucaoExataNaoNula[cont, 0] = k; problema.SolucaoExataNaoNula[cont, 1] = i; problema.SolucaoExataNaoNula[cont, 2] = j; problema.SolucaoExataNaoNula[cont, 3] = Convert.ToInt32(x[k, i, j].X); cont += 1; if (k == 0) { QtdAtendimentosCarro[k] += 1; } if (k == 1) { QtdAtendimentosCarro[k] += 1; } } } } } frota.Ocupacao = new double[problema.NumeroDeCarros, qtdnNula]; for (int i = 0; i < qtdnNula; i++) { if (problema.usuario[problema.SolucaoExataNaoNula[i, 1]].Carga > 0) { problema.usuario[i].TempoDeViagem = L[problema.SolucaoExataNaoNula[i, 0], problema.SolucaoExataNaoNula[i, 1]].X; } } ///////// Escrever os extras, no caso tempo usuario viagem string caminho4 = @"C:\Users\hcspe\Documents\Doutorado\TeseUberPool\Classe_Rotas_SARP\MSCordeau\Extras\"; caminho4 = caminho4 + Str + "_" + Agora + ".txt"; Stream entrada = File.Create(caminho4); StreamWriter escritor = new StreamWriter(entrada); escritor.WriteLine("Tempo Usuario Viagem"); for (int i = 0; i < qtdnNula; i++) { escritor.Write(Convert.ToString(problema.usuario[i].TempoDeViagem) + " "); } escritor.WriteLine(" "); entrada.Close(); escritor.Close(); } } }
static void Main() { try { GRBEnv env = new GRBEnv("bilinear.log"); GRBModel model = new GRBModel(env); // Create variables GRBVar x = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "x"); GRBVar y = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "y"); GRBVar z = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "z"); // Set objective GRBLinExpr obj = x; model.SetObjective(obj, GRB.MAXIMIZE); // Add linear constraint: x + y + z <= 10 model.AddConstr(x + y + z <= 10, "c0"); // Add bilinear inequality: x * y <= 2 model.AddQConstr(x * y <= 2, "bilinear0"); // Add bilinear equality: x * z + y * z == 1 model.AddQConstr(x * z + y * z == 1, "bilinear1"); // Optimize model try { model.Optimize(); } catch (GRBException e) { Console.WriteLine("Failed (as expected) " + e.ErrorCode + ". " + e.Message); } model.Set(GRB.IntParam.NonConvex, 2); model.Optimize(); Console.WriteLine(x.VarName + " " + x.X); Console.WriteLine(y.VarName + " " + y.X); Console.WriteLine(z.VarName + " " + z.X); Console.WriteLine("Obj: " + model.ObjVal + " " + obj.Value); x.Set(GRB.CharAttr.VType, GRB.INTEGER); model.Optimize(); Console.WriteLine(x.VarName + " " + x.X); Console.WriteLine(y.VarName + " " + y.X); Console.WriteLine(z.VarName + " " + z.X); Console.WriteLine("Obj: " + model.ObjVal + " " + obj.Value); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
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); }
static void Main() { try { // Sample data // Sets of days and workers string[] Shifts = new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string[] Workers = new string[] { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" }; int nShifts = Shifts.Length; int nWorkers = Workers.Length; // Number of workers required for each shift double[] shiftRequirements = new double[] { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 }; // Amount each worker is paid to work one shift double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 }; // Worker availability: 0 if the worker is unavailable for a shift double[,] availability = new double[, ] { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "assignment"); // Assignment variables: x[w][s] == 1 if worker w is assigned // to shift s. Since an assignment model always produces integer // solutions, we use continuous variables and solve as an LP. GRBVar[,] x = new GRBVar[nWorkers, nShifts]; for (int w = 0; w < nWorkers; ++w) { for (int s = 0; s < nShifts; ++s) { x[w, s] = model.AddVar(0, availability[w, s], pay[w], GRB.CONTINUOUS, Workers[w] + "." + Shifts[s]); } } // The objective is to minimize the total pay costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Constraint: assign exactly shiftRequirements[s] workers // to each shift s LinkedList <GRBConstr> reqCts = new LinkedList <GRBConstr>(); for (int s = 0; s < nShifts; ++s) { GRBLinExpr lhs = 0.0; for (int w = 0; w < nWorkers; ++w) { lhs.AddTerm(1.0, x[w, s]); } GRBConstr newCt = model.AddConstr(lhs == shiftRequirements[s], Shifts[s]); reqCts.AddFirst(newCt); } // Optimize model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { Console.WriteLine("The optimal objective is " + model.Get(GRB.DoubleAttr.ObjVal)); return; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } // Add slack variables to make the model feasible Console.WriteLine("The model is infeasible; adding slack variables"); // Set original objective coefficients to zero model.SetObjective(new GRBLinExpr()); // Add a new slack variable to each shift constraint so that the shifts // can be satisfied LinkedList <GRBVar> slacks = new LinkedList <GRBVar>(); foreach (GRBConstr c in reqCts) { GRBColumn col = new GRBColumn(); col.AddTerm(1.0, c); GRBVar newvar = model.AddVar(0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, col, c.Get(GRB.StringAttr.ConstrName) + "Slack"); slacks.AddFirst(newvar); } // Solve the model with slacks model.Optimize(); status = model.Get(GRB.IntAttr.Status); if ((status == GRB.Status.INF_OR_UNBD) || (status == GRB.Status.INFEASIBLE) || (status == GRB.Status.UNBOUNDED)) { Console.WriteLine("The model with slacks cannot be solved " + "because it is infeasible or unbounded"); return; } if (status != GRB.Status.OPTIMAL) { Console.WriteLine("Optimization was stopped with status " + status); return; } Console.WriteLine("\nSlack values:"); foreach (GRBVar sv in slacks) { if (sv.Get(GRB.DoubleAttr.X) > 1e-6) { Console.WriteLine(sv.Get(GRB.StringAttr.VarName) + " = " + sv.Get(GRB.DoubleAttr.X)); } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void Main() { try { // Sample data // Sets of days and workers string[] Shifts = new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string[] Workers = new string[] { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" }; int nShifts = Shifts.Length; int nWorkers = Workers.Length; // Number of workers required for each shift double[] shiftRequirements = new double[] { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 }; // Amount each worker is paid to work one shift double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 }; // Worker availability: 0 if the worker is unavailable for a shift double[,] availability = new double[,] { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "assignment"); // Assignment variables: x[w][s] == 1 if worker w is assigned // to shift s. Since an assignment model always produces integer // solutions, we use continuous variables and solve as an LP. GRBVar[,] x = new GRBVar[nWorkers,nShifts]; for (int w = 0; w < nWorkers; ++w) { for (int s = 0; s < nShifts; ++s) { x[w,s] = model.AddVar(0, availability[w,s], pay[w], GRB.CONTINUOUS, Workers[w] + "." + Shifts[s]); } } // The objective is to minimize the total pay costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Constraint: assign exactly shiftRequirements[s] workers // to each shift s LinkedList<GRBConstr> reqCts = new LinkedList<GRBConstr>(); for (int s = 0; s < nShifts; ++s) { GRBLinExpr lhs = 0.0; for (int w = 0; w < nWorkers; ++w) lhs += x[w,s]; GRBConstr newCt = model.AddConstr(lhs == shiftRequirements[s], Shifts[s]); reqCts.AddFirst(newCt); } // Optimize model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { Console.WriteLine("The optimal objective is " + model.Get(GRB.DoubleAttr.ObjVal)); return; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } // Add slack variables to make the model feasible Console.WriteLine("The model is infeasible; adding slack variables"); // Set original objective coefficients to zero model.SetObjective(new GRBLinExpr()); // Add a new slack variable to each shift constraint so that the shifts // can be satisfied LinkedList<GRBVar> slacks = new LinkedList<GRBVar>(); foreach (GRBConstr c in reqCts) { GRBColumn col = new GRBColumn(); col.AddTerm(1.0, c); GRBVar newvar = model.AddVar(0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, col, c.Get(GRB.StringAttr.ConstrName) + "Slack"); slacks.AddFirst(newvar); } // Solve the model with slacks model.Optimize(); status = model.Get(GRB.IntAttr.Status); if ((status == GRB.Status.INF_OR_UNBD) || (status == GRB.Status.INFEASIBLE) || (status == GRB.Status.UNBOUNDED)) { Console.WriteLine("The model with slacks cannot be solved " + "because it is infeasible or unbounded"); return; } if (status != GRB.Status.OPTIMAL) { Console.WriteLine("Optimization was stopped with status " + status); return; } Console.WriteLine("\nSlack values:"); foreach (GRBVar sv in slacks) { if (sv.Get(GRB.DoubleAttr.X) > 1e-6) { Console.WriteLine(sv.Get(GRB.StringAttr.VarName) + " = " + sv.Get(GRB.DoubleAttr.X)); } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
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); } }
public static void build_initial_model(bool lp_relax) { env = new GRBEnv(true); env.Set("LogFile", "Recoloracao.log"); env.Set(GRB.IntParam.LogToConsole, 0); env.Start(); model = new GRBModel(env); model.ModelName = "Recoloracao"; model.Set(GRB.IntParam.Threads, 1); model.Set(GRB.IntParam.Method, 1); model.Set(GRB.DoubleParam.TimeLimit, 1800); X = new GRBVar[input.nVertices, input.nCores]; var obj = new GRBLinExpr(); for (int i = 0; i < input.nVertices; i++) { for (int j = 0; j < input.nCores; j++) { string nome = "X_ " + i.ToString() + "_c " + j.ToString(); if (lp_relax) { X[i, j] = model.AddVar(0.0, 1.0, 1.0, GRB.CONTINUOUS, nome); } else { X[i, j] = model.AddVar(0.0, 1.0, 1.0, GRB.BINARY, nome); } if (input.caminhoColorido[i] != j + 1) { obj.AddTerm(1, X[i, j]); } } } model.SetObjective(obj, GRB.MINIMIZE); // Restrição 1 for (int i = 0; i < input.nVertices; i++) { GRBLinExpr soma = new GRBLinExpr(); for (int c = 0; c < input.nCores; c++) { soma.AddTerm(1.0, X[i, c]); } model.AddConstr(soma, GRB.EQUAL, 1, "Cor vértice" + i); } // Restrição 2 for (int p = 0; p < input.nVertices - 2; p++) { for (int r = p + 2; r < input.nVertices; r++) { for (int q = p + 1; q < r; q++) { for (int k = 0; k < input.nCores; k++) { model.AddConstr(X[p, k] - X[q, k] + X[r, k], GRB.LESS_EQUAL, 1, "p" + p + "-q" + q + "-r" + r + "-k" + k); } } } } }
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.Set(GRB.StringAttr.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.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Nutrition constraints for (int i = 0; i < nCategories; ++i) { GRBLinExpr ntot = 0.0; for (int j = 0; j < nFoods; ++j) ntot += 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); } }
static void Main(string[] args) { string[] filePaths = Directory.GetFiles(@"./", "*.json"); foreach (string arquivo in filePaths) { //Deserializar o arquivo Json para o c# var json = File.ReadAllText(arquivo); Parametros instancia = JsonConvert.DeserializeObject <Parametros>(json); //Modelo GRBEnv ambiente = new GRBEnv(); GRBModel modelo = new GRBModel(ambiente); modelo.ModelName = "Crew Scheduling Problem"; //número grande int M = 1000; //Variáveis //fração da tarefa i que o membro de equipe n completa na data j GRBVar[,,] x = new GRBVar[instancia.crew, instancia.task, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x[n, i, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "x_" + n + "_" + i + "_" + j); } } } //fração da tarefa i que é completada na data j GRBVar[,] x3 = new GRBVar[instancia.task, instancia.date]; for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x3[i, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "x3_" + i + "_" + j); } } //1 se alguma tarefa i é completada na data j GRBVar[,] x2 = new GRBVar[instancia.task, instancia.date]; for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x2[i, j] = modelo.AddVar(0, 1, 0, GRB.BINARY, "x2_" + i + "_" + j); } } //1 se a tarefa i é concluída dentro do horizonte de planejamento GRBVar[] x4 = new GRBVar[instancia.task]; for (int i = 0; i < instancia.task; i++) { x4[i] = modelo.AddVar(0, 1, -instancia.c[i] * 2, GRB.BINARY, "x4_" + i); } //variável fantasma GRBVar[] vf = new GRBVar[instancia.task]; for (int i = 0; i < instancia.task; i++) { vf[i] = modelo.AddVar(1, 1, instancia.c[i] * 2, GRB.BINARY, "vf_" + i); } //1 se o membro de equipe n está trabalhando na tarefa i na data j mas não na data j+1 GRBVar[,,] x5 = new GRBVar[instancia.crew, instancia.task, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x5[n, i, j] = modelo.AddVar(0, 1, 0.1, GRB.BINARY, "x5_" + n + "_" + i + "_" + j); } } } //1 se parte da tarefa i é completada na data j mas não na data j+1 GRBVar[,] x6 = new GRBVar[instancia.task, instancia.date]; for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x6[i, j] = modelo.AddVar(0, 1, 0.9, GRB.BINARY, "x6_" + i + "_" + j); } } //1 se o membro da equipe n vai trabalhar na data j GRBVar[,] y = new GRBVar[instancia.crew, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int j = 0; j < instancia.date; j++) { y[n, j] = modelo.AddVar(0, 1, instancia.hours_per_shift, GRB.BINARY, "y_" + n + "_" + j); } } //1 se membro da equipe n trabalha na tarefa i na data j GRBVar[,,] z = new GRBVar[instancia.crew, instancia.task, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { z[n, i, j] = modelo.AddVar(0, 1, 0.5, GRB.BINARY, "z_" + n + "_" + i + "_" + j); } } } //1 se o membro de equipe n trabalha na tarefa i GRBVar[,] z1 = new GRBVar[instancia.crew, instancia.task]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { z1[n, i] = modelo.AddVar(0, 1, 0.1, GRB.BINARY, "z1_" + n + "_" + i); } } //1 se o membro de equipe n trabalha no local técnico p na data j GRBVar[,,] w = new GRBVar[instancia.crew, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { w[n, p, j] = modelo.AddVar(0, 1, 0, GRB.BINARY, "w_" + n + "_" + p + "_" + j); } } } //1 se o membro de equipe n precisa de transporte entre o local técnico o e o local q na instancia.date j GRBVar[,,,] v = new GRBVar[instancia.crew, instancia.technical_place, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < instancia.date; j++) { v[n, p, q, j] = modelo.AddVar(0, 1, 0, GRB.BINARY, "v_" + n + "_" + p + "_" + q + "_" + j); } } } } //se a equipe n precisa de transporte para o local técnico p de outro local técnico na data j GRBVar[,,] w1 = new GRBVar[instancia.crew, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { w1[n, p, j] = modelo.AddVar(0, 1, 0, GRB.BINARY, "w1_" + n + "_" + p + "_" + j); } } } //se a equipe n precisa de transporte do local técnico p para outro local técnico GRBVar[,,] w2 = new GRBVar[instancia.crew, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { w2[n, p, j] = modelo.AddVar(0, 1, 0, GRB.BINARY, "w2_" + n + "_" + p + "_" + j); } } } //Função objetivo modelo.ModelSense = GRB.MINIMIZE; //Restrições GRBLinExpr exp = 0.0; GRBLinExpr exp2 = 0.0; GRBLinExpr exp3 = 0.0; //Restrições com relação a tarefa //restrição 2 //a tarefa deve ser concluída dentro do horizonte de planejamento for (int i = 0; i < instancia.task; i++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { for (int j = 0; j < instancia.date; j++) { exp.AddTerm(1, x[n, i, j]); } } modelo.AddConstr(exp == x4[i], "R2_" + i); } //restrição 3 //o número total de horas por turno não deve ser excedido for (int j = 0; j < instancia.date; j++) { for (int n = 0; n < instancia.crew; n++) { exp.Clear(); exp2.Clear(); exp3.Clear(); for (int i = 0; i < instancia.task; i++) { exp.AddTerm(instancia.c[i], x[n, i, j]); } for (int p = 0; p < instancia.technical_place; p++) { exp2.AddTerm(2 * instancia.tm[p], w[n, p, j]); exp2.AddTerm(-instancia.tm[p], w1[n, p, j]); exp2.AddTerm(-instancia.tm[p], w2[n, p, j]); } for (int p = 0; p < instancia.technical_place; p++) { for (int q = 0; q < instancia.technical_place; q++) { exp3.AddTerm(instancia.tr[p, q], v[n, p, q, j]); } } modelo.AddConstr(exp + exp2 + exp3 <= instancia.hours_per_shift, "R3_" + j + "_" + n); } } //restrição 4 //a soma das frações das tarefas locadas não pode exceder o total para completar a tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, x[n, i, j]); } modelo.AddConstr(x2[i, j] >= exp, "R4_" + i + "_" + j); } } //restrição 5 //soma de das frações dos membros e equipe num dado dia deve ser igual a x3 for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, x[n, i, j]); } modelo.AddConstr(x3[i, j] == exp, "R5_" + i + "_" + j); } } //restrição 6 //a tarefa i deve ser completada dentro do horizonte de planejamento se gi=1 for (int i = 0; i < instancia.task; i++) { modelo.AddConstr(x4[i] >= instancia.g[i], "R6_" + i); } //restrição 7 //fração da tarefa que é completada num dado dia não deve exceder X4 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(x4[i] >= x[n, i, j], "R7_" + n + "_" + i + "_" + j); } } } //restrição 8 //um membro de equipe não pode ser locado a uma tarefa em um dia em que ele não trabalha for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(y[n, j] >= z[n, i, j], "R8_" + n + "_" + i + "_" + j); } } } //restrição 9 //se o membro de equipe é locado para uma tarefa então z=1 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z[n, i, j] >= x[n, i, j], "R9_" + n + "_" + i + "_" + j); } } } //restrição 10 //a variável z não pode ser 1 se a equipe n não trabalha num dado dia for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z[n, i, j] <= M * x[n, i, j], "R10_" + n + "_" + i + "_" + j); } } } //restrição 11 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z1[n, i] >= z[n, i, j], "R11_" + n + "_" + i + "_" + j); } } } //Restrições de gerenciemanto //restrição 12 //preferencalmente uma tarefa deve concluida pela mesma pessoa que começou trabalhando nela for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date - 1; j++) { modelo.AddConstr(x5[n, i, j] >= z[n, i, j] - z[n, i, j + 1], "R12_" + n + "_" + i + "_" + j); } } } //restrição 13 //uma penalidade será dada ao planejamento se a tarefa i é completada em dias não consecutivos for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date - 1; j++) { modelo.AddConstr(x6[i, j] >= x2[i, j] - x2[i, j + 1], "R13_" + i + "_" + j); } } //restrição 14 //o número mínimo de membros de equipe que podem trabalhar simultaneamente em uma tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, z[n, i, j]); } modelo.AddConstr(exp >= instancia.d1[i] * x2[i, j], "R14_" + i + "_" + j); } } //restrição 15 //o número máximo de membros de equipe que podem trablhar simultaneamente em uma tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, z[n, i, j]); } modelo.AddConstr(exp <= instancia.d2[i] * x2[i, j], "R15_" + i + "_" + j); } } //restrição 16 //número mínimo de membros para trabalhar em um tarefa deve ser respeitado for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(x[n, i, j] <= x3[i, j] / instancia.d1[i], "R16_" + n + "_" + i + "_" + j); } } } //restrição 17 //membros de equipe não podem trabalhar em dias em que eles não estão disponíveis for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z[n, i, j] <= instancia.e[n, j], "R17_" + n + "_" + i + "_" + j); } } } //Restrições com relação a competência //restrição 18 //a combinação do nível de competencias de todos os membros //de equipe deve ser suficiente para cada tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { for (int k = 0; k < instancia.competencies; k++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(instancia.bm3[n, k], z[n, i, j]); } modelo.AddConstr(exp >= x2[i, j] * instancia.bo[i, k] * instancia.level_total, "R18_" + i + "_" + j + "_" + k); } } } //restrição 19 //pelo menos um membro de equipe deve ter nível 3 de competencia para a tarefa i for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { for (int k = 0; k < instancia.competencies; k++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(instancia.bm[n, k], z[n, i, j]); } modelo.AddConstr(exp >= x2[i, j] * instancia.bo[i, k], "R19_" + i + "_" + j + "_" + k); } } } //restrição 20 //pelo menos um mebro de equipe tem nível de competencia 3 se vários membros de equipe trabalham na mesma tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { for (int k = 0; k < instancia.competencies; k++) { exp.Clear(); exp2.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(instancia.bm[n, k], x[n, i, j]); exp2.AddTerm(instancia.bm2[n, k], x[n, i, j]); } modelo.AddConstr(exp >= exp2 * (double)(1 / instancia.d1[i]), "R20_" + i + "_" + j + "_" + k); } } } //Restrições com relação ao transporte //restrição 21 //cada membro de equipe trabalha em um local técnico em que a tarefa está localizada for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int i = 0; i < instancia.task; i++) { exp.AddTerm(instancia.tp[i, p], z[n, i, j]); } modelo.AddConstr(w[n, p, j] <= exp, "R21_" + n + "_" + p + "_" + j); } } } //restrição 22 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int i = 0; i < instancia.task; i++) { exp.AddTerm(instancia.tp[i, p], z[n, i, j]); } modelo.AddConstr(w[n, p, j] * M >= exp, "R22_" + n + "_" + p + "_" + j); } } } //restrição 23 //o membro de equipe só é transportado entre os locais técnicos que as tarefas dele estão localizadas for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int q = 0; q < instancia.technical_place; q++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(exp <= w[n, p, j] * M, "R23_" + n + "_" + p + "_" + j); } } } //restrição 24 for (int n = 0; n < instancia.crew; n++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int p = 0; p < instancia.technical_place; p++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(exp <= w[n, q, j] * M, "R24_" + n + "_" + q + "_" + j); } } } //restrição 25 //se o membro de equipe trabalha em mais do que um local técninco durante o turno for (int n = 0; n < instancia.crew; n++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int p = 0; p < instancia.technical_place; p++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(w1[n, q, j] == exp, "R25_" + n + "_" + q + "_" + j); } } } //restrição 26 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int q = 0; q < instancia.technical_place; q++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(w2[n, p, j] == exp, "R26_" + n + "_" + p + "_" + j); } } } //restrição 27 //cada membro de equipe pode apenas ser transportado de e para cada local técnico uma vez por dia for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(w1[n, p, j] <= 1, "R27_" + n + "_" + p + "_" + j); } } } //restrição 28 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(w2[n, p, j] <= 1, "R28_" + n + "_" + p + "_" + j); } } } //restrição 29 //funcionário será transportado apenas uma vez do e para o depósito for (int n = 0; n < instancia.crew; n++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int p = 0; p < instancia.technical_place; p++) { exp.AddTerm(2, w[n, p, j]); exp.AddTerm(-1, w1[n, p, j]); exp.AddTerm(-1, w2[n, p, j]); } modelo.AddConstr(exp == 2 * y[n, j], "R29_" + n + "_" + j); } } //aleatório int semente = 0; Random aleatorio = new Random(semente); //relógio Stopwatch relogio = new Stopwatch(); //variável para contar quantidade de soluções sem melhoria int sem_melhoria = 0; //variável para guardar melhor scenário int melhorCenario = 0; //variável para guardar número de cenários int num_scenarios = 5; //função que gera números aleatórios sem repetir int[] AleatorioaSemRepetir(int quantidade, int minimo, int maximo) { int sorteado; int[] NoRepet = new int[quantidade]; int posicao = 0; List <int> guarda = new List <int>(); while (posicao < quantidade) { sorteado = aleatorio.Next(minimo, maximo); if (!guarda.Contains(sorteado)) { guarda.Add(sorteado); NoRepet[posicao] = sorteado; posicao++; } } return(NoRepet); } //pega a primeira solução factível do gurobi relogio.Start(); modelo.Parameters.SolutionLimit = 1; modelo.Optimize(); //matriz para guardar melhor z double[,,] melhor_z = new double[instancia.crew, instancia.task, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { melhor_z[n, i, j] = z[n, i, j].X; } } } //melhor FO double bestFO = modelo.ObjVal; //mudar o gurobi para voltar a resolver o problema por completo modelo.Parameters.SolutionLimit = 2000000000; modelo.Set(GRB.DoubleParam.TimeLimit, 7200); //função fix and optimize para datas void multiCenariosFixAndOptimizeData(int num_scenarios) { // variável para guardar número de cenários int scenarios = 0; //seta o parâmetro do modelo para multiplos scenários modelo.NumScenarios = num_scenarios; //quantas datas ficarão fixas int datasFixas = instancia.date - 2; //vetros que irá guardar datas sorteadas para serem fixas int[] vetorDatas = new int[datasFixas]; //criar os cenários a serem otimizados pelo Gurobi while (scenarios < num_scenarios) { modelo.Parameters.ScenarioNumber = scenarios; //sorteia datas que serão fixadas vetorDatas = AleatorioaSemRepetir(datasFixas, 0, instancia.date); for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { if (vetorDatas.Contains(j)) { z[n, i, j].ScenNUB = melhor_z[n, i, j]; z[n, i, j].ScenNLB = melhor_z[n, i, j]; } else { z[n, i, j].Start = melhor_z[n, i, j]; } } } } semente++; scenarios++; } // Solve multi-scenario model modelo.Optimize(); // descobrir qual melhor cenário for (int s = 0; s < num_scenarios; s++) { modelo.Parameters.ScenarioNumber = s; // o comando modelo.ScenNObjVal devolve o valor da função objetivo do cenário atual double atual_FO = modelo.ScenNObjVal; if (atual_FO < bestFO) { //atualiza melhor cenário e melhor FO bestFO = atual_FO; melhorCenario = s; } else { sem_melhoria++; } } //atualiza a melhor solução de z modelo.Parameters.ScenarioNumber = melhorCenario; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { melhor_z[n, i, j] = z[n, i, j].ScenNX; } } } } // Fix and Optimize Datas //int num_scenarios = 5; //while (sem_melhoria < 20) //{ // multiCenariosFixAndOptimizeData(num_scenarios); // //escreve no console os cenários e suas respectivas FOs // for (int i = 0; i < num_scenarios; i++) // { // modelo.Parameters.ScenarioNumber = i; // Console.WriteLine("Solucao para cenario" + i.ToString() + ":" + modelo.ScenNObjVal.ToString()); // } //} //relogio.Stop(); ////a variável novoModelo recebe o modelo com melhor cenário //modelo.Parameters.ScenarioNumber = melhorCenario; //System.Console.WriteLine("Melhor FO:" + modelo.ObjVal.ToString()); //System.Console.WriteLine($"Tempo total {relogio.ElapsedMilliseconds / 1000} segundos"); //Função Fix and Optimize equipes void multiCenariosFixAndOptimizeEquipes(int num_scenarios) { // variável para guardar número de cenários int scenarios = 0; //seta o parâmetro do modelo para multiplos scenários modelo.NumScenarios = num_scenarios; //quantas datas ficarão fixas int equipesFixas = instancia.crew - 2; //vetros que irá guardar datas sorteadas para serem fixas int[] vetorEquipes = new int[equipesFixas]; //criar os cenários a serem otimizados pelo Gurobi while (scenarios < num_scenarios) { modelo.Parameters.ScenarioNumber = scenarios; //sorteia datas que serão fixadas vetorEquipes = AleatorioaSemRepetir(equipesFixas, 0, instancia.crew); foreach (int n in vetorEquipes) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { z[n, i, j].ScenNUB = melhor_z[n, i, j]; z[n, i, j].ScenNLB = melhor_z[n, i, j]; } } } semente++; scenarios++; } // Solve multi-scenario model modelo.Optimize(); // descobrir qual melhor cenário for (int s = 0; s < num_scenarios; s++) { modelo.Parameters.ScenarioNumber = s; // o comando modelo.ScenNObjVal devolve o valor da função objetivo do cenário atual double atual_FO = modelo.ScenNObjVal; if (atual_FO < bestFO) { //atualiza melhor cenário e melhor FO bestFO = atual_FO; melhorCenario = s; } else { sem_melhoria++; } } modelo.Parameters.ScenarioNumber = melhorCenario; //atualiza a melhor solução de z for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { melhor_z[n, i, j] = z[n, i, j].ScenNX; } } } } // Fix and Optimize equipes //int num_scenarios = 5; //while (sem_melhoria < 20) //{ // multiCenariosFixAndOptimizeEquipes(num_scenarios); // //escreve no console os cenários e suas respectivas FOs // for (int i = 0; i < num_scenarios; i++) // { // modelo.Parameters.ScenarioNumber = i; // Console.WriteLine("Solucao para cenario" + i.ToString() + ":" + modelo.ScenNObjVal.ToString()); // } //} //relogio.Stop(); ////a variável novoModelo recebe o modelo com melhor cenário //modelo.Parameters.ScenarioNumber = melhorCenario; //System.Console.WriteLine("Melhor FO:" + modelo.ObjVal.ToString()); //System.Console.WriteLine($"Tempo total {relogio.ElapsedMilliseconds / 1000} segundos"); // Função Fix and Optimize Tarefas void multiCenariosFixAndOptimizeTarefas(int num_scenarios) { // variável para guardar número de cenários int scenarios = 0; //seta o parâmetro do modelo para multiplos scenários modelo.NumScenarios = num_scenarios; //quantas datas ficarão fixas int tarefasFixas = instancia.task - 2; //vetros que irá guardar datas sorteadas para serem fixas int[] vetorTarefas = new int[tarefasFixas]; //criar os cenários a serem otimizados pelo Gurobi while (scenarios < num_scenarios) { modelo.Parameters.ScenarioNumber = scenarios; //sorteia datas que serão fixadas vetorTarefas = AleatorioaSemRepetir(tarefasFixas, 0, instancia.task); for (int n = 0; n < instancia.crew; n++) { foreach (int i in vetorTarefas) { for (int j = 0; j < instancia.date; j++) { z[n, i, j].ScenNUB = melhor_z[n, i, j]; z[n, i, j].ScenNLB = melhor_z[n, i, j]; } } } semente++; scenarios++; } // Solve multi-scenario model modelo.Optimize(); } // Fix and Optimize tarefas while (sem_melhoria < 50) { //desfixar variáveis z for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { z[n, i, j].LB = 0.0; z[n, i, j].UB = 1.0; } } } multiCenariosFixAndOptimizeTarefas(num_scenarios); for (int s = 0; s < num_scenarios; s++) { modelo.Parameters.ScenarioNumber = s; double atualFO = modelo.ScenNObjVal; if (atualFO < bestFO) { bestFO = atualFO; melhorCenario = s; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { melhor_z[n, i, j] = z[n, i, j].ScenNX; } } } } } //escreve no console os cenários e suas respectivas FOs for (int i = 0; i < num_scenarios; i++) { modelo.Parameters.ScenarioNumber = i; Console.WriteLine("Solucao para cenario " + i.ToString() + ":" + modelo.ScenNObjVal.ToString()); } } relogio.Stop(); //a variável novoModelo recebe o modelo com melhor cenário modelo.Parameters.ScenarioNumber = melhorCenario; System.Console.WriteLine("Melhor FO:" + modelo.ScenNObjVal.ToString()); System.Console.WriteLine("Melhor FO:" + bestFO.ToString()); System.Console.WriteLine($"Tempo total {relogio.ElapsedMilliseconds / 1000} segundos"); // Seta classe Resultados Resultado resultado = new Resultado(); resultado.nome = arquivo; resultado.segundos = relogio.ElapsedMilliseconds / 1000; resultado.valor = modelo.ObjVal; string output = JsonConvert.SerializeObject(resultado); System.IO.File.AppendAllText("final.txt", output); } }
static void Main() { try { // Sample data // Sets of days and workers string[] Shifts = new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string[] Workers = new string[] { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" }; int nShifts = Shifts.Length; int nWorkers = Workers.Length; // Number of workers required for each shift double[] shiftRequirements = new double[] { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 }; // Amount each worker is paid to work one shift double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 }; // Worker availability: 0 if the worker is unavailable for a shift double[,] availability = new double[,] { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "assignment"); // Assignment variables: x[w][s] == 1 if worker w is assigned // to shift s. Since an assignment model always produces integer // solutions, we use continuous variables and solve as an LP. GRBVar[,] x = new GRBVar[nWorkers,nShifts]; for (int w = 0; w < nWorkers; ++w) { for (int s = 0; s < nShifts; ++s) { x[w,s] = model.AddVar(0, availability[w,s], pay[w], GRB.CONTINUOUS, Workers[w] + "." + Shifts[s]); } } // The objective is to minimize the total pay costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Constraint: assign exactly shiftRequirements[s] workers // to each shift s for (int s = 0; s < nShifts; ++s) { GRBLinExpr lhs = 0.0; for (int w = 0; w < nWorkers; ++w) lhs += x[w, s]; model.AddConstr(lhs == shiftRequirements[s], Shifts[s]); } // Optimize model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { Console.WriteLine("The optimal objective is " + model.Get(GRB.DoubleAttr.ObjVal)); return; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } // Do IIS Console.WriteLine("The model is infeasible; computing IIS"); LinkedList<string> removed = new LinkedList<string>(); // Loop until we reduce to a model that can be solved while (true) { model.ComputeIIS(); Console.WriteLine("\nThe following constraint cannot be satisfied:"); foreach (GRBConstr c in model.GetConstrs()) { if (c.Get(GRB.IntAttr.IISConstr) == 1) { Console.WriteLine(c.Get(GRB.StringAttr.ConstrName)); // Remove a single constraint from the model removed.AddFirst(c.Get(GRB.StringAttr.ConstrName)); model.Remove(c); break; } } Console.WriteLine(); model.Optimize(); status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { break; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } } Console.WriteLine("\nThe following constraints were removed " + "to get a feasible LP:"); foreach (string s in removed) { Console.Write(s + " "); } Console.WriteLine(); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public Dictionary <EdgePair, Double> Solve(FCTPGraph ti) { Dictionary <EdgePair, Double> edgeFlows = new Dictionary <EdgePair, Double>(); Dictionary <String, Edge> edgeMap = new Dictionary <String, Edge>(); Dictionary <String, GRBVar> varMap = new Dictionary <String, GRBVar>(); String currentVar = ""; try { //Model GRBEnv env = new GRBEnv(); env.Set(GRB.IntParam.LogToConsole, 0); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "tranportation"); //edges foreach (Edge e in ti.Edges) { String xij = edgeVarName(e.Source, e.Sink); edgeMap.Add(xij, e); GRBVar var = model.AddVar(0, GRB.INFINITY, e.C, GRB.CONTINUOUS, xij); varMap.Add(xij, var); } //objective min Sum cij xij model.Set(GRB.IntAttr.ModelSense, GRB.MINIMIZE); //integrate variables model.Update(); //supply constraints foreach (Node source in ti.Sources) { GRBLinExpr sourceConstraint = new GRBLinExpr(); foreach (Node sink in ti.Sinks) { String name = edgeVarName(source.Id, sink.Id); sourceConstraint.AddTerm(1, varMap[name]); } model.AddConstr(sourceConstraint, GRB.EQUAL, source.Amount, ""); } //demand constraints foreach (Node sink in ti.Sinks) { GRBLinExpr sinkConstraint = new GRBLinExpr(); foreach (Node source in ti.Sources) { String name = edgeVarName(source.Id, sink.Id); sinkConstraint.AddTerm(1, varMap[name]); } model.AddConstr(sinkConstraint, GRB.EQUAL, sink.Amount, ""); } //update constraints model.Update(); model.Write("mipTranportationGurobi.lp"); env.Set(GRB.IntParam.Threads, 1); model.Optimize(); bool status = model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL; Console.WriteLine("Status: " + status); foreach (String s in edgeMap.Keys) { currentVar = s; double flow = varMap[s].Get(GRB.DoubleAttr.X); Edge e = edgeMap[s]; EdgePair ep = new EdgePair(e.Source, e.Sink); edgeFlows.Add(ep, flow); } model.Dispose(); } catch (GRBException e) { Console.Out.WriteLine(currentVar + " - is current var"); Console.Out.WriteLine(e.ErrorCode); Console.Out.WriteLine(e.ToString()); } return(edgeFlows); }
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.Set(GRB.StringAttr.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.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // 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); } }
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.Set(GRB.StringAttr.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.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // 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].Set(GRB.DoubleAttr.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].Set(GRB.DoubleAttr.Start, 0.0); Console.WriteLine("Closing plant " + p + "\n"); break; } } // Use barrier to solve root relaxation model.GetEnv().Set(GRB.IntParam.Method, GRB.METHOD_BARRIER); // Solve model.Optimize(); // Print solution Console.WriteLine("\nTOTAL COSTS: " + model.Get(GRB.DoubleAttr.ObjVal)); Console.WriteLine("SOLUTION:"); for (int p = 0; p < nPlants; ++p) { if (open[p].Get(GRB.DoubleAttr.X) == 1.0) { Console.WriteLine("Plant " + p + " open:"); for (int w = 0; w < nWarehouses; ++w) { if (transport[w, p].Get(GRB.DoubleAttr.X) > 0.0001) { Console.WriteLine(" Transport " + transport[w, p].Get(GRB.DoubleAttr.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) { //Deserializar o arquivo Json para o c# //JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); var json = File.ReadAllText("C:\\Users\\ruany\\Documents\\dissertacao\\gerador-instancias\\instanciaT11E8D10F6.json"); Parametros instancia = JsonConvert.DeserializeObject <Parametros>(json); // matrizes que irão guardar as soluções do Relax and Fix double[,,] matriz_RaF_x = new double[instancia.crew, instancia.task, instancia.date]; double[,] matriz_RaF_x3 = new double[instancia.task, instancia.date]; double[,] matriz_RaF_x2 = new double[instancia.task, instancia.date]; double[] matriz_RaF_x4 = new double[instancia.task]; double[,,] matriz_RaF_x5 = new double[instancia.crew, instancia.task, instancia.date]; double[,] matriz_RaF_x6 = new double[instancia.task, instancia.date]; double[,] matriz_RaF_y = new double[instancia.crew, instancia.date]; double[,,] matriz_RaF_z = new double[instancia.crew, instancia.task, instancia.date]; double[,] matriz_RaF_z1 = new double[instancia.crew, instancia.task]; double[,,] matriz_RaF_w = new double[instancia.crew, instancia.technical_place, instancia.date]; double[,,,] matriz_RaF_v = new double[instancia.crew, instancia.technical_place, instancia.technical_place, instancia.date]; double[,,] matriz_RaF_w1 = new double[instancia.crew, instancia.technical_place, instancia.date]; double[,,] matriz_RaF_w2 = new double[instancia.crew, instancia.technical_place, instancia.date]; //tempo por iteração double tempo_iteracao, tempo_total; //status de cada iteração int status_RF; //lista List <double> lista_RF = new List <double>(); double soma_RF = 0; //função Relax and Fix void modelo_RelaxAndFixData(int iteracao) { //Modelo GRBEnv ambiente = new GRBEnv(); GRBModel modelo = new GRBModel(ambiente); //número grande int M = 1000; //Variáveis //fração da tarefa i que o membro de equipe n completa na data j GRBVar[,,] x = new GRBVar[instancia.crew, instancia.task, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x[n, i, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "x_" + n + "_" + i + "_" + j); } } } //fração da tarefa i que é completada na data j GRBVar[,] x3 = new GRBVar[instancia.task, instancia.date]; for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x3[i, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "x3_" + i + "_" + j); } } //1 se alguma tarefa i é completada na data j GRBVar[,] x2 = new GRBVar[instancia.task, instancia.date]; for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x2[i, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "x2_" + i + "_" + j); } } //1 se a tarefa i é concluída dentro do horizonte de planejamento GRBVar[] x4 = new GRBVar[instancia.task]; for (int i = 0; i < instancia.task; i++) { x4[i] = modelo.AddVar(0, 1, instancia.c[i] * 2, GRB.CONTINUOUS, "x4_" + i); } //variável fantasma GRBVar[] vf = new GRBVar[instancia.task]; for (int i = 0; i < instancia.task; i++) { vf[i] = modelo.AddVar(1, 1, instancia.c[i] * 2, GRB.BINARY, "vf_" + i); } //1 se o membro de equipe n está trabalhando na tarefa i na data j mas não na data j+1 GRBVar[,,] x5 = new GRBVar[instancia.crew, instancia.task, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x5[n, i, j] = modelo.AddVar(0, 1, 0.1, GRB.CONTINUOUS, "x5_" + n + "_" + i + "_" + j); } } } //1 se parte da tarefa i é completada na data j mas não na data j+1 GRBVar[,] x6 = new GRBVar[instancia.task, instancia.date]; for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { x6[i, j] = modelo.AddVar(0, 1, 0.9, GRB.CONTINUOUS, "x6_" + i + "_" + j); } } //1 se o membro da equipe n vai trabalhar na data j GRBVar[,] y = new GRBVar[instancia.crew, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int j = 0; j < instancia.date; j++) { y[n, j] = modelo.AddVar(0, 1, instancia.hours_per_shift, GRB.CONTINUOUS, "y_" + n + "_" + j); } } //1 se membro da equipe n trabalha na tarefa i na data j GRBVar[,,] z = new GRBVar[instancia.crew, instancia.task, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { z[n, i, j] = modelo.AddVar(0, 1, 0.5, GRB.CONTINUOUS, "z_" + n + "_" + i + "_" + j); } } } //1 se o membro de equipe n trabalha na tarefa i GRBVar[,] z1 = new GRBVar[instancia.crew, instancia.task]; for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { z1[n, i] = modelo.AddVar(0, 1, 0.1, GRB.CONTINUOUS, "z1_" + n + "_" + i); } } //1 se o membro de equipe n trabalha no local técnico p na data j GRBVar[,,] w = new GRBVar[instancia.crew, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { w[n, p, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "w_" + n + "_" + p + "_" + j); } } } //1 se o membro de equipe n precisa de transporte entre o local técnico o e o local q na instancia.date j GRBVar[,,,] v = new GRBVar[instancia.crew, instancia.technical_place, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < instancia.date; j++) { v[n, p, q, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "v_" + n + "_" + p + "_" + q + "_" + j); } } } } //se a equipe n precisa de transporte para o local técnico p de outro local técnico na data j GRBVar[,,] w1 = new GRBVar[instancia.crew, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { w1[n, p, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "w1_" + n + "_" + p + "_" + j); } } } //se a equipe n precisa de transporte do local técnico p para outro local técnico GRBVar[,,] w2 = new GRBVar[instancia.crew, instancia.technical_place, instancia.date]; for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { w2[n, p, j] = modelo.AddVar(0, 1, 0, GRB.CONTINUOUS, "w2_" + n + "_" + p + "_" + j); } } } //Função objetivo modelo.ModelSense = GRB.MINIMIZE; //Restrições GRBLinExpr exp = 0.0; GRBLinExpr exp2 = 0.0; GRBLinExpr exp3 = 0.0; //Restrições com relação a tarefa //restrição 2 //a tarefa deve ser concluída dentro do horizonte de planejamento for (int i = 0; i < instancia.task; i++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { for (int j = 0; j < instancia.date; j++) { exp.AddTerm(1, x[n, i, j]); } } modelo.AddConstr(exp == x4[i], "R2_" + i); } //restrição 3 //o número total de horas por turno não deve ser excedido for (int j = 0; j < instancia.date; j++) { for (int n = 0; n < instancia.crew; n++) { exp.Clear(); exp2.Clear(); exp3.Clear(); for (int i = 0; i < instancia.task; i++) { exp.AddTerm(instancia.c[i], x[n, i, j]); } for (int p = 0; p < instancia.technical_place; p++) { exp2.AddTerm(2 * instancia.tm[p], w[n, p, j]); exp2.AddTerm(-instancia.tm[p], w1[n, p, j]); exp2.AddTerm(-instancia.tm[p], w2[n, p, j]); } for (int p = 0; p < instancia.technical_place; p++) { for (int q = 0; q < instancia.technical_place; q++) { exp3.AddTerm(instancia.tr[p, q], v[n, p, q, j]); } } modelo.AddConstr(exp + exp2 + exp3 <= instancia.hours_per_shift, "R3_" + j + "_" + n); } } //restrição 4 //a soma das frações das tarefas locadas não pode exceder o total para completar a tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, x[n, i, j]); } modelo.AddConstr(x2[i, j] >= exp, "R4_" + i + "_" + j); } } //restrição 5 //soma de das frações dos membros e equipe num dado dia deve ser igual a x3 for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, x[n, i, j]); } modelo.AddConstr(x3[i, j] == exp, "R5_" + i + "_" + j); } } //restrição 6 //a tarefa i deve ser completada dentro do horizonte de planejamento se gi=1 for (int i = 0; i < instancia.task; i++) { modelo.AddConstr(x4[i] >= instancia.g[i], "R6_" + i); } //restrição 7 //fração da tarefa que é completada num dado dia não deve exceder X4 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(x4[i] >= x[n, i, j], "R7_" + n + "_" + i + "_" + j); } } } //restrição 8 //um membro de equipe não pode ser locado a uma tarefa em um dia em que ele não trabalha for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(y[n, j] >= z[n, i, j], "R8_" + n + "_" + i + "_" + j); } } } //restrição 9 //se o membro de equipe é locado para uma tarefa então z=1 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z[n, i, j] >= x[n, i, j], "R9_" + n + "_" + i + "_" + j); } } } //restrição 10 //a variável z não pode ser 1 se a equipe n não trabalha num dado dia for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z[n, i, j] <= M * x[n, i, j], "R10_" + n + "_" + i + "_" + j); } } } //restrição 11 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z1[n, i] >= z[n, i, j], "R11_" + n + "_" + i + "_" + j); } } } //Restrições de gerenciemanto //restrição 12 //preferencalmente uma tarefa deve concluida pela mesma pessoa que começou trabalhando nela for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date - 1; j++) { modelo.AddConstr(x5[n, i, j] >= z[n, i, j] - z[n, i, j + 1], "R12_" + n + "_" + i + "_" + j); } } } //restrição 13 //uma penalidade será dada ao planejamento se a tarefa i é completada em dias não consecutivos for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date - 1; j++) { modelo.AddConstr(x6[i, j] >= x2[i, j] - x2[i, j + 1], "R13_" + i + "_" + j); } } //restrição 14 //o número mínimo de membros de equipe que podem trabalhar simultaneamente em uma tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, z[n, i, j]); } modelo.AddConstr(exp >= instancia.d1[i] * x2[i, j], "R14_" + i + "_" + j); } } //restrição 15 //o número máximo de membros de equipe que podem trablhar simultaneamente em uma tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(1, z[n, i, j]); } modelo.AddConstr(exp <= instancia.d2[i] * x2[i, j], "R15_" + i + "_" + j); } } //restrição 16 //número mínimo de membros para trabalhar em um tarefa deve ser respeitado for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(x[n, i, j] <= x3[i, j] / instancia.d1[i], "R16_" + n + "_" + i + "_" + j); } } } //restrição 17 //membros de equipe não podem trabalhar em dias em que eles não estão disponíveis for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(z[n, i, j] <= instancia.e[n, j], "R17_" + n + "_" + i + "_" + j); } } } //Restrições com relação a competência //restrição 18 //a combinação do nível de competencias de todos os membros //de equipe deve ser suficiente para cada tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { for (int k = 0; k < instancia.competencies; k++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(instancia.bm3[n, k], z[n, i, j]); } modelo.AddConstr(exp >= x2[i, j] * instancia.bo[i, k] * instancia.level_total, "R18_" + i + "_" + j + "_" + k); } } } //restrição 19 //pelo menos um membro de equipe deve ter nível 3 de competencia para a tarefa i for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { for (int k = 0; k < instancia.competencies; k++) { exp.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(instancia.bm[n, k], z[n, i, j]); } modelo.AddConstr(exp >= x2[i, j] * instancia.bo[i, k], "R19_" + i + "_" + j + "_" + k); } } } //restrição 20 //pelo menos um mebro de equipe tem nível de competencia 3 se vários membros de equipe trabalham na mesma tarefa for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { for (int k = 0; k < instancia.competencies; k++) { exp.Clear(); exp2.Clear(); for (int n = 0; n < instancia.crew; n++) { exp.AddTerm(instancia.bm[n, k], x[n, i, j]); exp2.AddTerm(instancia.bm2[n, k], x[n, i, j]); } modelo.AddConstr(exp >= exp2 * (double)(1 / instancia.d1[i]), "R20_" + i + "_" + j + "_" + k); } } } //Restrições com relação ao transporte //restrição 21 //cada membro de equipe trabalha em um local técnico em que a tarefa está localizada for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int i = 0; i < instancia.task; i++) { exp.AddTerm(instancia.tp[i, p], z[n, i, j]); } modelo.AddConstr(w[n, p, j] <= exp, "R21_" + n + "_" + p + "_" + j); } } } //restrição 22 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int i = 0; i < instancia.task; i++) { exp.AddTerm(instancia.tp[i, p], z[n, i, j]); } modelo.AddConstr(w[n, p, j] * M >= exp, "R22_" + n + "_" + p + "_" + j); } } } //restrição 23 //o membro de equipe só é transportado entre os locais técnicos que as tarefas dele estão localizadas for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int q = 0; q < instancia.technical_place; q++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(exp <= w[n, p, j] * M, "R23_" + n + "_" + p + "_" + j); } } } //restrição 24 for (int n = 0; n < instancia.crew; n++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int p = 0; p < instancia.technical_place; p++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(exp <= w[n, q, j] * M, "R24_" + n + "_" + q + "_" + j); } } } //restrição 25 //se o membro de equipe trabalha em mais do que um local técninco durante o turno for (int n = 0; n < instancia.crew; n++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int p = 0; p < instancia.technical_place; p++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(w1[n, q, j] == exp, "R25_" + n + "_" + q + "_" + j); } } } //restrição 26 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int q = 0; q < instancia.technical_place; q++) { exp.AddTerm(1, v[n, p, q, j]); } modelo.AddConstr(w2[n, p, j] == exp, "R26_" + n + "_" + p + "_" + j); } } } //restrição 27 //cada membro de equipe pode apenas ser transportado de e para cada local técnico uma vez por dia for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(w1[n, p, j] <= 1, "R27_" + n + "_" + p + "_" + j); } } } //restrição 28 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { modelo.AddConstr(w2[n, p, j] <= 1, "R28_" + n + "_" + p + "_" + j); } } } //restrição 29 //funcionário será transportado apenas uma vez do e para o depósito for (int n = 0; n < instancia.crew; n++) { for (int j = 0; j < instancia.date; j++) { exp.Clear(); for (int p = 0; p < instancia.technical_place; p++) { exp.AddTerm(2, w[n, p, j]); exp.AddTerm(-1, w1[n, p, j]); exp.AddTerm(-1, w2[n, p, j]); } modelo.AddConstr(exp == 2 * y[n, j], "R29_" + n + "_" + j); } } //variáveis a serem fixadas if (iteracao != 0) { for (int n = 0; n < instancia.crew; n++) { //fixar variável y for (int j = 0; j < iteracao - 1; j++) { y[n, j].Set(GRB.DoubleAttr.LB, matriz_RaF_y[n, j]); y[n, j].Set(GRB.DoubleAttr.UB, matriz_RaF_y[n, j]); //fixar variável z for (int i = 0; i < instancia.task; i++) { z[n, i, j].Set(GRB.DoubleAttr.LB, matriz_RaF_z[n, i, j]); z[n, i, j].Set(GRB.DoubleAttr.UB, matriz_RaF_z[n, i, j]); } } } } //varivais binárias //variável z for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { z[n, i, iteracao].Set(GRB.CharAttr.VType, GRB.BINARY); } } //variável y for (int n = 0; n < instancia.crew; n++) { y[n, iteracao].Set(GRB.CharAttr.VType, GRB.BINARY); } //variável x4 for (int i = 0; i < instancia.task; i++) { x4[i].Set(GRB.CharAttr.VType, GRB.BINARY); } //variável x5 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < iteracao; j++) { x5[n, i, j].Set(GRB.CharAttr.VType, GRB.BINARY); } } } //variável x6 for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < iteracao; j++) { x6[i, j].Set(GRB.CharAttr.VType, GRB.BINARY); } } //variável z1 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { z1[n, i].Set(GRB.CharAttr.VType, GRB.BINARY); } } //variável w for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < iteracao; j++) { w[n, p, j].Set(GRB.CharAttr.VType, GRB.BINARY); } } } //variável v for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < iteracao; j++) { v[n, p, q, j].Set(GRB.CharAttr.VType, GRB.BINARY); } } } } //variável w1 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < iteracao; j++) { w1[n, p, j].Set(GRB.CharAttr.VType, GRB.BINARY); } } } //variável w2 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < iteracao; j++) { w2[n, p, j].Set(GRB.CharAttr.VType, GRB.BINARY); } } } //otimizar modelo modelo.Set(GRB.DoubleParam.TimeLimit, tempo_iteracao); modelo.Update(); modelo.Optimize(); tempo_total -= modelo.Get(GRB.DoubleAttr.Runtime); //atualizar int solverStatus = modelo.Get(GRB.IntAttr.Status); if (modelo.SolCount == 0 || solverStatus == 3) { status_RF = 999999; return; } else { //salvar a salocao for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { //variável z matriz_RaF_z[n, i, iteracao] = z[n, i, iteracao].X; } //variável y matriz_RaF_y[n, iteracao] = y[n, iteracao].X; } // se estiver na última iteracao salvar nas matizes o valor das variáveis if (iteracao == instancia.date) { //variável x for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_x[n, i, j] = x[n, i, j].X; } } } //variável x3 for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_x3[i, j] = x3[i, j].X; } } //vairável x2 for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_x2[i, j] = x2[i, j].X; } } //variável x4 for (int i = 0; i < instancia.task; i++) { matriz_RaF_x4[i] = x4[i].X; } //variável x5 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_x5[n, i, j] = x5[n, i, j].X; } } } //variável x6 for (int i = 0; i < instancia.task; i++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_x6[i, j] = x6[i, j].X; } } //variável z1 for (int n = 0; n < instancia.crew; n++) { for (int i = 0; i < instancia.task; i++) { matriz_RaF_z1[n, i] = z1[n, i].X; } } //variável w for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_w[n, p, j] = w[n, p, j].X; } } } //variável v for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int q = 0; q < instancia.technical_place; q++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_v[n, p, q, j] = v[n, p, q, j].X; } } } } //variável w1 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_w1[n, p, j] = w1[n, p, j].X; } } } //variável w2 for (int n = 0; n < instancia.crew; n++) { for (int p = 0; p < instancia.technical_place; p++) { for (int j = 0; j < instancia.date; j++) { matriz_RaF_w2[n, p, j] = w2[n, p, j].X; } } } } } if (iteracao == instancia.date) { double funcaoObjetivo; funcaoObjetivo = modelo.Get(GRB.DoubleAttr.ObjVal); Console.WriteLine("Solução atual:" + funcaoObjetivo.ToString()); lista_RF.Add(funcaoObjetivo); soma_RF += funcaoObjetivo; } } //Relaz and Fix //Stopwatch para contar o tempo Stopwatch relogio = new Stopwatch(); tempo_total = 3600; relogio.Start(); for (int j = 0; j < instancia.date; j++) { status_RF = 0; tempo_iteracao = tempo_total / (instancia.date - j + 1); modelo_RelaxAndFixData(j); if (status_RF != 0) { lista_RF.Add(99999999); soma_RF += 99999999; } } relogio.Stop(); Console.WriteLine("tempo total de:" + (relogio.ElapsedMilliseconds / 1000).ToString() + "segundos"); Console.ReadKey(); }
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.Set(GRB.StringAttr.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.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // 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 += 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 += 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].Set(GRB.DoubleAttr.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].Set(GRB.DoubleAttr.Start, 0.0); Console.WriteLine("Closing plant " + p + "\n"); break; } } // Use barrier to solve root relaxation model.GetEnv().Set(GRB.IntParam.Method, GRB.METHOD_BARRIER); // Solve model.Optimize(); // Print solution Console.WriteLine("\nTOTAL COSTS: " + model.Get(GRB.DoubleAttr.ObjVal)); Console.WriteLine("SOLUTION:"); for (int p = 0; p < nPlants; ++p) { if (open[p].Get(GRB.DoubleAttr.X) == 1.0) { Console.WriteLine("Plant " + p + " open:"); for (int w = 0; w < nWarehouses; ++w) { if (transport[w,p].Get(GRB.DoubleAttr.X) > 0.0001) { Console.WriteLine(" Transport " + transport[w,p].Get(GRB.DoubleAttr.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); } }