示例#1
0
        /// <summary>
        /// Generates a test file
        /// </summary>
        static void GenerateExamples()
        {
            FileStream   fs = new FileStream("examples.hl", FileMode.Create);
            StreamWriter w  = new StreamWriter(fs);

            Random rnd = new Random(2);

            // Dependencies
            w.WriteLine("needs \"test_explicit.hl\"");
            w.WriteLine("let test = [");

            for (int k = 0; k < 300; k++)
            {
                List <decimal> cs   = new List <decimal>();
                List <string>  vars = new List <string>();

                int i = rnd.Next(100);
                while (i >= 0)
                {
                    vars.Add('x'.ToString() + "_" + String.Format("{0:000}", i));
                    cs.Add(rnd.Next(1000000000));

                    i -= rnd.Next(10) + 1;
                }

                LinearFunction f = new LinearFunction(cs, vars);
                w.Write(f.ToHOLExplicit(5, null));
                //                w.Write("`" + f.ToHOLString(5) + "`");
                w.WriteLine(";");
            }

            w.WriteLine("];;");
            w.Flush();
            fs.Close();
        }
示例#2
0
 /// <summary>
 /// Private constructor
 /// </summary>
 private Inequality(Label id, IneqType type, LinearFunction lhs, LpNumber rhs, bool negFlag)
 {
     this.Id      = id;
     this.type    = type;
     this.lhs     = lhs;
     this.rhs     = rhs;
     this.NegFlag = negFlag;
 }
示例#3
0
        /// <summary>
        /// Returns the equality 0 = 0
        /// </summary>
        public static Inequality Zero()
        {
            Label          id   = new Label("ZERO", "");
            LinearFunction lhs  = new LinearFunction(new List <decimal>(), new List <string>());
            LpNumber       rhs  = new LpNumber(0);
            Inequality     ineq = new Inequality(id, IneqType.Eq, lhs, rhs, false);

            return(ineq);
        }
示例#4
0
        public static LinearFunction operator *(decimal n, LinearFunction f)
        {
            LinearFunction result = new LinearFunction();

            foreach (var term in f.terms)
            {
                result.terms.Add(term * n);
            }

            return(result);
        }
示例#5
0
        /// <summary>
        /// Rounds down the linear function
        /// </summary>
        /// <param name="precision"></param>
        /// <returns></returns>
        public LinearFunction RoundDown(int precision)
        {
            LinearFunction f = new LinearFunction();

            foreach (var term in terms)
            {
                f.terms.Add(term.RoundDown(precision));
            }

            return(f);
        }
示例#6
0
        /// <summary>
        /// Addition
        /// </summary>
        /// <param name="f1"></param>
        /// <param name="f2"></param>
        /// <returns></returns>
        public static LinearFunction operator +(LinearFunction f1, LinearFunction f2)
        {
            f1.terms.Sort();
            f2.terms.Sort();

            LinearFunction f = new LinearFunction();

            int n1 = f1.terms.Count;
            int n2 = f2.terms.Count;
            int index1 = 0, index2 = 0;

            while (index1 < n1 && index2 < n2)
            {
                Term t1 = f1.terms[index1];
                Term t2 = f2.terms[index2];

                int r = t1.CompareTo(t2);
                if (r == 0)
                {
                    LpNumber n = t1.c + t2.c;
                    if (n.value != 0)
                    {
                        f.terms.Add(new Term(n, t1.varName));
                    }
                    index1++;
                    index2++;
                }
                else if (r > 0)
                {
                    f.terms.Add(t2);
                    index2++;
                }
                else
                {
                    f.terms.Add(t1);
                    index1++;
                }
            }

            for (int i = index1; i < n1; i++)
            {
                f.terms.Add(f1.terms[i]);
            }

            for (int i = index2; i < n2; i++)
            {
                f.terms.Add(f2.terms[i]);
            }

            return(f);
        }
示例#7
0
        /// <summary>
        /// Parses an inequality
        /// </summary>
        /// <param name="scanner"></param>
        /// <returns></returns>
        public static Inequality ParseInequality(Scanner scanner)
        {
            Token t;
            // Identifier
            Label id = Label.ParseLabel(scanner);

            // :
            t = scanner.nextToken();
            if (t.Type != TokenType.Colon)
            {
                throw new Exception(": expected: " + t);
            }

            // lhs
            LinearFunction lhs = LinearFunction.ParseFunction(scanner);

            // type
            t = scanner.nextToken();
            IneqType type;

            switch (t.Type)
            {
            case TokenType.Le:
                type = IneqType.Le;
                break;

            case TokenType.Ge:
                type = IneqType.Ge;
                break;

            case TokenType.Eq:
                type = IneqType.Eq;
                break;

            default:
                throw new Exception("<=, =>, or = expected: " + t);
            }

            // rhs
            t = scanner.nextToken();

            if (t.Type != TokenType.Integer && t.Type != TokenType.Double)
            {
                throw new Exception("A number is expected: " + t);
            }

            LpNumber rhs = new LpNumber(decimal.Parse(t.StringValue));

            return(new Inequality(id, type, lhs, rhs, false));
        }
示例#8
0
        /// <summary>
        /// Parses a linear function
        /// </summary>
        /// <param name="scanner"></param>
        /// <returns></returns>
        public static LinearFunction ParseFunction(Scanner scanner)
        {
            LinearFunction f = new LinearFunction();
            Token          t;

            while (true)
            {
                t = scanner.peekToken();
                if (t.Type != TokenType.Plus && t.Type != TokenType.Minus)
                {
                    break;
                }

                Term term = Term.ParseTerm(scanner);
                f.terms.Add(term);
            }

            return(f);
        }
示例#9
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);
        }
示例#10
0
        /// <summary>
        /// Parses a LP
        /// </summary>
        /// <param name="scanner"></param>
        /// <returns></returns>
        public static LP ParseLP(Scanner scanner)
        {
            LP lp = new LP();

            // Maximize
            Token t = scanner.nextToken();

            if (t.Type != TokenType.Identifier && t.StringValue != "Maximize")
            {
                throw new Exception("Maximize expected: " + t);
            }

            // objective
            t = scanner.nextToken();
            if (t.Type != TokenType.Identifier)
            {
                throw new Exception("Identifier expected: " + t);
            }

            // :
            t = scanner.nextToken();
            if (t.Type != TokenType.Colon)
            {
                throw new Exception(": expected: " + t);
            }

            // objective function
            lp.objective = LinearFunction.ParseFunction(scanner);

            // Subject To
            t = scanner.nextToken();
            if (t.Type != TokenType.Identifier && t.StringValue != "Subject")
            {
                throw new Exception("Subject To expected: " + t);
            }

            t = scanner.nextToken();
            if (t.Type != TokenType.Identifier && t.StringValue != "To")
            {
                throw new Exception("Subject To expected: " + t);
            }

            // Constraints
            while (true)
            {
                t = scanner.peekToken();
                if (t.Type == TokenType.Identifier && t.StringValue == "Bounds")
                {
                    break;
                }

                if (t.Type == TokenType.EOF)
                {
                    break;
                }

                Inequality ineq = Inequality.ParseInequality(scanner);
                lp.originalIneqs.Add(ineq);
            }

            // Bounds
            t = scanner.nextToken();
            if (t.Type != TokenType.Identifier && t.StringValue != "Bounds")
            {
                throw new Exception("Bounds expected: " + t);
            }

            // Bounds
            while (true)
            {
                t = scanner.peekToken();
                if (t.Type == TokenType.Identifier && t.StringValue == "End")
                {
                    break;
                }

                if (t.Type == TokenType.EOF)
                {
                    break;
                }

                ParseBound(scanner, lp);
            }

            return(lp);
        }