Ejemplo n.º 1
0
        public Reporte(Simplex sollutions)
        {
            _sollutions = sollutions;

            SimplexSolverParams solverParams = new SimplexSolverParams();

            solverParams.GetSensitivityReport = true;

            _sollutions.Solver.Solve(solverParams);

            _reportSensitivity = _sollutions.Solver.GetReport(LinearSolverReportType.Sensitivity);
            _sensitivityReport = _reportSensitivity as ILinearSolverSensitivityReport;
        }
Ejemplo n.º 2
0
Archivo: Otm.cs Proyecto: falreis/tcc
        public void Get()
        {
            SimplexSolver solver = new SimplexSolver();

            double[] estimatedProfitOfProjectX  = new double[] { 1, 1.8, 1.6, 0.8, 1.4 };
            double[] capitalRequiredForProjectX = new double[] { 6, 12, 10, 4, 8 };
            double   availableCapital           = 20;

            int[] chooseProjectX = new int[5];

            int profit;

            solver.AddRow("profit", out profit);
            solver.AddGoal(profit, 0, false);

            int expenditure;

            solver.AddRow("expenditure", out expenditure);
            solver.SetBounds(expenditure, 0, availableCapital);

            for (int i = 0; i < 5; i++)
            {
                solver.AddVariable(string.Format("project{0}", i), out chooseProjectX[i]);
                solver.SetBounds(chooseProjectX[i], 0, 1);
                solver.SetIntegrality(chooseProjectX[i], true);
                solver.SetCoefficient(profit, chooseProjectX[i], estimatedProfitOfProjectX[i]);
                solver.SetCoefficient(expenditure, chooseProjectX[i], capitalRequiredForProjectX[i]);
            }

            SimplexSolverParams param = new SimplexSolverParams();

            param.MixedIntegerGenerateCuts = true;
            solver.Solve(param);

            Console.WriteLine(solver.MipResult);
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Project {0} is {1} selected.", i, solver.GetValue(chooseProjectX[i]) == 1 ? "" : "not ");
            }
            Console.WriteLine("The estimated total profit is: ${0} million.", (double)solver.GetValue(profit).ToDouble());
            Console.WriteLine("The total expenditure is: ${0} million.", solver.GetValue(expenditure).ToDouble());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Solves a sample (randomly generated?) cutting stock problem.
        /// Given a bolt of cloth of fixed width, and demand for cut strips of the cloth, determine the min "loss" cut patterns to use and how many
        /// of them.
        /// Loss is defined as the scrap thrown away.
        /// It is acceptable to have extra cut widths made.  They do not contribute to the cost.  (this may be unrealistic in the real world)
        /// Solver runs by 1st creating an enumeration of possible cut patterns using a CspSolver, then choosing between the patterns and selecting a qty of the patterns such that the
        /// amount of scrap is minimized and all demand is met using the SimplexSolver MIP code.
        ///
        /// In an industrial case, there would likely be more constraints in the generation of the cut patterns.  There can be other restrictions such as "these can't be done together"
        /// or "these MUST be done together (matching pattern or color?)".  This can easily be added to the CspSolver model.
        /// Also, there are likely other characteristics of the cuts or the master problem which would need adaptations.
        ///
        /// Further, the limit on the columns generated is implemented in a very arbitrary order.  It is more likely that some ordering of the
        /// value of the columns is needed.  In most industrial occurances, the dual variables from the LP relaxation would likely be used to
        /// guide the generation of columns in an interative fasion rather than a one-time shot at the beginning.
        ///
        /// YMMV
        /// </summary>
        public static void ShortCuttingStock()
        {
            Console.WriteLine("*** Short Cutting Stock ***");
            int    NumItems    = 5;     // how many cut widths to generate
            int    ClothWidth  = 40;    // width of the stock to cut the widths from
            double efficiency  = 0.7;   // reject cut patterns less than this % used of the clothwidth
            int    maxPatterns = 100;   // max # of patterns to generate
            bool   verbose     = true;  // set this to true if you want some (useful?) output
            bool   saveMpsFile = false; // set this to true if you want it to save an mps file in c:\\temp\\cutstock.mps

            int itemSizeMin   = 5;      // minimum size for random generation of cut
            int itemSizeMax   = 10;     // maximum size for random generation of cut
            int itemDemandMin = 10;     // minimum random demand for each cut
            int itemDemandMax = 40;     // maximum random demand for each cut

            int seed = 12447;           // use System.DateTime.Now.Millisecond; instead if you want a random problem.

            if (verbose)
            {
                System.Console.WriteLine(String.Format("Random seed={0}\tmaxWidth={1}", seed, ClothWidth));
            }

            Random rand = new Random(seed);

            int[] cuts   = new int[NumItems];
            int[] demand = new int[NumItems];
            // item weights and demands
            for (int cnt = 0; cnt < NumItems; cnt++)
            {
                cuts[cnt]   = rand.Next(itemSizeMin, itemSizeMax);;
                demand[cnt] = rand.Next(itemDemandMin, itemDemandMax);
                if (verbose)
                {
                    System.Console.WriteLine(String.Format("item[{0}]\tweight={1}\tdemand={2}", cnt, cuts[cnt], demand[cnt]));
                }
            }
            List <int[]> patterns;

            SolveKnapsack(maxPatterns, cuts, ClothWidth, efficiency, out patterns);
            SimplexSolver solver2 = new SimplexSolver();
            int           vId     = 0;

            int[] usage = new int[patterns.Count];
            // construct rows that make sure that the demand is met for each kind of cut
            for (int cnt = 0; cnt < NumItems; cnt++)
            {
                solver2.AddRow(String.Format("item{0}", cnt), out vId);
                solver2.SetBounds(vId, demand[cnt], Rational.PositiveInfinity);
            }
            int patCnt = 0;

            if (verbose)
            {
                System.Console.WriteLine(String.Format("Generated {0} patterns", patterns.Count));
            }
            // set usage coeffs (A matrix entries) -- put the patterns as columns in the MIP.
            Dictionary <int, int> patIdForCol = new Dictionary <int, int>();

            foreach (int[] pattern in patterns)
            {
                int    pId     = 0;
                String varName = String.Format("Pattern{0}", patCnt);
                solver2.AddVariable(varName, out pId);
                patIdForCol[pId] = patCnt;
                solver2.SetIntegrality(pId, true);
                solver2.SetBounds(pId, 0, Rational.PositiveInfinity);
                for (int cnt = 0; cnt < NumItems; cnt++)
                {
                    solver2.SetCoefficient(cnt, pId, pattern[cnt]); // set the coefficient in the matrix
                                                                    // accumulate the quantity used for this pattern.  It will be used to figure out the scrap later.
                    usage[patCnt] += pattern[cnt] * cuts[cnt];
                }
                patCnt++;
            }
            // set objective coeffs.  --- the cost is the scrap
            solver2.AddRow("Scrap", out vId);
            for (int cnt = 0; cnt < patterns.Count; cnt++)
            {
                int colId = solver2.GetIndexFromKey(String.Format("Pattern{0}", cnt));
                solver2.SetCoefficient(vId, colId, (ClothWidth - usage[cnt]));
            }
            solver2.AddGoal(vId, 0, true);
            // invoke the IP solver.
            SimplexSolverParams parms = new SimplexSolverParams();

            parms.MixedIntegerGenerateCuts = true;
            parms.MixedIntegerPresolve     = true;

            if (saveMpsFile)
            {
                MpsWriter writer = new MpsWriter(solver2);
                using (TextWriter textWriter = new StreamWriter(File.OpenWrite("c:\\temp\\cutstock.mps")))
                {
                    writer.WriteMps(textWriter, true);
                }
            }
            solver2.Solve(parms);
            if (solver2.LpResult == LinearResult.Optimal &&
                solver2.MipResult == LinearResult.Optimal)
            {
                //Rational[] solutionVals = solver2.GetValues();
                int goalIndex = 0;
                // output if desired.
                if (verbose)
                {
                    System.Console.WriteLine("Solver complete, printing cut plan.");
                    foreach (int cnt in solver2.VariableIndices)
                    {
                        Rational val = solver2.GetValue(cnt);
                        if (val != 0)
                        {
                            if (solver2.IsGoal(cnt))
                            {
                                goalIndex = cnt;
                                System.Console.WriteLine(String.Format("Goal:{0}\t:   {1}\t", val, solver2.GetKeyFromIndex(cnt)));
                            }
                            else if (solver2.IsRow(cnt))
                            {
                                System.Console.WriteLine(String.Format("{0}:\tValue=   {1}\t", solver2.GetKeyFromIndex(cnt), val));
                            }
                            else
                            {
                                System.Console.Write(String.Format("{0}\tQuantity={1}:\t", solver2.GetKeyFromIndex(cnt), val));
                                for (int cnt2 = 0; cnt2 < NumItems; cnt2++)
                                {
                                    System.Console.Write(String.Format("{0} ", patterns[patIdForCol[cnt]][cnt2]));
                                }
                                System.Console.WriteLine(String.Format("\tUsage:{0} / {2} efficiency={1}%", usage[cnt - NumItems], (int)(100 * (double)usage[cnt - NumItems] / (double)ClothWidth), ClothWidth));
                            }
                        }
                    }
                    System.Console.WriteLine(String.Format("Total scrap={0}", solver2.GetSolutionValue(goalIndex)));
                }
            }
            else
            {
                System.Console.WriteLine("Generated problem is infeasible.  It is likely that more generated columns are needed.");
            }

            Console.WriteLine();
        }
Ejemplo n.º 4
0
        public List <Bag.Item> LinearProgramming(List <Item> items)
        {
            List <Bag.Item> choosenItems = new List <Bag.Item>();
            int             itemsCount   = items.Count;
            double          capacity     = MaxWeightAllowed;

            SimplexSolver solver = new SimplexSolver();

            //double[] estimatedProfitOfProjectX = new double[] { 1, 1.8, 1.6, 0.8, 1.4 };
            //double[] capitalRequiredForProjectX = new double[] { 6, 12, 10, 4, 8 };
            //double availableCapital = 20;
            //int[] chooseProjectX = new int[5];

            double[] values  = new double[itemsCount];
            double[] weights = new double[itemsCount];

            for (int i = 0; i < itemsCount; i++)
            {
                values[i]  = items[i].Value;
                weights[i] = items[i].Weight;
            }

            int[] chosenItems = new int[itemsCount];

            //int profit;
            //solver.AddRow("profit", out profit);
            //solver.AddGoal(profit, 0, false);

            int MaximumValue;

            solver.AddRow("MaximumValue", out MaximumValue);
            solver.AddGoal(MaximumValue, 0, false);

            //int expenditure;
            //solver.AddRow("expenditure", out expenditure);
            //solver.SetBounds(expenditure, 0, availableCapital);

            int MaximumWeight;

            solver.AddRow("MaximumWeight", out MaximumWeight);
            solver.SetBounds(MaximumWeight, 0, capacity);

            //for (int i = 0; i < 5; i++)
            //{
            //    solver.AddVariable(string.Format("project{0}", i),
            //                        out chooseProjectX[i]);
            //    solver.SetBounds(chooseProjectX[i], 0, 1);
            //    solver.SetIntegrality(chooseProjectX[i], true);
            //    solver.SetCoefficient(profit, chooseProjectX[i],
            //                           estimatedProfitOfProjectX[i]);
            //    solver.SetCoefficient(expenditure, chooseProjectX[i],
            //                           capitalRequiredForProjectX[i]);
            //}

            for (int i = 0; i < itemsCount; i++)
            {
                solver.AddVariable(string.Format("Item{0}", i),
                                   out chosenItems[i]);
                solver.SetBounds(chosenItems[i], 0, 1);
                solver.SetIntegrality(chosenItems[i], true);
                solver.SetCoefficient(MaximumValue, chosenItems[i],
                                      values[i]);
                solver.SetCoefficient(MaximumWeight, chosenItems[i],
                                      weights[i]);
            }

            //SimplexSolverParams param = new SimplexSolverParams();
            //param.MixedIntegerGenerateCuts = true;
            //solver.Solve(param);

            SimplexSolverParams param = new SimplexSolverParams();

            param.MixedIntegerGenerateCuts = true;
            solver.Solve(param);

            //Console.WriteLine(solver.MipResult);
            //for (int i = 0; i < 5; i++)
            //{
            //    Console.WriteLine("Project {0} is {1} selected.", i,
            //                    solver.GetValue(chooseProjectX[i]) == 1 ? "" : "not ");
            //}
            //Console.WriteLine("The estimated total profit is: ${0} million.",
            //                  (double)solver.GetValue(profit).ToDouble());
            //Console.WriteLine("The total expenditure is: ${0} million.",
            //                   solver.GetValue(expenditure).ToDouble());

            //string result = "";
            for (int i = 0; i < itemsCount; i++)
            {
                if (solver.GetValue(chosenItems[i]) == 1)
                {
                    //result += "Selected Item " + i + " ";
                    choosenItems.Add(items[i]);
                }
            }

            //result += " value "+(double)solver.GetValue(MaximumValue).ToDouble()+ " weight "+ solver.GetValue(MaximumWeight).ToDouble();


            return(choosenItems);
        }
Ejemplo n.º 5
0
        protected static void CCN_Simplex()
        {
            int param1 = ReadSelectionInt("Max agents", 100, min: 1, max: 1000);
            var param3 = ReadSelectionInt("Max time\"", 120, min: 10, max: 1200);

            //Set agent shifts
            var      solveShifts = new CSP.ShiftsPlanner(param1);
            TimeSpan ts8h        = GetTimeSpanHours(8);
            TimeSpan ts9h        = GetTimeSpanHours(9);
            TimeSpan ts10h       = GetTimeSpanHours(10);
            TimeSpan ts30mi      = GetTimeSpanMinutes(30);

            var shifts = new List <CSP.Models.Shift>();

            shifts.Add(new CSP.Models.Shift(name: "A", start: GetTimeSpanHours(7), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "G", start: GetTimeSpanHours(8), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "B", start: GetTimeSpanHours(9), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "I", start: GetTimeSpanHours(10), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "E", start: GetTimeSpanHours(11), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "D", start: GetTimeSpanHours(13), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "C", start: GetTimeSpanHours(15), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "CL", start: GetTimeSpanHours(16), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "H", start: GetTimeSpanHours(17), duration: ts8h));

            shifts.Add(new CSP.Models.Shift(name: "A++", start: GetTimeSpanHours(7), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "B+", start: GetTimeSpanHours(9), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "B++", start: GetTimeSpanHours(9), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "I+", start: GetTimeSpanHours(10), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "I++", start: GetTimeSpanHours(10), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "E+", start: GetTimeSpanHours(11), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "E++", start: GetTimeSpanHours(11), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "+D", start: GetTimeSpanHours(12), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "D++", start: GetTimeSpanHours(13), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "C+", start: GetTimeSpanHours(15), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "CL+", start: GetTimeSpanHours(16), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "++H", start: GetTimeSpanHours(15), duration: ts10h));
            solveShifts.Shifts = shifts;

            //Set requirements per shift
            int[]    liveData     = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 9, 11, 22, 25, 21, 32, 44, 38, 33, 48, 41, 54, 50, 42, 43, 45, 60, 62, 56, 44, 33, 22, 11, 18, 16, 24, 28, 6, 12, 15, 8, 6 };
            var      requirements = new List <CSP.Models.HalfHourRequirement>();
            TimeSpan ts           = GetTimeSpanHours(0);

            for (int i = 0; i < liveData.Length; i++)
            {
                requirements.Add(new CSP.Models.HalfHourRequirement(start: ts, requiredForce: liveData[i]));
                ts = ts.Add(ts30mi);
            }
            solveShifts.HalfHourRequirements = requirements;

            //pair shifts with vids
            Dictionary <CSP.Models.Shift, int> shiftsX;
            int             vidGoal;
            var             SX       = solveShifts.PrepareSimplexSolver(maxAgents: param1, shiftsExt: out shiftsX, vidGoal: out vidGoal);
            var             sxParams = new SimplexSolverParams();
            ILinearSolution solution = null;

            Task taskSolve = new Task(() =>
            {
                solution = SX.Solve(sxParams);
            });
            Stopwatch timer = new Stopwatch();

            timer.Start();
            taskSolve.Start();

            TimeSpan limit = new TimeSpan(hours: 0, minutes: 0, seconds: param3);

            while (!taskSolve.IsCompleted)
            {
                Console.SetCursorPosition(0, Console.CursorTop);
                Console.Write("  {0:hh}:{0:mm}:{0:ss}", timer.Elapsed);
                Thread.Sleep(millisecondsTimeout: 500);
            }
            Console.WriteLine("\n");

            timer.Stop();

            if (solution.Result == LinearResult.Feasible || solution.Result == LinearResult.Optimal)
            {
                Console.WriteLine(" solved as {1} after {0}", timer.Elapsed, solution.Result);
                Console.WriteLine("Goal: {0}", solution.GetValue(vidGoal).ToDouble());
                List <CSP.Models.ShiftForce> shiftsForce = new List <CSP.Models.ShiftForce>();
                foreach (var shift in shiftsX)
                {
                    var force = solution.GetValue(shift.Value).ToDouble();
                    shiftsForce.Add(new CSP.Models.ShiftForce(shift: shift.Key, force: (int)force));
                }
                solveShifts.ShowSolution(1, shiftsForce, showAgents: true, showSlots: true);
            }
            else
            {
                Console.WriteLine(" no solved :: {1} after {0}", timer.Elapsed, solution.Result);
            }
        }