Exemplo n.º 1
0
        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;
                });
            }
        }
Exemplo n.º 2
0
        public MasterModelOutputs buildModel(
            InputData inputData,
            int nCUT,
            MasterModelParameters masterModelParameters,
            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[] Make1 = gModel.AddVars(inputData.ProdList.Count, GRB.CONTINUOUS);
                GRBVar[] Inv1  = gModel.AddVars(inputData.ProdList.Count, GRB.CONTINUOUS);
                GRBVar[] Sell1 = gModel.AddVars(inputData.ProdList.Count, GRB.CONTINUOUS);

                //MAKE1 VARNAME
                inputData.ProdList.ForEach(pl => {
                    int ixP            = inputData.ProdList.IndexOf(pl);
                    Make1[ixP].VarName = "MAKE1_Prod: " + pl.PROD;
                });

                //INV1 VARNAME
                inputData.ProdList.ForEach(pl => {
                    int ixP           = inputData.ProdList.IndexOf(pl);
                    Inv1[ixP].VarName = "INV1_Prod: " + pl.PROD;
                });

                //MAKE1 VARNAME
                inputData.ProdList.ForEach(pl => {
                    int ixP            = inputData.ProdList.IndexOf(pl);
                    Sell1[ixP].VarName = "SELL1_Prod: " + pl.PROD;
                });

                //MAKE1 => 0 (constrain)
                //GRB.CONTINUOUS
                for (int a = 0; a < Make1.Length; a++)
                {
                    expr1.Clear();
                    expr1.AddTerm(1, Make1[a]);
                    gModel.AddConstr(expr1, GRB.GREATER_EQUAL, 0, ">=0");
                }

                //INV1 => 0 (constrain)
                for (int a = 0; a < Inv1.Length; a++)
                {
                    expr1.Clear();
                    expr1.AddTerm(1, Inv1[a]);
                    gModel.AddConstr(expr1, GRB.GREATER_EQUAL, 0, ">=0");
                }

                //SELL1 => 0 (constrain)
                for (int a = 0; a < Sell1.Length; a++)
                {
                    expr1.Clear();
                    expr1.AddTerm(1, Sell1[a]);
                    gModel.AddConstr(expr1, GRB.GREATER_EQUAL, 0, ">=0");
                }

                //SELL1 <= market[p,1]
                expr1.Clear();
                inputData.ProdList.ForEach(pl => {
                    double market = inputData
                                    .MarketList
                                    .Find(ml =>
                                          ml.PROD.Equals(pl.PROD) &&
                                          ml.T.Equals(1)).MARKET;

                    int ixP = inputData.ProdList.IndexOf(pl);

                    expr1.Clear();
                    expr1.AddTerm(1, Sell1[ixP]);
                    gModel.AddConstr(expr1, GRB.LESS_EQUAL, market, "<=Market");
                });

                GRBVar Min_Stage2_Profit = gModel.AddVar(double.MinValue, double.MaxValue, masterModelParameters.Min_Stage2_Profit, GRB.CONTINUOUS, "Min_Stage2_Profit");

                //Funcion objetivo
                //maximize Expected_Profit:
                //sum { s in SCEN}
                //prob[s] *
                //sum { p in PROD} (revenue[p, 1, s] * Sell1[p] -
                //prodcost[p] * Make1[p] - invcost[p] * Inv1[p]) +
                //Min_Stage2_Profit;
                expr1.Clear();
                inputData.ScenList.ForEach(sl =>
                {
                    double prob = inputData.ProbList.Find(x => x.SCEN.Equals(sl.SCEN)).PROB;

                    inputData.ProdList.ForEach(pl => {
                        double revenue = inputData
                                         .RevenueList
                                         .Find(rl =>
                                               rl.PROD.Equals(pl.PROD) &&
                                               rl.T.Equals(1) &&
                                               rl.SCEN.Equals(sl.SCEN))
                                         .REVENUE;

                        int ixP        = inputData.ProdList.IndexOf(pl);
                        double invcost = inputData.InvCostList.Find(inv => inv.PROD.Equals(pl.PROD)).INVCOST;

                        double prodcost = inputData.ProdCostList.Find(inv => inv.PROD.Equals(pl.PROD)).PRODCOST;

                        expr1.AddTerm(prob * revenue, Sell1[ixP]);
                        expr1.AddTerm(-prob * prodcost, Make1[ixP]);
                        expr1.AddTerm(-prob * invcost, Inv1[ixP]);
                        expr1.AddTerm(1, Min_Stage2_Profit);
                    });
                });

                //Insertar funcion objetivo
                gModel.SetObjective(expr1, GRB.MAXIMIZE);

                //subj to Cut_Defn {k in 1..nCUT}:  KE ESTA PASANDO
                // Min_Stage2_Profit <=
                //    sum { t in 2..T, s in SCEN}
                //    time_price[t, s, k] * avail[t] +
                //    sum { p in PROD, s in SCEN}
                //    bal2_price[p, s, k] * (-Inv1[p]) +
                //    sum { p in PROD, t in 2..T, s in SCEN}
                //    sell_lim_price[p, t, s, k] * market[p, t];
                expr1.Clear();
                double sumPriceAvail  = 0;
                double sumPriceMarket = 0;
                expr1.AddTerm(1, Min_Stage2_Profit);
                for (int k = 1; k <= nCUT; k++)
                {
                    //    sum { t in 2..T, s in SCEN}
                    //    time_price[t, s, k] * avail[t] +
                    Tlist2.ForEach(tl =>
                    {
                        inputData.ScenList.ForEach(sl =>
                        {
                            double timePrice = masterModelParameters.timePriceList.Find(x => x.T.Equals(tl.T) &&
                                                                                        x.SCEN.Equals(sl.SCEN) &&
                                                                                        x.nCUT.Equals(k)).TIMEPRICE;

                            double avail = inputData.AvailList.Find(al => al.T.Equals(tl.T)).AVAIL;

                            sumPriceAvail += timePrice * avail;
                        });
                    });

                    //    sum { p in PROD, t in 2..T, s in SCEN}
                    //    sell_lim_price[p, t, s, k] * market[p, t];
                    inputData.ProdList.ForEach(pl => {
                        Tlist2.ForEach(tl => {
                            inputData.ScenList.ForEach(sl =>
                            {
                                double sellLimPrice = masterModelParameters.sellLimPriceList.Find(slpl => slpl.PROD.Equals(pl.PROD) &&
                                                                                                  slpl.T.Equals(tl.T) &&
                                                                                                  slpl.SCEN.Equals(sl.SCEN) &&
                                                                                                  slpl.nCUT.Equals(k)).SELLLIMPRICE;

                                double market = inputData.MarketList.Find(ml => ml.PROD.Equals(pl.PROD) &&
                                                                          ml.T.Equals(tl.T)).MARKET;

                                sumPriceMarket += sellLimPrice * market;
                            });
                        });
                    });

                    //  sum { p in PROD, s in SCEN}
                    //  bal2_price[p, s, k] * (-Inv1[p]) +
                    inputData.ProdList.ForEach(pl =>
                    {
                        inputData.ScenList.ForEach(sl =>
                        {
                            double bal2Price = masterModelParameters.balance2PriceList.Find(bp => bp.PROD.Equals(pl.PROD) &&
                                                                                            bp.SCEN.Equals(sl.SCEN) && bp.nCUT.Equals(k)).BALANCE2PRICE;

                            int ixP = inputData.ProdList.IndexOf(pl);
                            expr1.AddTerm(bal2Price, Inv1[ixP]);
                        });
                    });
                }
                gModel.AddConstr(expr1, GRB.LESS_EQUAL, sumPriceAvail + sumPriceMarket, "Cut_Defn");

                //subject to Time1:
                //sum { p in PROD} (1 / rate[p]) * Make1[p] <= avail[1];
                expr1.Clear();
                inputData.ProdList.ForEach(pl =>
                {
                    double rate      = 1 / inputData.RateList.Find(rl => rl.PROD.Equals(pl.PROD)).RATE;
                    double avail     = inputData.AvailList.Find(al => al.T.Equals(1)).AVAIL;
                    double rateAvail = avail / rate;
                    int ixP          = inputData.ProdList.IndexOf(pl);

                    gModel.AddConstr(Make1[ixP], GRB.GREATER_EQUAL, rateAvail, "TIME1");
                });


                //subject to Balance1 { p in PROD}:
                //Make1[p] + inv0[p] = Sell1[p] + Inv1[p];
                expr1.Clear();
                inputData.ProdList.ForEach(pl => {
                    expr1.Clear();

                    int ixP = inputData.ProdList.IndexOf(pl);
                    expr1.AddTerm(1, Sell1[ixP]);
                    expr1.AddTerm(1, Inv1[ixP]);
                    expr1.AddTerm(-1, Make1[ixP]);

                    double inv0 = inputData.Inv0List.Find(il => il.PROD.Equals(pl.PROD)).INV0;

                    gModel.AddConstr(inv0, GRB.EQUAL, expr1, "Balance1");
                });

                //carpeta donde se expande el modelo master
                gModel.Write(outputFolder + "Master_Model.lp");

                // RESOLVER EL MODELO
                try
                {
                    Console.WriteLine("Solving the master model with gurobi..");
                    gModel.Optimize();

                    if (gModel.Status == 2)
                    {
                        for (int m = 0; m < Make1.Length; m++)
                        {
                            Console.WriteLine("Make1 Var: " + Make1[m].VarName + " = " + Make1[m].X);
                        }

                        for (int m = 0; m < Inv1.Length; m++)
                        {
                            Console.WriteLine("Inv1 Var: " + Inv1[m].VarName + " = " + Inv1[m].X);
                        }

                        for (int m = 0; m < Sell1.Length; m++)
                        {
                            Console.WriteLine("Sell Var: " + Sell1[m].VarName + " = " + Sell1[m].X);
                        }
                    }

                    gModel.Dispose();
                    env.Dispose();

                    return(new MasterModelOutputs()
                    {
                        make1 = Make1,
                        sell1 = Sell1,
                        inv1 = Inv1,
                        expectedProfit = gModel.ObjVal,
                        gModel = gModel
                    });
                }
                catch { Console.WriteLine("ERROR SOLVING THE MODEL"); }

                gModel.Dispose();
                env.Dispose();
            }
            catch (GRBException ex)
            {
                Console.WriteLine("Error code: " + ex.ErrorCode + ". " + ex.Message);
            }

            return(new MasterModelOutputs());
        }