Пример #1
0
        private static void ScenSolve(GAMSWorkspace ws, GAMSCheckpoint cp, Queue <double> bmultQueue, Object queueMutex, Object ioMutex)
        {
            GAMSModelInstance mi = cp.AddModelInstance();

            GAMSParameter bmult = mi.SyncDB.AddParameter("bmult", 0, "demand multiplier");
            GAMSOptions   opt   = ws.AddOptions();

            opt.AllModelTypes = "cplexd";
            // instantiate the GAMSModelInstance and pass a model definition and GAMSModifier to declare bmult mutable
            mi.Instantiate("transport us lp min z", opt, new GAMSModifier(bmult));

            bmult.AddRecord().Value = 1.0;

            while (true)
            {
                double b;
                // dynamically get a bmult value from the queue instead of passing it to the different threads at creation time
                lock (queueMutex)
                {
                    if (0 == bmultQueue.Count)
                    {
                        return;
                    }
                    b = bmultQueue.Dequeue();
                }
                bmult.FirstRecord().Value = b;
                mi.Solve();
                // we need to make the ouput a critical section to avoid messed up report informations
                lock (ioMutex)
                {
                    Console.WriteLine("Scenario bmult=" + b + ":");
                    Console.WriteLine("  Modelstatus: " + mi.ModelStatus);
                    Console.WriteLine("  Solvestatus: " + mi.SolveStatus);
                    Console.WriteLine("  Obj: " + mi.SyncDB.GetVariable("z").FindRecord().Level);
                }
            }
        }
Пример #2
0
        // Needs to be called with an uninstantiated GAMSModelInstance
        static void GUSSCall(GAMSSet dict, GAMSModelInstance mi, string solveStatement, GAMSOptions opt = null, GAMSModelInstanceOpt miOpt = null, TextWriter output = null)
        {
            List <Tuple <GAMSModifier, GAMSParameter> > modifierList = new List <Tuple <GAMSModifier, GAMSParameter> >();

            if (dict.Dim != 3)
            {
                throw new GAMSException("Dict needs to be 3-dimensional");
            }

            string  scenName   = dict.FirstRecord(new string[] { " ", "scenario", " " }).Keys[0];
            GAMSSet scenSymbol = dict.GAMSDatabase.GetSet(scenName);


            foreach (GAMSSetRecord rec in dict)
            {
                if (rec.Keys[1].ToLower() == "scenario")
                {
                    continue;
                }
                if (rec.Keys[1].ToLower() == "param")
                {
                    int modifierDim = dict.GAMSDatabase.GetParameter(rec.Keys[2]).Dim - scenSymbol.Dim;
                    if (modifierDim < 0)
                    {
                        throw new GAMSException("Dimension of " + rec.Keys[2] + " too small");
                    }
                    modifierList.Add(new Tuple <GAMSModifier, GAMSParameter>
                                         (new GAMSModifier(mi.SyncDB.AddParameter(rec.Keys[0], modifierDim, "")),
                                         dict.GAMSDatabase.GetParameter(rec.Keys[2])));
                }
                else if ((rec.Keys[1].ToLower() == "lower") || (rec.Keys[1].ToLower() == "upper") || (rec.Keys[1].ToLower() == "fixed"))
                {
                    int modifierDim = dict.GAMSDatabase.GetParameter(rec.Keys[2]).Dim - scenSymbol.Dim;
                    if (modifierDim < 0)
                    {
                        throw new GAMSException("Dimension of " + rec.Keys[2] + " too small");
                    }
                    GAMSVariable modifierVar;
                    try
                    {
                        modifierVar = dict.GAMSDatabase.GetVariable(rec.Keys[0]);
                    }
                    catch (Exception)
                    {
                        modifierVar = mi.SyncDB.AddVariable(rec.Keys[0], modifierDim, VarType.Free, "");
                    }
                    if (rec.Keys[1].ToLower() == "lower")
                    {
                        modifierList.Add(new Tuple <GAMSModifier, GAMSParameter>
                                             (new GAMSModifier(modifierVar, UpdateAction.Lower, mi.SyncDB.AddParameter(rec.Keys[2], modifierDim, "")),
                                             dict.GAMSDatabase.GetParameter(rec.Keys[2])));
                    }
                    else if (rec.Keys[1].ToLower() == "upper")
                    {
                        modifierList.Add(new Tuple <GAMSModifier, GAMSParameter>
                                             (new GAMSModifier(modifierVar, UpdateAction.Upper, mi.SyncDB.AddParameter(rec.Keys[2], modifierDim, "")),
                                             dict.GAMSDatabase.GetParameter(rec.Keys[2])));
                    }
                    else  // fixed
                    {
                        modifierList.Add(new Tuple <GAMSModifier, GAMSParameter>
                                             (new GAMSModifier(modifierVar, UpdateAction.Fixed, mi.SyncDB.AddParameter(rec.Keys[2], modifierDim, "")),
                                             dict.GAMSDatabase.GetParameter(rec.Keys[2])));
                    }
                }
                else if ((rec.Keys[1].ToLower() == "level") || (rec.Keys[1].ToLower() == "marginal"))
                {
                    // Check that parameter exists in GAMSDatabase, will throw an exception if not
                    GAMSParameter x = dict.GAMSDatabase.GetParameter(rec.Keys[2]);
                }
                else
                {
                    throw new GAMSException("Cannot handle UpdateAction " + rec.Keys[1]);
                }
            }
            List <GAMSModifier> mL = new List <GAMSModifier>();

            foreach (Tuple <GAMSModifier, GAMSParameter> tup in modifierList)
            {
                mL.Add(tup.Item1);
            }
            mi.Instantiate(solveStatement, opt, mL.ToArray());

            List <Tuple <GAMSSymbol, GAMSParameter, string> > outList = new List <Tuple <GAMSSymbol, GAMSParameter, string> >();

            foreach (GAMSSetRecord s in scenSymbol)
            {
                foreach (Tuple <GAMSModifier, GAMSParameter> tup in modifierList)
                {
                    GAMSParameter p;
                    GAMSParameter pscen = tup.Item2;

                    if (tup.Item1.DataSym == null)
                    {
                        p = (GAMSParameter)tup.Item1.GamsSym;
                    }
                    else
                    {
                        p = tup.Item1.DataSym;
                    }

                    // Implemented SymbolUpdateType=BaseCase
                    p.Clear();

                    GAMSParameterRecord rec;
                    string[]            filter = new string[pscen.Dim];
                    for (int i = 0; i < scenSymbol.Dim; i++)
                    {
                        filter[i] = s.Keys[i];
                    }
                    for (int i = scenSymbol.Dim; i < pscen.Dim; i++)
                    {
                        filter[i] = " ";
                    }
                    try
                    {
                        rec = pscen.FirstRecord(filter);
                    }
                    catch (GAMSException)
                    {
                        continue;
                    }
                    do
                    {
                        string[] myKeys = new string[p.Dim];
                        for (int i = 0; i < p.Dim; i++)
                        {
                            myKeys[i] = rec.Keys[scenSymbol.Dim + i];
                        }
                        p.AddRecord(myKeys).Value = rec.Value;
                    } while (rec.MoveNext());
                }

                mi.Solve(GAMSModelInstance.SymbolUpdateType.BaseCase, output, miOpt);
                if (outList.Count == 0)
                {
                    foreach (GAMSSetRecord rec in dict)
                    {
                        if ((rec.Keys[1].ToLower() == "level") || (rec.Keys[1].ToLower() == "marginal"))
                        {
                            outList.Add(new Tuple <GAMSSymbol, GAMSParameter, string>(mi.SyncDB.GetSymbol(rec.Keys[0]), dict.GAMSDatabase.GetParameter(rec.Keys[2]), rec.Keys[1].ToLower()));
                        }
                    }
                }

                foreach (Tuple <GAMSSymbol, GAMSParameter, string> tup in outList)
                {
                    string[] myKeys = new string[scenSymbol.Dim + tup.Item1.FirstRecord().Keys.Length];
                    for (int i = 0; i < scenSymbol.Dim; i++)
                    {
                        myKeys[i] = s.Keys[i];
                    }

                    if ((tup.Item3 == "level") && (tup.Item1 is GAMSVariable))
                    {
                        foreach (GAMSVariableRecord rec in tup.Item1)
                        {
                            for (int i = 0; i < rec.Keys.Length; i++)
                            {
                                myKeys[scenSymbol.Dim + i] = s.Keys[i];
                            }
                            tup.Item2.AddRecord(myKeys).Value = rec.Level;
                        }
                    }
                    else if ((tup.Item3 == "level") && (tup.Item1 is GAMSEquation))
                    {
                        foreach (GAMSEquationRecord rec in tup.Item1)
                        {
                            for (int i = 0; i < rec.Keys.Length; i++)
                            {
                                myKeys[scenSymbol.Dim + i] = s.Keys[i];
                            }
                            tup.Item2.AddRecord(myKeys).Value = rec.Level;
                        }
                    }
                    else if ((tup.Item3 == "marginal") && (tup.Item1 is GAMSVariable))
                    {
                        foreach (GAMSVariableRecord rec in tup.Item1)
                        {
                            for (int i = 0; i < rec.Keys.Length; i++)
                            {
                                myKeys[scenSymbol.Dim + i] = s.Keys[i];
                            }
                            tup.Item2.AddRecord(myKeys).Value = rec.Marginal;
                        }
                    }
                    else if ((tup.Item3 == "marginal") && (tup.Item1 is GAMSEquation))
                    {
                        foreach (GAMSEquationRecord rec in tup.Item1)
                        {
                            for (int i = 0; i < rec.Keys.Length; i++)
                            {
                                myKeys[scenSymbol.Dim + i] = s.Keys[i];
                            }
                            tup.Item2.AddRecord(myKeys).Value = rec.Marginal;
                        }
                    }
                }
            }
        }
Пример #3
0
        static void Main(string[] args)
        {
            GAMSWorkspace ws;

            if (Environment.GetCommandLineArgs().Length > 1)
            {
                ws = new GAMSWorkspace(systemDirectory: Environment.GetCommandLineArgs()[1]);
            }
            else
            {
                ws = new GAMSWorkspace();
            }
            GAMSCheckpoint cp = ws.AddCheckpoint();

            // initialize a GAMSCheckpoint by running a GAMSJob
            GAMSJob t7 = ws.AddJobFromString(GetModelText());

            t7.Run(cp);

            // create a GAMSModelInstance and solve it multiple times with different scalar bmult
            GAMSModelInstance mi = cp.AddModelInstance();

            GAMSParameter bmult = mi.SyncDB.AddParameter("bmult", 0, "demand multiplier");
            GAMSOptions   opt   = ws.AddOptions();

            opt.AllModelTypes = "gurobi";

            // instantiate the GAMSModelInstance and pass a model definition and GAMSModifier to declare bmult mutable
            mi.Instantiate("transport us lp min z", opt, new GAMSModifier(bmult));

            bmult.AddRecord().Value = 1.0;
            double[] bmultlist      = new double[] { 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3 };

            foreach (double b in bmultlist)
            {
                bmult.FirstRecord().Value = b;
                mi.Solve();
                Console.WriteLine("Scenario bmult=" + b + ":");
                Console.WriteLine("  Modelstatus: " + mi.ModelStatus);
                Console.WriteLine("  Solvestatus: " + mi.SolveStatus);
                Console.WriteLine("  Obj: " + mi.SyncDB.GetVariable("z").FindRecord().Level);
            }

            // create a GAMSModelInstance and solve it with single links in the network blocked
            mi = cp.AddModelInstance();

            GAMSVariable  x   = mi.SyncDB.AddVariable("x", 2, VarType.Positive, "");
            GAMSParameter xup = mi.SyncDB.AddParameter("xup", 2, "upper bound on x");

            // instantiate the GAMSModelInstance and pass a model definition and GAMSModifier to declare upper bound of X mutable
            mi.Instantiate("transport us lp min z", modifiers: new GAMSModifier(x, UpdateAction.Upper, xup));

            foreach (GAMSSetRecord i in t7.OutDB.GetSet("i"))
            {
                foreach (GAMSSetRecord j in t7.OutDB.GetSet("j"))
                {
                    xup.Clear();
                    xup.AddRecord(i.Keys[0], j.Keys[0]).Value = 0;
                    mi.Solve();
                    Console.WriteLine("Scenario link blocked: " + i.Keys[0] + " - " + j.Keys[0]);
                    Console.WriteLine("  Modelstatus: " + mi.ModelStatus);
                    Console.WriteLine("  Solvestatus: " + mi.SolveStatus);
                    Console.WriteLine("  Obj: " + mi.SyncDB.GetVariable("z").FindRecord().Level);
                }
            }
        }
        public void ProcessTask(TaskManager.TaskDetails oTask, out List <string> lsLogs, out string sOutput, out string sStatus)
        {
            // cast input values
            CutStockInput oInput = new CutStockInput();

            oInput = (CutStockInput)oDF.XmlStringToObject(oTask.InputValues, oInput);

            CutStockOutput oOutput = new CutStockOutput();

            // call processing algorithm

            GAMSWorkspace ws = new GAMSWorkspace();

            lsLog.Add("working directory : " + ws.WorkingDirectory);
            // instantiate GAMSOptions and define parameters
            GAMSOptions  opt          = ws.AddOptions();
            GAMSDatabase cutstockData = ws.AddDatabase("csdata");

            opt.AllModelTypes = "Cplex";
            opt.OptCR         = 0.0; // Solve to optimality
            opt.Defines.Add("pmax", oInput.MaxPattern.ToString());
            opt.Defines.Add("solveMasterAs", "RMIP");

            GAMSSet       widths   = cutstockData.AddSet("i", 1, "widths");
            GAMSParameter rawWidth = cutstockData.AddParameter("r", 0, "raw width");
            GAMSParameter demand   = cutstockData.AddParameter("d", 1, "demand");
            GAMSParameter width    = cutstockData.AddParameter("w", 1, "width");

            rawWidth.AddRecord().Value = oInput.RawWidth;

            foreach (CutItem oI in oInput.Items)
            {
                widths.AddRecord(oI.Name);
                demand.AddRecord(oI.Name).Value = oI.Demand;
                width.AddRecord(oI.Name).Value  = oI.Width;
            }

            // create initial checkpoint
            GAMSCheckpoint masterCP      = ws.AddCheckpoint();
            GAMSJob        masterInitJob = ws.AddJobFromString(GetMasterModel());

            masterInitJob.Run(opt, masterCP, cutstockData);

            GAMSJob masterJob = ws.AddJobFromString("execute_load 'csdata', aip, pp; solve master min z using %solveMasterAs%;", masterCP);

            GAMSSet       pattern     = cutstockData.AddSet("pp", 1, "pattern index");
            GAMSParameter patternData = cutstockData.AddParameter("aip", 2, "pattern data");

            // Initial pattern: pattern i hold width i
            int patternCount = 0;

            foreach (GAMSParameterRecord rec in width)
            {
                patternData.AddRecord(rec.Keys[0], pattern.AddRecord((++patternCount).ToString()).Keys[0]).Value = (int)(oInput.RawWidth / rec.Value);
            }

            // create model instance for sub job
            GAMSCheckpoint subCP = ws.AddCheckpoint();

            ws.AddJobFromString(GetSubModel()).Run(opt, subCP, cutstockData);
            GAMSModelInstance subMI = subCP.AddModelInstance();

            // define modifier demdual
            GAMSParameter demandDual = subMI.SyncDB.AddParameter("demdual", 1, "dual of demand from master");

            subMI.Instantiate("pricing min z using mip", opt, new GAMSModifier(demandDual));

            // find new pattern
            bool patternAdded = true;

            do
            {
                masterJob.Run(opt, masterCP, cutstockData);
                // Copy duals into gmssubMI.SyncDB DB
                demandDual.Clear();
                foreach (GAMSEquationRecord dem in masterJob.OutDB.GetEquation("demand"))
                {
                    demandDual.AddRecord(dem.Keys[0]).Value = dem.Marginal;
                }

                subMI.Solve();
                if (subMI.SyncDB.GetVariable("z").FindRecord().Level < -0.00001)
                {
                    if (patternCount == oInput.MaxPattern)
                    {
                        lsLog.Add("Out of pattern. Increase maxpattern (currently " + oInput.MaxPattern + ")." + Environment.NewLine);
                        patternAdded = false;
                    }
                    else
                    {
                        lsLog.Add("New pattern! Value: " + subMI.SyncDB.GetVariable("z").FindRecord().Level + Environment.NewLine);
                        GAMSSetRecord s = pattern.AddRecord((++patternCount).ToString());
                        foreach (GAMSVariableRecord y in subMI.SyncDB.GetVariable("y"))
                        {
                            if (y.Level > 0.5)
                            {
                                patternData.AddRecord(y.Keys[0], s.Keys[0]).Value = Math.Round(y.Level);
                            }
                        }
                    }
                }
                else
                {
                    patternAdded = false;
                }
            } while (patternAdded);

            // solve final MIP
            opt.Defines["solveMasterAs"] = "MIP";
            masterJob.Run(opt, cutstockData);
            var dlevel = masterJob.OutDB.GetVariable("z").FindRecord().Level;

            oOutput.OptimalSolution = (int)dlevel;
            lsLog.Add("Optimal Solution: " + dlevel + Environment.NewLine);
            List <Pattern> lP = new List <Pattern>();

            foreach (GAMSVariableRecord xp in masterJob.OutDB.GetVariable("xp"))
            {
                string sPatternLog = "";
                if (xp.Level > 0.5)
                {
                    sPatternLog = string.Format("  pattern {0,2} {1,4} times: ", xp.Keys[0], Math.Round(xp.Level));
                    GAMSParameterRecord aip = masterJob.OutDB.GetParameter("aip").FirstRecord(" ", xp.Keys[0]);

                    Pattern oP = new Pattern()
                    {
                        Name = "pattern " + xp.Keys[0].ToString(), Count = (int)Math.Round(xp.Level)
                    };
                    List <PatternPiece> lPP = new List <PatternPiece>();
                    int    x     = 0;
                    double scale = 100 / masterJob.OutDB.GetParameter("r").FirstRecord().Value;
                    do
                    {
                        sPatternLog += " " + aip.Keys[0] + ": " + aip.Value.ToString();
                        // draw cuts
                        for (int i = 0; i < aip.Value; i++)
                        {
                            PatternPiece oPP = new PatternPiece()
                            {
                                Name  = aip.Keys[0],
                                Width = (int)(width.FindRecord(aip.Keys[0]).Value *scale),
                                Left  = x,
                                Color = oInput.Items.Where(xi => xi.Name == aip.Keys[0]).FirstOrDefault().Color
                            };
                            lPP.Add(oPP);
                            // x += oPP.Width - 1;
                            x += oPP.Width;
                        }
                    } while (aip.MoveNext());

                    if (x < 100)
                    {
                        PatternPiece oPExcess = new PatternPiece()
                        {
                            Name  = "E",
                            Width = (int)(rawWidth.FirstRecord().Value *scale - x),
                            Left  = x,
                            Color = "CCCCCC"
                        };
                        lPP.Add(oPExcess);
                    }
                    lsLog.Add(sPatternLog);
                    oP.Pieces = lPP.ToArray();
                    lP.Add(oP);
                }
            }

            oOutput.Patterns = lP.ToArray();
            // clean up of unmanaged resources
            cutstockData.Dispose();
            subMI.Dispose();
            opt.Dispose();


            sOutput = oDF.ObjectToXmlString(oOutput);
            sStatus = "completed";
            lsLogs  = lsLog;
        }