예제 #1
0
        /// <summary>
        /// This is final model to solve. You can see it is the same model except this is a MIP
        /// </summary>
        public void SolveFinalMIPModel()
        {
            SetCurrentToMaster(Domain.IntegerNonnegative);
            Model            masterMIPModel = _context.CurrentModel;
            SimplexDirective simplex        = new SimplexDirective();
            Solution         sol            = _context.Solve(simplex);

            if (sol.Quality == SolverQuality.Optimal)
            {
                Console.WriteLine("\n**** Final Solution ****");
                var goal = masterMIPModel.Goals.First().ToDouble();
                PrintSolution(masterMIPModel.Decisions.First().GetValues(), goal, true);
            }

            //TODO: PrintSolution(masterMIPModel.Decisions.First().GetValues()) & Report report = sol.GetReport(ReportVerbosity.All) SHOW DIFF VALUES!!!
            //2nd appears to be more accurate

            Report report = sol.GetReport(ReportVerbosity.All);

            Console.WriteLine(report);
        }
예제 #2
0
        /// <summary>
        /// Initially formulate the model as an LP
        /// Solve the LP model. If the model is solved to an optimal result,
        /// find the duals of the constraints. FindNewPattern() method uses duals and
        /// tries to find a new pattern. If a new pattern is found, it is added to the PatternRolls data.
        /// This model keeps on growing if there is a new pattern found in the FindNewPattern() method
        /// and resolved. This process continues until there is no new pattern
        /// </summary>
        /// <returns>Returns true if an optimal solution is found, otherwise false</returns>
        public bool SolveMasterModel()
        {
            SetCurrentToMaster(Domain.RealNonnegative);
            Model            masterModel = _context.CurrentModel;
            SimplexDirective simplex     = new SimplexDirective();

            simplex.GetSensitivity = true; //setting this to true, generates shadow prices, needed to calc new pattern
            Solution sol = _context.Solve(simplex);

            //Check if the solution is optimal
            if (sol.Quality == SolverQuality.Optimal)
            {
                Report report = sol.GetReport(ReportVerbosity.All);

                //LinearReport has the Sensitivity report
                LinearReport lpReport = report as LinearReport;

                //Copying the duals from lpReport.GetShadowPrices
                //This is needed to match indexes (Roll Widths) in the SetRoll. For example: GetShadowPrices returns the keys as DemandConstraint(12),
                //but keys should just be 12 to match the indexes
                //Currently a limitation with our API
                //https://ideas.repec.org/p/fth/nesowa/96-18.html
                _shadowPrices.Clear();
                foreach (KeyValuePair <string, Rational> pair in lpReport.GetShadowPrices(masterModel.Constraints.First()))
                {
                    _shadowPrices.Add(new KeyValuePair <int, Rational>(GetIndexFromName(pair.Key), pair.Value));
                }
                //we have defined a single decision with multiple values (how many cuts per pattern to reach demanded rolls)
                var goal = masterModel.Goals.First().ToDouble();
                PrintSolution(masterModel.Decisions.First().GetValues(), goal, false);
                //Console.WriteLine();
                //Console.WriteLine("Now totalRolls required to meet the demand:{0}", masterModel.Goals.First().ToDouble());
                //Console.WriteLine();
                return(true);
            }
            return(false);
        }
예제 #3
0
        private void button_Click(object sender, RoutedEventArgs e)
        {
            context.ClearModel();
            Model model = context.CreateModel();

            List <Decision> decisions = new List <Decision>();

            var    formula = "";
            string con     = "";

            foreach (var item in dataGridVars.Items)
            {
                string li       = "L" + (item as Invester).Line;
                double maxValue = Double.Parse((item as Invester).MaxValue) * Double.Parse(Value.Text) / 100f;
                String contrain = li + " <= " + maxValue;
                ParseContrain(contrain);
                con += " " + li + " +";
                Decision dc = new Decision(Domain.RealRange(0, maxValue), li);
                decisions.Add(dc);
                model.AddDecision(dc);
            }
            ParseContrain(con.Substring(0, con.Length - 1) + " >= " + Value.Text);
            foreach (var item in dataGridVars.Items)
            {
                formula += " " + Double.Parse((item as Invester).Interest) + " * L" + (item as Invester).Line;
                if ((item as Invester).Line <= dataGridVars.Items.Count - 1)
                {
                    formula += " +";
                }
                String contrain = "L" + (item as Invester).Line + " >= 0 ";
                ParseContrain(contrain);
            }
            TargetFormula = formula.Substring(1, formula.Length - 2);

            FormulaTB.Text = TargetFormula;

            foreach (var list in ListOfContrains)
            {
                string c = "";
                for (int i = 0; i < list.Capacity; i++)
                {
                    if (i != 0 && i < list.Capacity - 1)
                    {
                        c += list[i] >= 0 ? " + " : " - ";
                    }
                    if (i == list.Capacity - 1)
                    {
                        c += " " + listOfStringContrains[ListOfContrains.IndexOf(list)] + " " + list[i];
                    }
                    else
                    {
                        c += Math.Abs(list[i]) + " * L" + i;
                    }
                }
                model.AddConstraint("C" + ListOfContrains.IndexOf(list), c);

                Console.WriteLine(c);
            }
            model.AddGoal("Goal", GoalKind.Minimize, TargetFormula);
            var directive = new SimplexDirective()
            {
                IterationLimit = -1,
                TimeLimit      = -1,
                Arithmetic     = Arithmetic.Exact,
                GetSensitivity = true
            };
            Solution solution = context.Solve(directive);

            Quality.Text = solution.Quality.ToString();
            Console.WriteLine(solution.GetReport().ToString());
            if (solution.Quality != SolverQuality.Optimal)
            {
                return;
            }

            context.PropagateDecisions();

            for (int i = 0; i < decisions.Count; i++)
            {
                var old = (dataGridVars.Items[i] as Invester);
                old.SelectedValue     = decisions[i].ToDouble().ToString();
                dataGridVars.Items[i] = old;
            }
            dataGridVars.Items.Refresh();
            dataGridVars.UpdateLayout();
        }
예제 #4
0
        public void getDemo()
        {
            Console.WriteLine("Enter the name of input file");


            //Singleton Design Pattern
            var solver = SolverContext.GetContext();

            // Create empty model
            var model = solver.CreateModel();

            //get data
            string[] data;
            string   input = Console.ReadLine();

            //valid file name control
            try
            {
                new Info(input);
            }
            catch (ArgumentException e)
            {
                Console.WriteLine(e.Message + "\nProcess failed.");
                Console.ReadKey();
                return;
            }
            Info info = new Info(input);



            //read data from file
            data = info.Read();


            //all the information we put into the necessary collections
            info.allInfo();



            //create variables
            Decision[] xs = new GetDecision().getX(data.Length - 1);
            Decision[] ys = new GetDecision().getY(data.Length - 1);

            //add xs and ys
            model.AddDecisions(xs);
            model.AddDecisions(ys);

            // I addded Wts and Zts
            List <Term> wt = info.addWt(xs);
            List <Term> zt = info.addZt(ys);

            //ı adeed constraints
            for (int i = 0; i < wt.Count; i++)
            {
                model.AddConstraint(("Constraint1_" + i), info.D[i] <= wt[i] + zt[i] + info.E[i]);
            }
            for (int i = 0; i < wt.Count; i++)
            {
                model.AddConstraint(("Constraint2_" + i), zt[i] <= 0.2 * (wt[i] + zt[i] + info.E[i]));
            }

            // I took the  expression from term denominated of z equation
            model.AddGoal("Goal", GoalKind.Minimize, info.getGoalTerm(xs, ys));

            //Report and solution part
            // SimplexDirective = Instruction, orders. It's about how you're going to work on what you want to figure out
            SimplexDirective simplex  = new SimplexDirective();
            Solution         solution = solver.Solve(simplex);


            //print report
            Console.WriteLine("--------------------------------------------");
            Report report = solution.GetReport();

            Console.Write("{0}", report);
            Console.WriteLine("--------------------------------------------\n\n");


            //our comment
            getFormat();

            //I got the variables into an array
            double[] varResults = new double[xs.Length * 2];
            int      k          = 0;

            foreach (Decision d in solution.Decisions)
            {
                varResults[k] = d.ToDouble();

                k++;
            }
            double totalCost = 0.0;

            k = 0;
            int m = varResults.Length / 2;

            //using the array in the specified format
            for (int i = 0; i < varResults.Length / 2; i++)
            {
                Console.WriteLine("\n\n" + info.t[k] + ".year ->> (" + info.c[k] + "  *  " + varResults[k] + ")  =  " + info.c[k] * varResults[k]);
                Console.WriteLine(info.t[k] + ".year ->> (" + info.n[k] + "  *  " + varResults[m] + ")  =  " + info.n[k] * varResults[m]);
                Console.WriteLine(info.t[k] + ".year ->>  " + ((info.c[k] * varResults[k]) + (info.n[k] * varResults[m])) + "\n\n");

                totalCost += (info.c[k] * varResults[k]) + (info.n[k] * varResults[m]);
                k++; m++;
            }
            Console.WriteLine("\n\nFinal Total Cost = " + totalCost);


            Console.ReadKey();
        }
예제 #5
0
        private OptimizationModel Solve(OptimizationModel optimizationModel)
        {
            var           furnances = optimizationModel.Furnaces;
            SolverContext context   = SolverContext.GetContext();
            Model         model     = context.CreateModel();


            var furnancesSet = new Set(Domain.Any, "Furnances");

            var parametersList       = new List <Parameter>();
            var gasExpenseBasePeriod = new Parameter(Domain.Real, "GasExpenseBasePeriod", furnancesSet);

            gasExpenseBasePeriod.SetBinding(furnances, "GasExpenseBasePeriod", "FurnanceId");

            var minGasExpense = new Parameter(Domain.Real, "MinGasExpense", furnancesSet);

            minGasExpense.SetBinding(furnances, "MinGasExpense", "FurnanceId");

            var maxGasExpense = new Parameter(Domain.Real, "MaxGasExpense", furnancesSet);

            maxGasExpense.SetBinding(furnances, "MaxGasExpense", "FurnanceId");

            var coxExpenseBasePeriod = new Parameter(Domain.Real, "CoxExpenseBasePeriod", furnancesSet);

            coxExpenseBasePeriod.SetBinding(furnances, "CoxExpenseBasePeriod", "FurnanceId");

            var coxReplacementEquivalent = new Parameter(Domain.Real, "CoxReplacementEquivalent", furnancesSet);

            coxReplacementEquivalent.SetBinding(furnances, "CoxReplacementEquivalent", "FurnanceId");

            var ironPerformance = new Parameter(Domain.Real, "IronPerformance", furnancesSet);

            ironPerformance.SetBinding(furnances, "IronPerformance", "FurnanceId");

            var theoreticTemperatureBasePeriod = new Parameter(Domain.Real, "TheoreticTemperatureBasePeriod", furnancesSet);

            theoreticTemperatureBasePeriod.SetBinding(furnances, "TheoreticTemperatureBasePeriod", "FurnanceId");

            var minTemperature = new Parameter(Domain.Real, "MinTemperature", furnancesSet);

            minTemperature.SetBinding(furnances, "MinTemperature", "FurnanceId");

            var maxTemperature = new Parameter(Domain.Real, "MaxTemperature", furnancesSet);

            maxTemperature.SetBinding(furnances, "MaxTemperature", "FurnanceId");

            var deltaIronPerformanceGasChanged = new Parameter(Domain.Real, "DeltaIronPerformanceGasChanged", furnancesSet);

            deltaIronPerformanceGasChanged.SetBinding(furnances, "DeltaIronPerformanceGasChanged", "FurnanceId");

            var deltaIronPerformanceCoxChanged = new Parameter(Domain.Real, "DeltaIronPerformanceCoxChanged", furnancesSet);

            deltaIronPerformanceCoxChanged.SetBinding(furnances, "DeltaIronPerformanceCoxChanged", "FurnanceId");

            var deltaTemperatureGasChanged = new Parameter(Domain.Real, "DeltaTemperatureGasChanged", furnancesSet);

            deltaTemperatureGasChanged.SetBinding(furnances, "DeltaTemperatureGasChanged", "FurnanceId");

            parametersList.Add(gasExpenseBasePeriod);
            parametersList.Add(minGasExpense);
            parametersList.Add(maxGasExpense);
            parametersList.Add(coxExpenseBasePeriod);
            parametersList.Add(coxReplacementEquivalent);
            parametersList.Add(ironPerformance);
            parametersList.Add(minTemperature);
            parametersList.Add(maxTemperature);
            parametersList.Add(theoreticTemperatureBasePeriod);
            parametersList.Add(deltaIronPerformanceGasChanged);
            parametersList.Add(deltaIronPerformanceCoxChanged);
            parametersList.Add(deltaTemperatureGasChanged);

            model.AddParameters(parametersList.ToArray());


            Decision decision = new Decision(Domain.RealNonnegative, "decision", furnancesSet);

            model.AddDecision(decision);

            /*(koksekv*стоимость кокса - стоимость природного газа)*расход ту readjust*/
            model.AddGoal("CokeSaving", GoalKind.Maximize,
                          Model.Sum(Model.ForEach(furnancesSet, FurnanceId => (coxReplacementEquivalent[FurnanceId] * optimizationModel.CoxCost - optimizationModel.GasCost) * decision[FurnanceId])));

            model.AddConstraint("RequiredIronPerformance",
                                Model.Sum(Model.ForEach(furnancesSet, CalculatePerformanceConstraint)) >= optimizationModel.RequiredIronPerformance);

            // (расходПГ - расходБазовомПериоде)*ИзмПрЧугИзмПГ - ЭквЗамКокс*(расходПГ - расходБазовомПериоде)*ИзмПрЧугИзимКокса + ПрПоЧугБазовомПер
            Term CalculatePerformanceConstraint(Term FurnanceId)
            {
                var val = (decision[FurnanceId] - gasExpenseBasePeriod[FurnanceId]) * deltaIronPerformanceGasChanged[FurnanceId] -
                          coxReplacementEquivalent[FurnanceId] * (decision[FurnanceId] - gasExpenseBasePeriod[FurnanceId]) *
                          deltaIronPerformanceCoxChanged[FurnanceId] + ironPerformance[FurnanceId];

                return(val);
            }

            model.AddConstraints("GasExpenseInterval", Model.ForEach(furnancesSet, FurnanceId => (minGasExpense[FurnanceId] <= decision[FurnanceId] <= maxGasExpense[FurnanceId])));

            Term CalculateTemperatureConstraint(Term FurnanceId)
            {
                return(minTemperature[FurnanceId] <= ((decision[FurnanceId] - gasExpenseBasePeriod[FurnanceId]) * deltaTemperatureGasChanged[FurnanceId] + theoreticTemperatureBasePeriod[FurnanceId]) <= maxTemperature[FurnanceId]);
            }

            model.AddConstraints("TemperatureInterval", Model.ForEach(furnancesSet, CalculateTemperatureConstraint));

            Term CalculateCoxSupplyConstraint(Term FurnanceId)
            {
                return(coxExpenseBasePeriod[FurnanceId] + 0.001 * (gasExpenseBasePeriod[FurnanceId] - decision[FurnanceId]) + coxReplacementEquivalent[FurnanceId]);
            }

            model.AddConstraint("CoxSupply", Model.Sum(Model.ForEach(furnancesSet, CalculateCoxSupplyConstraint)) <= optimizationModel.CoxSupply);

            model.AddConstraint("GasSupply", Model.Sum(Model.ForEach(furnancesSet, FurnanceId => decision[FurnanceId])) <= optimizationModel.GasSupply);



            SimplexDirective simplex = new SimplexDirective();
            Solution         solved  = context.Solve(simplex);
            var report = solved.GetReport();

            optimizationModel.OptimizedFunctionResult = solved.Goals.First().ToDouble();
            var reportToString = report.ToString();

            ViewBag.ReportToString = reportToString;

            var results = report.ToString().Split(new[] { "Decisions:" }, StringSplitOptions.None)[1].Split(':')
                          .Select(line => line.Remove(line.IndexOf("\r", StringComparison.Ordinal)))
                          .Where(line => !string.IsNullOrEmpty(line)).Select(Convert.ToDouble).ToList();

            for (var index = 0; index < furnances.Count; index++)
            {
                var furnace = furnances[index];
                furnace.GasExpenseToReadjust = results[index];
            }

            return(optimizationModel);
        }
예제 #6
0
        private void Solv_Click(object sender, EventArgs e)
        {
            //Coded by : Mohammed Al Sayed
            //Zagzig university ,Group B section 13
            if (Objtxt.Text == "")
            {
                MessageBox.Show("Please Enter The Object Function", "Error",
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return;
            }
            try
            {
                Objtxt.Text = Objtxt.Text.ToLower().TrimEnd(Environment.NewLine.ToCharArray());//triming newline at the end
                string objectfunction = Objtxt.Text;

                //begin Setting object function

                Model model = context.CreateModel();//Creating Linear Programming Model

                for (int i = 0; i < objectfunction.Length; i++)
                {                                             //extracting Variables and adding decisions
                    if (char.IsNumber(objectfunction[i]) && char.IsLetter(objectfunction[i + 1]))
                    {
                        objectfunction = objectfunction.Insert(i + 1, "*");//Parsing text into an acceptable Term like 2*x+3*y  >> 2x become 2*x
                    }
                    else if (char.IsLetter(objectfunction[i]))

                    {
                        //Adding Decisions(Variables) into model
                        model.AddDecision(new Decision(Domain.RealNonnegative, objectfunction[i].ToString()));//each literal represent a variable
                    }
                }
                //end setting object function

                //begin SettingConstrains
                if (Cnstrntxt.Text == "")
                {
                    MessageBox.Show("Please Enter The Constrains", "Error",
                                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return;
                }

                Cnstrntxt.Text = Cnstrntxt.Text.ToLower().TrimEnd(Environment.NewLine.ToCharArray()); //removing newline at the end of the text
                string constrainsRaw = Cnstrntxt.Text;
                //parsing text into an acceptable MOL term ,, something like that 2*x+4*y a programatic equation
                for (int i = 0; i < constrainsRaw.Length - 1; i++)
                {
                    if (char.IsNumber(constrainsRaw[i]) && char.IsLetter(constrainsRaw[i + 1])) //2X
                    {
                        constrainsRaw = constrainsRaw.Insert(i + 1, "*");                       //2*x
                    }
                }
                //spliting constrains
                string[] constrains = constrainsRaw.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

                for (int i = 0; i <= constrains.GetUpperBound(0); i++)
                {
                    model.AddConstraint("Constrain_" + i.ToString(), constrains[i]);//each line represent a constrain
                }
                //end setting constrains

                //begin setting goal
                GoalKind goal;                //defining a goal
                if (tpcom.SelectedIndex == 1) //goal type
                {
                    goal = GoalKind.Minimize;
                }
                else
                {
                    goal = GoalKind.Maximize;
                }

                model.AddGoal("target", goal, objectfunction);
                //end setting goal

                //begin solving

                SimplexDirective simplxReactor = new SimplexDirective();            ///solver object
                if (Chksensitivity.Checked)
                {
                    simplxReactor.GetSensitivity = true;                         //sensitivity
                }
                if (ChkInfeasibility.Checked)
                {
                    simplxReactor.GetInfeasibility = true;                           //infeasibility
                }
                if (cmbAlgorithm.SelectedIndex == 1)
                {
                    simplxReactor.Algorithm = SimplexAlgorithm.Dual;                                  //Algorithm used
                }
                Solution solution = context.Solve(simplxReactor);


                Report report = solution.GetReport(); //defining a report


                if (ChkFullReport.Checked)
                {
                    txtreport.Text = report.ToString(); //presenting the report in report textbox
                }
                ResultTextbox.Text = "";                //removing old values if existed
                ResultTextbox.Text = solution.Goals.First().ToDouble().ToString();

                VarResultTextbox.Text = "";
                foreach (Decision d in model.Decisions) //adding decisions(variables) and they production size in variable textbox
                {
                    VarResultTextbox.Text += d.Name + " = " + d.ToString() + Environment.NewLine;
                }

                //Duals aka shadow prices
                if (chkdual.Checked)
                {
                    txtdual.Text = "";                                                                       //removing old values if existed
                    LinearReport lin = ((LinearReport)solution.GetReport());                                 //generating a linear programming report out of the solution report

                    foreach (Microsoft.SolverFoundation.Services.Constraint constraint in model.Constraints) //getting constrains from the model
                    {
                        foreach (var dual in lin.GetShadowPrices(constraint))                                //getting the shadow prices for each constrain
                        {
                            txtdual.Text += dual.Key + " = " + dual.Value.ToDouble().ToString() + Environment.NewLine;
                        }
                    }
                }
                //end shadowprices

                //begin Sensitivity Analysis
                if (Chksensitivity.Checked)
                {
                    txtbound.Text = "";                                                                      //removing old values if existed
                    LinearReport lin = ((LinearReport)solution.GetReport());                                 //generating a linear programming report out of the solution report

                    foreach (Microsoft.SolverFoundation.Services.Constraint constraint in model.Constraints) //getting constrains from the model
                    {
                        foreach (var bound in lin.GetConstraintBoundsSensitivity(constraint))                //getting the boundaries prices for each constrain
                        {
                            //parsing the boundaries into intervals
                            //opening the interval if infinity existed
                            txtbound.Text += bound.Key + " = " + bound.Value.Current.ToDouble().ToString() + Environment.NewLine +
                                             (Double.IsInfinity(bound.Value.Lower.ToDouble()) ? "]" : "[") + bound.Value.Lower.ToDouble().ToString() + " , " + bound.Value.Upper.ToDouble().ToString() + (Double.IsInfinity(bound.Value.Upper.ToDouble()) ? "[" : "]")
                                             + Environment.NewLine + Environment.NewLine
                            ;
                        }
                    }
                }
                context.ClearModel();//killing the model object so we can create a new one

                //end solving

                //begin handling errors
            }

            catch (Exception ex)
            {
                context.ClearModel();
                txtreport.Text = "An Error have occured  If you're sure about you entries  "
                                 + "Please Send this report to the programmer" + Environment.NewLine + Environment.NewLine;
                txtreport.Text += Objtxt.Text + Environment.NewLine + Environment.NewLine;
                txtreport.Text += Cnstrntxt.Text + Environment.NewLine + Environment.NewLine;


                txtreport.Text     += ex.Message;
                txtreport.ForeColor = Color.Red;
                MessageBox.Show("Error,Please Check your entries" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            tabControl1.SelectedIndex = 1;
            //end handling errors
        }
예제 #7
0
        public static TradeUpContract findBestContract(List<Skin> higherTier, List<Skin> lowerTier)
        {
            SolverContext context = SolverContext.GetContext();
            Model model = context.CreateModel();
            var targets = getDecisions(higherTier, 1);
            foreach(var decision in targets)
            {
                model.AddDecision(decision.Item1);
            }

            var decisions = getDecisions(lowerTier, 10);
            foreach (var decision in decisions)
            {
                model.AddDecision(decision.Item1);
            }

            List<string> basicConstraints = new List<string>();
            foreach (var target in higherTier)
            {
                basicConstraints.Add(getBasicConstraints(target, 1));
            }

            basicConstraints.Add(getBasicConstraints(lowerTier, 10));

            int i = 0;
            foreach(var constraint in basicConstraints)
            {
                model.AddConstraint("basicConstraint" + i, constraint);
                i++;
            }

            List<string> complexConstraintsBase = getComplexConstraintsBase(lowerTier);

            List<string> complexConstraints = new List<string>();
            foreach(var target in targets)
            {
                var constraintTemplate = "{0} - 1 + (({1}) / 10) * {2} + {3} <= {4}";
                complexConstraints.Add(
                    string.Format(
                        constraintTemplate,
                        getVariableName(target.Item2, target.Item3),
                        string.Join(" + ",complexConstraintsBase),
                        target.Item2.getFloatValueRange().ToString(CultureInfo.InvariantCulture),
                        target.Item2.minFloatValue.ToString(CultureInfo.InvariantCulture),
                        EnumUtil.getQualityBorder(target.Item3).ToString(CultureInfo.InvariantCulture)));
            }

            i = 0;
            foreach(var constraint in complexConstraints)
            {
                model.AddConstraint("ComplexConstraint"+i, constraint);
                i++;
            }

            string goal = generateGoal(targets, decisions);

            model.AddGoal("mainGoal", GoalKind.Maximize, goal);

            SimplexDirective directive = new SimplexDirective();
            directive.Arithmetic = Arithmetic.Exact;
            Solution solution = context.Solve(directive);
            Report report = solution.GetReport();
            //Console.WriteLine("x1: {0}, x: {1}", x1, x2, x3);
            //Console.WriteLine("Gain: {0}", goal);

            Console.Write("{0}", report);
            context.ClearModel();

            var contract = new TradeUpContract();

            foreach(var decision in decisions)
            {
                if(decision.Item1.ToDouble() > 0)
                {
                    contract.tradeUpList.Add(new Tuple<Skin, Quality, int>(decision.Item2, decision.Item3, (int)Math.Round(decision.Item1.ToDouble())));
                }
            }

            foreach (var target in targets)
            {
                if (target.Item1.ToDouble() > 0)
                {
                    contract.resultsList.Add(new Tuple<Skin, Quality>(target.Item2, target.Item3));
                }
            }

            contract.potentialGain = model.Goals.First().ToDouble() / contract.resultsList.Count;

            return contract;
        }
예제 #8
0
        static void Sample1()
        {
            SolverContext context = SolverContext.GetContext();
            Model model = context.CreateModel();

            Decision x1 = new Decision(Domain.IntegerRange(0, 10), "x1");
            Decision x2 = new Decision(Domain.IntegerRange(0, 10), "x2");
            Decision x3 = new Decision(Domain.IntegerRange(0, 10), "x3");

            Decision t1fn = new Decision(Domain.IntegerRange(0, 1), "t1fn");
            Decision t1mw = new Decision(Domain.IntegerRange(0, 1), "t1mw");
            Decision t1ft = new Decision(Domain.IntegerRange(0, 1), "t1ft");

            Decision t2fn = new Decision(Domain.IntegerRange(0, 1), "t2fn");
            Decision t2mw = new Decision(Domain.IntegerRange(0, 1), "t2mw");
            Decision t2ft = new Decision(Domain.IntegerRange(0, 1), "t2ft");

            Rational M = 100;

            //model.AddDecisions(x1, x2);
            model.AddDecisions(x1, x2, x3, t1fn, t1mw, t1ft, t2fn, t2mw, t2ft);

            model.AddConstraint("Row0", x1 + x2 + x3 == 10);
            model.AddConstraint("Quality1", t1fn + t1mw + t1ft == 1);
            model.AddConstraint("Quality2", t2fn + t2mw + t2ft == 1);

            //string fnTerm = ""
            //model.AddConstraint("Row1", (x1 * 0.035 + x2 * 0.11) / 10 <= 0.07);

            //target 1
            model.AddConstraint("Target1FN", " t1fn - 1 + ((x1 * 0.035 + x2 * 0.11 + x3 * 0.25) / 10) <= 0.07");
            model.AddConstraint("Target1MW", " t1mw - 1 + ((x1 * 0.035 + x2 * 0.11 + x3 * 0.25) / 10) <= 0.15");
            model.AddConstraint("Target1FT", " t1ft - 1 + ((x1 * 0.035 + x2 * 0.11 + x3 * 0.25) / 10) <= 0.35");

            //target 2
            model.AddConstraint("Target2FN", " t2fn - 1 + ((x1 * 0.035 + x2 * 0.11 + x3 * 0.25) / 10) * 0.72 + 0.06 <= 0.07");
            model.AddConstraint("Target2MW", " t2mw - 1 + ((x1 * 0.035 + x2 * 0.11 + x3 * 0.25) / 10) * 0.72 + 0.06 <= 0.15");
            model.AddConstraint("Target2FT", " t2ft - 1 + ((x1 * 0.035 + x2 * 0.11 + x3 * 0.25) / 10) * 0.72 + 0.06 <= 0.35");

            //model.AddConstraint("Row2", mw * (x1 * 0.035 + x2 * 0.11) / 10 <= 0.15);

            //model.AddConstraint("Row2", x2 + z * 100 <= 100);

            Goal goal = model.AddGoal("Goal0", GoalKind.Maximize, (t1fn * 120 + t1mw * 61 + t1ft * 34 + t2fn * 76 + t2mw * 61 + t2ft * 34) - (x1 * 9 + x2 * 8 + x3 * 5) * 2);

            //Goal goal = model.AddGoal("Goal0", GoalKind.Maximize,
            //    "Max[x1-0.07,0] * 4 - x1");

            SimplexDirective directive = new SimplexDirective();
            directive.Arithmetic = Arithmetic.Exact;
            Solution solution = context.Solve(directive);
            Report report = solution.GetReport();
            Console.WriteLine("x1: {0}, x: {1}", x1, x2, x3);
            Console.WriteLine("Gain: {0}", goal);

            Console.Write("{0}", report);
            context.ClearModel();
        }
        public Solution alternative_solve(out Dictionary <Models.Shift, Decision> shiftsN, out Dictionary <Models.Shift, Decision> shiftsO)
        {
            SolverContext SC    = SolverContext.GetContext();
            Model         model = SC.CreateModel();

            var maxRq = HalfHourRequirements.Max(x => x.RequiredForce);

            shiftsN = shiftsO = null;

            //split shifts into two Dictionaries (each dict holds each Shift as key and the Decision variable as Value)
            var normal_shifts = new Dictionary <Models.Shift, Decision>(); //for normal shifts
            int i             = 0;

            Shifts.ForEach(x => {
                Decision des = new Decision(Domain.IntegerRange(0, maxRq), string.Format("{0}_{1}", x.Name, i));
                normal_shifts.Add(x, des);
                model.AddDecision(des);
                i++;
            });

            var overtime_shifts = new Dictionary <Models.Shift, Decision>(); //for overtime shifts

            i = 0;
            OvertimeShifts.ForEach(x => {
                Decision des = new Decision(Domain.IntegerRange(0, maxRq), string.Format("{0}_{1}", x.Name, i));
                overtime_shifts.Add(x, des);
                model.AddDecision(des);
                i++;
            });

            List <Decision> excess = new List <Decision>(); //used to calculate sum of excess values

            HalfHourRequirements.ForEach(hh =>
            {
                var ShiftsActive = new List <Decision>();
                foreach (var entry in normal_shifts)
                {
                    if (entry.Key.IncludesHalfHour(hh.Start))
                    {
                        ShiftsActive.Add(entry.Value);
                        excess.Add(entry.Value);
                    }
                }
                foreach (var entry in overtime_shifts)
                {
                    if (entry.Key.IncludesHalfHour(hh.Start))
                    {
                        ShiftsActive.Add(entry.Value);
                        excess.Add(entry.Value);
                    }
                }

                //add constraint for sum of force of active shifts on that halfhour
                //if we need agents but no shifts exists for a halfhour, do not add a constraint
                if (ShiftsActive.Count > 0)
                {
                    var sum_constr = new SumTermBuilder(ShiftsActive.Count);
                    ShiftsActive.ForEach(s => sum_constr.Add(s));

                    var constr = sum_constr.ToTerm() >= hh.RequiredForce;
                    model.AddConstraint(string.Format("_{0:hh}{0:mm}", hh.Start), constr);

                    //constr = sum_constr.ToTerm() <= hh.RequiredForce * 2.0;
                    //model.AddConstraint(string.Format("limitconst_for_{0:hh}{0:mm}", hh.Start), constr);
                }
            });

            //Constrain maximum number of agents working 8hour shifts
            var max_agents_constraint = new SumTermBuilder(Shifts.Count);

            foreach (var entry in normal_shifts)
            {
                max_agents_constraint.Add(entry.Value);
            }
            var ma_constr = max_agents_constraint.ToTerm() <= MaxAgents;

            model.AddConstraint("Max_agents_constraint", ma_constr);

            //1st goal: Minimize overtime shifts (if work manageable by normal shifts, no overtime shifts will be used)
            var overtime_obj = new SumTermBuilder(OvertimeShifts.Count);

            foreach (var entry in overtime_shifts)
            {
                overtime_obj.Add(entry.Value);
            }
            model.AddGoal("Minimize_overtime", GoalKind.Minimize, overtime_obj.ToTerm());

            //2st goal: Minimize normal shifts
            var normal_obj = new SumTermBuilder(Shifts.Count);

            foreach (var entry in normal_shifts)
            {
                normal_obj.Add(entry.Value);
            }
            model.AddGoal("Minimize_normal", GoalKind.Minimize, normal_obj.ToTerm());

            //3rd goal: Try to minimize excess
            var sumReqs = HalfHourRequirements.Sum(x => x.RequiredForce);

            model.AddGoal("Minimize_excess", GoalKind.Minimize, Model.Sum(excess.ToArray()) - sumReqs);

            SimplexDirective simplex  = new SimplexDirective();
            Solution         solution = SC.Solve(simplex);

            shiftsN = normal_shifts;
            shiftsO = overtime_shifts;

            return(solution);
        }