public LPSolver( int input_dimension, int total_constraint_count, double[] origin, // Just the image, not the epsilon double originbound // Bounding rectangle ) { solver_ = new GurobiSolver(); input_dimension_ = input_dimension; int varCount = LPSTerm.TotalVarCount(); Console.WriteLine("Number of variables: " + varCount); vars_ = new int[varCount]; for (int i = 0; i < varCount; i++) { int vid; solver_.AddVariable("x" + i, out vid); solver_.SetIntegrality(vid, RobustnessOptions.Integrality); if (i < origin.Length) { double lb = Math.Max(Utils.RobustnessOptions.MinValue, origin[i] - originbound); double ub = Math.Min(Utils.RobustnessOptions.MaxValue, origin[i] + originbound); if (lb <= ub) { // Tighter bounds for the image variables! solver_.SetBounds(vid, lb, ub); } else { // Bound validation failed, very weird. Oh well just don't use the bounds. // The programmer got the Min/Max values wrong. solver_.SetBounds(vid, origin[i] - originbound, origin[i] + originbound); } } else { solver_.SetBounds(vid, Utils.RobustnessOptions.MinValue, Utils.RobustnessOptions.MaxValue); } vars_[i] = vid; } }
public void AddConstraint(LPSConstraint ct) { int ctid = ct_cnt; solver_.AddRow("constraint" + ct_cnt, out ctid); Vector <double> coefficients = ct.Term.GetCoefficients(); int totalvars = LPSTerm.TotalVarCount(); for (int j = 0; j < totalvars; j++) { // Due to the way MSF works, if we are adding a 0 coefficient // this amounts to actually removing it. However, the coefficient // is not there to start with, hence let's not add it, at all! if (coefficients[j] != 0) { solver_.SetCoefficient(ctid, vars_[j], coefficients[j]); } } switch (ct.Inequality) { case InequalityType.LT: solver_.SetUpperBound(ctid, -ct.Term.Intercept); // - RobustnessOptions.StrictInequalityLambda * Math.Abs(ct.Term.Intercept)); break; case InequalityType.LE: solver_.SetUpperBound(ctid, -ct.Term.Intercept); break; case InequalityType.GT: solver_.SetLowerBound(ctid, -ct.Term.Intercept); // + RobustnessOptions.StrictInequalityLambda * Math.Abs(ct.Term.Intercept)); break; case InequalityType.GE: solver_.SetLowerBound(ctid, -ct.Term.Intercept); break; case InequalityType.EQ: // solver_.SetValue(ctid, -ct.Term.Intercept); WRONG solver_.SetBounds(ctid, -ct.Term.Intercept, -ct.Term.Intercept); break; default: break; } ct_cnt++; }