/// <summary> /// Creates files for producing a formal proof for the given linear program /// </summary> static bool ProcessLP(string fname, LpNumber upperBound, int precision, ListHyp hypermap, bool infeasible, bool holTerms) { if (precision > 7) { throw new Exception("Cannot solve the problem: " + fname); } LP lp; LPSolution sol; // Load an LP FileStream fs = new FileStream(fname + ".lp", FileMode.Open); using (fs) { StreamReader r = new StreamReader(fs); Scanner scanner = new Scanner(r, fname + ".lp"); lp = LP.ParseLP(scanner); } // Load solutions fs = new FileStream(fname + ".txt", FileMode.Open); using (fs) { sol = LPSolution.LoadSolution(new StreamReader(fs), precision, upperBound, infeasible); } if (!infeasible && sol.Optimal.value > upperBound.value) { throw new Exception("Optimal value is greater than " + upperBound.value + ": " + fname); } if (!lp.SetSolution(sol, precision, infeasible)) { return(false); } // Create a test file containing all inequalities explicitly // FileStream test = new FileStream(fname + "_test.hl", FileMode.Create); // lp.ConvertToHOL(new StreamWriter(test), precision); // test.Close(); // Create a certificate file FileStream main = new FileStream(fname + "_out.hl", FileMode.Create); FileStream main_bin = new FileStream(fname + "_out.bin", FileMode.Create); lp.PrintCertificate(new StreamWriter(main), new BinaryWriter(main_bin), precision, hypermap, log, infeasible, holTerms); main_bin.Close(); main.Close(); // Debug file with text inequalities // FileStream text = new FileStream(fname + "_text.hl", FileMode.Create); // lp.PrintAllText(new StreamWriter(text), precision, hypermap); // text.Close(); return(true); }
/// <summary> /// Creates files for a formal proof for a general linear program /// </summary> static bool processLPGeneral(string fname, int precision, LpNumber upperBound) { if (precision > 10) { throw new Exception("Cannot solve the problem (precision > 10): " + fname); } LP lp; LPSolution sol; // Load an LP FileStream fs = new FileStream(fname + ".lp", FileMode.Open); using (fs) { StreamReader r = new StreamReader(fs); Scanner scanner = new Scanner(r, fname + ".lp"); lp = LP.ParseLP(scanner); } // Load solutions fs = new FileStream(fname + ".txt", FileMode.Open); using (fs) { sol = LPSolution.LoadSolution(new StreamReader(fs), precision, upperBound, false); } if (!lp.SetSolution(sol, precision, false)) { return(false); } // Create a test file containing all inequalities explicitly FileStream test = new FileStream(fname + "_test.hl", FileMode.Create); lp.ConvertToHOL(new StreamWriter(test), precision); test.Close(); return(true); }
/// <summary> /// Loads solutions from a stream (a file) /// </summary> /// <param name="r"></param> /// <returns></returns> public static LPSolution LoadSolution(StreamReader r, int precision, LpNumber upperBound) { LPSolution sol = new LPSolution(); sol.UpperBound = upperBound; string str = r.ReadLine(); if (str == null) { throw new Exception("Two numbers are expected on the first line"); } string[] els = str.Split(' '); if (els.Length != 2) { throw new Exception("Two numbers are expected on the first line"); } // Subtract one since we don't count the objective function sol.NumberOfConstraints = int.Parse(els[0]) - 1; sol.NumberOfVariables = int.Parse(els[1]); // Optimal var vals = ReadThirdValue(r, 1, precision); sol.Optimal = vals[0]; // Skip one line (the objective function) ReadThirdValue(r, 1, precision); // Constraints sol.ConstraintMarginals = ReadThirdValue(r, sol.NumberOfConstraints, precision); // Bounds sol.VariableMarginals = ReadThirdValue(r, sol.NumberOfVariables, precision); return(sol); }
/// <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); }
/// <summary> /// Loads solutions from a stream (a file) /// </summary> /// <param name="r"></param> /// <returns></returns> public static LPSolution LoadSolution(StreamReader r, int precision, LpNumber upperBound, bool infeasible) { LPSolution sol = new LPSolution(); sol.UpperBound = upperBound; if (infeasible) { sol.UpperBound = new LpNumber(0); } string str = r.ReadLine(); if (str == null) throw new Exception("Two numbers are expected on the first line"); string[] els = str.Split(' '); if (els.Length != 2) throw new Exception("Two numbers are expected on the first line"); int nc = int.Parse(els[0]); int nv = int.Parse(els[1]); if (infeasible) { sol.NumberOfConstraints = nc; // Do not count slack variables sol.NumberOfVariables = nv - nc; } else { // Subtract one since we don't count the objective function for a feasible solution sol.NumberOfConstraints = nc - 1; sol.NumberOfVariables = nv; } // Optimal var vals = ReadThirdValue(r, 1, precision); sol.Optimal = vals[0]; if (!infeasible) { // Skip one line (the objective function) ReadThirdValue(r, 1, precision); } // Constraints sol.ConstraintMarginals = ReadThirdValue(r, sol.NumberOfConstraints, precision); if (infeasible) { // Skip slack variables ReadThirdValue(r, nc, precision); } // Bounds sol.VariableMarginals = ReadThirdValue(r, sol.NumberOfVariables, precision); return sol; }
/// <summary> /// Loads solutions from a stream (a file) /// </summary> /// <param name="r"></param> /// <returns></returns> public static LPSolution LoadSolution(StreamReader r, int precision, LpNumber upperBound, bool infeasible) { LPSolution sol = new LPSolution(); sol.UpperBound = upperBound; if (infeasible) { sol.UpperBound = new LpNumber(0); } string str = r.ReadLine(); if (str == null) { throw new Exception("Two numbers are expected on the first line"); } string[] els = str.Split(' '); if (els.Length != 2) { throw new Exception("Two numbers are expected on the first line"); } int nc = int.Parse(els[0]); int nv = int.Parse(els[1]); if (infeasible) { sol.NumberOfConstraints = nc; // Do not count slack variables sol.NumberOfVariables = nv - nc; } else { // Subtract one since we don't count the objective function for a feasible solution sol.NumberOfConstraints = nc - 1; sol.NumberOfVariables = nv; } // Optimal var vals = ReadThirdValue(r, 1, precision); sol.Optimal = vals[0]; if (!infeasible) { // Skip one line (the objective function) ReadThirdValue(r, 1, precision); } // Constraints sol.ConstraintMarginals = ReadThirdValue(r, sol.NumberOfConstraints, precision); if (infeasible) { // Skip slack variables ReadThirdValue(r, nc, precision); } // Bounds sol.VariableMarginals = ReadThirdValue(r, sol.NumberOfVariables, precision); return(sol); }
/// <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, bool infeasible) { if (sol.NumberOfVariables != vars.Number) throw new Exception("Inconsistent number of variables"); if (sol.NumberOfConstraints != originalIneqs.Count) throw new Exception("Inconsistent number of constraints"); if (infeasible) { ResortVariables(); } 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; if (infeasible) { df = -sum2.lhs; } else { 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; }
/// <summary> /// Loads solutions from a stream (a file) /// </summary> /// <param name="r"></param> /// <returns></returns> public static LPSolution LoadSolution(StreamReader r, int precision, LpNumber upperBound) { LPSolution sol = new LPSolution(); sol.UpperBound = upperBound; string str = r.ReadLine(); if (str == null) throw new Exception("Two numbers are expected on the first line"); string[] els = str.Split(' '); if (els.Length != 2) throw new Exception("Two numbers are expected on the first line"); // Subtract one since we don't count the objective function sol.NumberOfConstraints = int.Parse(els[0]) - 1; sol.NumberOfVariables = int.Parse(els[1]); // Optimal var vals = ReadThirdValue(r, 1, precision); sol.Optimal = vals[0]; // Skip one line (the objective function) ReadThirdValue(r, 1, precision); // Constraints sol.ConstraintMarginals = ReadThirdValue(r, sol.NumberOfConstraints, precision); // Bounds sol.VariableMarginals = ReadThirdValue(r, sol.NumberOfVariables, precision); return sol; }