Пример #1
0
        /// <summary>
        /// Processes all inequalities based on the given solution
        /// </summary>
        /// <param name="sol"></param>
        /// <param name="precision"></param>
        /// <returns></returns>
        public bool SetSolution(LPSolution sol, int precision)
        {
            if (sol.NumberOfVariables != vars.Number)
            {
                throw new Exception("Inconsistent number of variables");
            }

            if (sol.NumberOfConstraints != originalIneqs.Count)
            {
                throw new Exception("Inconsistent number of constraints");
            }

            ineqs = new List <Inequality>();
//            ineqMarginals = new List<LpNumber>();

            // Constraints
            for (int i = 0; i < sol.NumberOfConstraints; i++)
            {
                LpNumber m = sol.ConstraintMarginals[i];
                if (m.IsZero(precision))
                {
                    continue;
                }

                Inequality ineq = originalIneqs[i];

                if (m.value < 0)
                {
                    ineq = -ineq;
                    m    = -m;
                }

                ineq          = ineq.Round(precision);
                ineq.Marginal = m;
                ineqs.Add(ineq);
//                ineqMarginals.Add(m);
            }

            // Variables
            List <Inequality> tmpIneqs = new List <Inequality>();

            for (int i = 0; i < sol.NumberOfVariables; i++)
            {
                Variable var = vars[i];
                LpNumber m   = sol.VariableMarginals[i];
                if (m.IsZero(precision))
                {
                    continue;
                }

                Inequality ineq;

                if (m.value < 0)
                {
                    var.LMarginal = -m;
                    ineq          = -Inequality.FromLowerBound(var);
                    ineq          = ineq.Round(precision) * (-m.value);
                }
                else
                {
                    var.UMarginal = m;
                    ineq          = Inequality.FromUpperBound(var);
                    ineq          = ineq.Round(precision) * m.value;
                }

                tmpIneqs.Add(ineq);
            }


            // Compute additional inequality
//            Inequality sum1 = ineqs[0] * ineqs[0].Marginal.value; //ineqMarginals[0].value;
            Inequality sum1 = Inequality.Zero();

            for (int i = 0; i < ineqs.Count; i++)
            {
                sum1 += ineqs[i] * ineqs[i].Marginal.value; //ineqMarginals[i].value;
            }

            Inequality sum2 = sum1;

            for (int i = 0; i < tmpIneqs.Count; i++)
            {
                sum2 += tmpIneqs[i];
            }

            // df
            LinearFunction df = objective - sum2.lhs;

            // Compute corrections for marginals
            foreach (var term in df.Terms)
            {
                LpNumber c = term.c;
                if (c.value < 0)
                {
                    vars[term.varName].LMarginal -= c;
                }
                else
                {
                    vars[term.varName].UMarginal += c;
                }
            }

            // Verification
            LpNumber sum = sum1.rhs;

            for (int i = 0; i < vars.Number; i++)
            {
                Variable var = vars[i];
                if (!var.LMarginal.IsZero(precision))
                {
                    sum -= var.LMarginal * LpNumber.RoundDown(var.LBound, precision);
                }

                if (!var.UMarginal.IsZero(precision))
                {
                    sum += var.UMarginal * LpNumber.RoundUp(var.UBound, precision);
                }
            }

            LpNumber eps = sol.UpperBound - sum;

            Console.WriteLine("eps = {0}", eps);

            if (eps.value < 0)
            {
                return(false);
            }

            // Set the upper bound
            upperBound = sol.UpperBound;

            // Generate inequalities for variables
            Console.Write("Generating inequalities for variables...");
            varIneqs = new List <Inequality>();
//            varIneqMarginals = new List<LpNumber>();

            for (int i = 0; i < vars.Number; i++)
            {
                Variable   var = vars[i];
                Inequality ineq;

                if (!var.LMarginal.IsZero(precision))
                {
                    ineq          = -Inequality.FromLowerBound(var);
                    ineq          = ineq.Round(precision);
                    ineq.Marginal = var.LMarginal;
                    varIneqs.Add(ineq);
//                    varIneqMarginals.Add(var.LMarginal);
                }

                if (!var.UMarginal.IsZero(precision))
                {
                    ineq          = Inequality.FromUpperBound(var);
                    ineq          = ineq.Round(precision);
                    ineq.Marginal = var.UMarginal;
                    varIneqs.Add(ineq);
//                    varIneqMarginals.Add(var.UMarginal);
                }
            }
            Console.WriteLine("done");

            return(true);
        }
Пример #2
0
 /// <summary>
 /// Rounds down the term (it is assumed that var >= 0)
 /// </summary>
 /// <returns></returns>
 public Term RoundDown(int precision)
 {
     return(new Term(c.RoundDown(precision), varName));
 }