static void Main(string[] args) { Console.WriteLine("READING DATA...."); //FOLDER FILES string inputFolder = "..//..//..//InputFiles//"; //Relative path string outputFolder = "..//..//..//OutputFiles//"; //Relative path ReadData readData = new ReadData(); InputData inputData = readData.readData(inputFolder); //GLOBAL VARS int nCUT = 0; double Min_Stage2_Profit = double.MaxValue; double GAP = double.MaxValue; //let { p in PROD} //inv1[p] := 0; List <Inv0_param> inv1List = new List <Inv0_param>(); inputData.ProdList.ForEach(pl => { Inv0_param invProd = new Inv0_param() { PROD = pl.PROD, INV0 = 0 }; inv1List.Add(invProd); }); SubModelParameters subModelParams = new SubModelParameters() { inv1 = inv1List }; SubModelOutputs subModelOutputs = new SubModelOutputs(); MasterModelParameters masterModelParameters = new MasterModelParameters(); MasterModelOutputs masterModelOutputs = new MasterModelOutputs(); //FOR 50 for (int x = 0; x <= 50; x++) { SubModel sb = new SubModel(subModelParams); subModelOutputs = sb.Build_Model(inputData, outputFolder); //if Stage2_Profit < Min_Stage2_Profit - 0.00001 if (subModelOutputs.stage2Profit < Min_Stage2_Profit - 0.00001) { //let GAP := min(GAP, Min_Stage2_Profit - Stage2_Profit); GAP = Math.Min(GAP, Min_Stage2_Profit - subModelOutputs.stage2Profit); //option display_1col 0; //display GAP, Make, Sell, Inv; //let nCUT := nCUT + 1; nCUT++; //let { t in 2..T, s in SCEN} time_price[t, s, nCUT] := Time[t, s].dual; List <TimePrice_param> timePriceList = new List <TimePrice_param>(); List <T_param> tlist2 = inputData.TList.FindAll(tl => tl.T >= 2); tlist2.ForEach(tl => { inputData.ScenList.ForEach(sl => { string cn = "TIME_" + tl.T + "_" + sl.SCEN; double dl = subModelOutputs.gModel.GetConstrByName(cn).Get(GRB.DoubleAttr.Pi); TimePrice_param tpp = new TimePrice_param() { nCUT = nCUT, T = tl, SCEN = sl, DUAL = dl }; timePriceList.Add(tpp); }); }); //let { p in PROD, s in SCEN} bal2_price[p, s, nCUT] := Balance2[p, s].dual; List <Balance2Price_param> balance2PriceList = new List <Balance2Price_param>(); inputData.ProdList.ForEach(pl => { inputData.ScenList.ForEach(sl => { string cn = "BALANCE2_" + pl.PROD + "_" + sl.SCEN; var dl = subModelOutputs.gModel.GetConstrByName(cn).Get(GRB.DoubleAttr.Pi); Balance2Price_param b2p = new Balance2Price_param() { nCUT = nCUT, PROD = pl, SCEN = sl, DUAL = dl }; balance2PriceList.Add(b2p); }); }); //let { p in PROD, t in 2..T, s in SCEN} sell_lim_price[p, t, s, nCUT] := Sell[p, t, s].urc; List <SellLimPrice_param> sellLimPriceList = new List <SellLimPrice_param>(); IndexesVar ixVar = new IndexesVar(); inputData.ProdList.ForEach(pl => { tlist2.ForEach(tl => { inputData.ScenList.ForEach(sl => { int ixP = inputData.ProdList.IndexOf(pl); int ixT = tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(sl); int ix = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, tlist2.Count, inputData.ScenList.Count); SellLimPrice_param slp = new SellLimPrice_param() { nCUT = nCUT, PROD = pl, SCEN = sl, T = tl, URC = subModelOutputs.sell[ix].RC }; sellLimPriceList.Add(slp); }); }); }); } else { break; } //printf "\nRE-SOLVING MASTER PROBLEM\n\n"; //solve Master; //printf "\n"; //option display_1col 20; //display Make1, Inv1, Sell1; MasterModel masterModel = new MasterModel(); masterModelOutputs = masterModel.buildModel(inputData, nCUT, masterModelParameters, outputFolder); //let { p in PROD} //inv1[p] := Inv1[p]; inputData.ProdList.ForEach(pl => { int ixP = inputData.ProdList.IndexOf(pl); //inv1List.Find(il => il.PROD.Equals(pl.PROD)).INV0 = masterModelOutputs.inv1[ixP].X; Inv0_param invProdNew = new Inv0_param() { PROD = pl.PROD, INV0 = masterModelOutputs.inv1[ixP].X }; int ixPInv = inv1List.IndexOf(inv1List.Find(il => il.PROD.Equals(pl.PROD))); inv1List[ixPInv] = invProdNew; }); } }
public SubModelOutputs Build_Model( InputData inputData, string outputFolder ) { try { // Create an empty environment, set options and start GRBEnv env = new GRBEnv(true); env.Set("LogFile", "LogFileGurobiModel.log"); env.Start(); int T = 4; List <T_param> Tlist2 = inputData.TList.FindAll(tl => tl.T >= 2); List <T_param> Tlist3 = inputData.TList.FindAll(tl => tl.T >= 3); // Create empty Gurobi model GRBModel gModel = new GRBModel(env); // Create an empty linear expression object. //Parameters and variables will be added and then used to add model components //(Objective Function and Constraints). GRBLinExpr expr1 = 0.0; GRBLinExpr expr2 = 0.0; // Crear la variables GRBVar[] Make = gModel.AddVars(inputData.ProdList.Count * Tlist2.Count * inputData.ScenList.Count, GRB.CONTINUOUS); GRBVar[] Inv = gModel.AddVars(inputData.ProdList.Count * Tlist2.Count * inputData.ScenList.Count, GRB.CONTINUOUS); GRBVar[] Sell = gModel.AddVars(inputData.ProdList.Count * Tlist2.Count * inputData.ScenList.Count, GRB.CONTINUOUS); //MAKE VARNAME inputData.ProdList.ForEach(pl => { Tlist2.ForEach(tl => { inputData.ScenList.ForEach(sl => { int ixP = inputData.ProdList.IndexOf(pl); int ixT = Tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(sl); int ix = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); Make[ix].VarName = "MAKE_PROD: " + pl.PROD + " T: " + tl.T + " SCEN: " + sl.SCEN; }); }); }); //INV VARNAME inputData.ProdList.ForEach(pl => { Tlist2.ForEach(tl => { inputData.ScenList.ForEach(sl => { int ixP = inputData.ProdList.IndexOf(pl); int ixT = Tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(sl); int ix = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); Inv[ix].VarName = "INV_PROD: " + pl.PROD + " T: " + tl.T + " SCEN: " + sl.SCEN; }); }); }); //SELL VARNAME inputData.ProdList.ForEach(pl => { Tlist2.ForEach(tl => { inputData.ScenList.ForEach(sl => { int ixP = inputData.ProdList.IndexOf(pl); int ixT = Tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(sl); int ix = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); Sell[ix].VarName = "SELL_PROD: " + pl.PROD + " T: " + tl.T + " SCEN: " + sl.SCEN; }); }); }); //MAKE => 0 (constrain) //GRB.CONTINUOUS for (int a = 0; a < Make.Length; a++) { expr1.Clear(); expr1.AddTerm(1, Make[a]); gModel.AddConstr(expr1, GRB.GREATER_EQUAL, 0, ">=0"); } //INV => 0 (constrain) for (int a = 0; a < Inv.Length; a++) { expr1.Clear(); expr1.AddTerm(1, Inv[a]); gModel.AddConstr(expr1, GRB.GREATER_EQUAL, 0, ">=0"); } //SELL => 0 (constrain) for (int a = 0; a < Sell.Length; a++) { expr1.Clear(); expr1.AddTerm(1, Sell[a]); gModel.AddConstr(expr1, GRB.GREATER_EQUAL, 0, ">=0"); } //SELL <= market[p,t] expr1.Clear(); inputData.ProdList.ForEach(pl => { Tlist2.ForEach(tl => { inputData.ScenList.ForEach(sl => { double market = inputData .MarketList .Find(ml => ml.PROD.Equals(pl.PROD) && ml.T.Equals(tl.T)).MARKET; int ixP = inputData.ProdList.IndexOf(pl); int ixT = Tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(sl); int index = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); expr1.Clear(); expr1.AddTerm(1, Sell[index]); gModel.AddConstr(expr1, GRB.LESS_EQUAL, market, "<=Market"); }); }); }); //Construir funcion objetivo //maximize Stage2_Profit: // sum {s in SCEN} prob[s] * // sum {p in PROD, t in 2..T} (revenue[p,t,s]*Sell[p,t,s] - // prodcost[p]*Make[p,t,s] - invcost[p]*Inv[p,t,s]); expr1.Clear(); inputData.ScenList.ForEach(s => { double prob = inputData.ProbList.Find(x => x.SCEN.Equals(s.SCEN)).PROB; inputData.ProdList.ForEach(p => { Tlist2.ForEach(tl => { //SELL double revenue = inputData .RevenueList .Find(r => r.PROD.Equals(p.PROD) && r.T.Equals(tl.T) && r.SCEN.Equals(s.SCEN) ).REVENUE; double prodCost = inputData .ProdCostList .Find(pc => pc.PROD.Equals(p.PROD) ).PRODCOST; double invCost = inputData .InvCostList .Find(ic => ic.PROD.Equals(p.PROD) ).INVCOST; int ixP = inputData.ProdList.IndexOf(p); int ixT = Tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(s); int indexVar = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); expr1.AddTerm(prob * revenue, Sell[indexVar]); expr1.AddTerm(-1 * prob * prodCost, Make[indexVar]); expr1.AddTerm(-1 * prob * invCost, Inv[indexVar]); }); }); }); //Insertar funcion objetivo gModel.SetObjective(expr1, GRB.MAXIMIZE); //Insertar Restricciones //subject to Time {t in 2..T, s in SCEN}: //sum {p in PROD} (1/rate[p]) * Make[p,t,s] <= avail[t]; expr1.Clear(); Tlist2.ForEach(tl => { inputData.ScenList.ForEach(sl => { inputData.ProdList.ForEach(pl => { double rate = 1 / inputData.RateList.Find(rl => rl.PROD.Equals(pl.PROD)).RATE; int ixP = inputData.ProdList.IndexOf(pl); int ixT = Tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(sl); int ixMake = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); expr1.AddTerm(rate, Make[ixMake]); }); double avail = inputData.AvailList.Find(al => al.T.Equals(tl.T)).AVAIL; gModel.AddConstr(expr1, GRB.LESS_EQUAL, avail, "TIME_" + tl.T + "_" + sl.SCEN); }); }); //subject to Balance2 { p in PROD, s in SCEN}: //Make[p, 2, s] + inv1[p] = Sell[p, 2, s] + Inv[p, 2, s]; //2 => index T => 0 expr1.Clear(); inputData.ProdList.ForEach(pl => { inputData.ScenList.ForEach(sl => { int ixP = inputData.ProdList.IndexOf(pl); int ixT = 0; int ixS = inputData.ScenList.IndexOf(sl); int ix = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); double inv1 = subModelParams.inv1.Find(il => il.PROD.Equals(pl.PROD)).INV0; expr1.Clear(); expr2.Clear(); //como sumar un param ???? expr1.AddTerm(1, Make[ix]); //expr1.AddTerm(inv1, null); ???? como??? // Se despeja vars & params expr1.AddTerm(-1, Sell[ix]); expr1.AddTerm(-1, Inv[ix]); gModel.AddConstr(expr1, GRB.EQUAL, inv1, "BALANCE2_" + pl.PROD + "_" + sl.SCEN); }); }); //subject to Balance { p in PROD, t in 3..T, s in SCEN}: //Make[p, t, s] + Inv[p, t - 1, s] = Sell[p, t, s] + Inv[p, t, s]; inputData.ProdList.ForEach(pl => { Tlist3.ForEach(tl => { inputData.ScenList.ForEach(sl => { int ixP = inputData.ProdList.IndexOf(pl); int ixT = Tlist2.IndexOf(tl); int ixS = inputData.ScenList.IndexOf(sl); int ix = ixVar.getIx3(ixP, ixT, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); int ix2 = ixVar.getIx3(ixP, ixT - 1, ixS, inputData.ProdList.Count, Tlist2.Count, inputData.ScenList.Count); expr1.Clear(); expr2.Clear(); expr1.AddTerm(1, Make[ix]); expr1.AddTerm(1, Inv[ix2]); expr2.AddTerm(1, Sell[ix]); expr2.AddTerm(1, Inv[ix]); gModel.AddConstr(expr1, GRB.EQUAL, expr2, "SUBJECT TO BALANCE"); }); }); }); //carpeta donde se expande el modelo gModel.Write(outputFolder + "Submodel_Model.lp"); // RESOLVER EL MODELO try { Console.WriteLine("Solving the sub model with gurobi.."); gModel.Optimize(); if (gModel.Status == 2) { for (int m = 0; m < Make.Length; m++) { Console.WriteLine("Make Var: " + Make[m].VarName + " = " + Make[m].X); } for (int m = 0; m < Inv.Length; m++) { Console.WriteLine("Inv Var: " + Inv[m].VarName + " = " + Inv[m].X); } for (int m = 0; m < Sell.Length; m++) { Console.WriteLine("Sell Var: " + Sell[m].VarName + " = " + Sell[m].X); } } SubModelOutputs smo = new SubModelOutputs() { make = Make, sell = Sell, inv = Inv, stage2Profit = gModel.ObjVal, gModel = gModel }; //gModel.Dispose(); //env.Dispose(); return(smo); } catch { Console.WriteLine("ERROR SOLVING THE MODEL"); } gModel.Dispose(); env.Dispose(); } catch (GRBException ex) { Console.WriteLine("Error code: " + ex.ErrorCode + ". " + ex.Message); } return(new SubModelOutputs()); }