public bool SolveSimple(AD.Term equation, AD.Variable[] args, double[,] limits, double[][] seeds) { rResults.Clear(); this.dim = args.Length; this.limits = limits; this.ranges = new double[dim]; for (int i = 0; i < dim; i++) { this.ranges[i] = (this.limits[i, 1] - this.limits[i, 0]); } equation = equation.AggregateConstants(); term = AD.TermUtils.Compile(equation, args); this.rpropStepWidth = new double[dim]; this.rpropStepConvergenceThreshold = new double[dim]; if (seeds != null) { for (int i = 0; i < seeds.Length; i++) { RpropResult r = RPropLoopSimple(seeds[i]); rResults.Add(r); if (r.finalUtil > 0.75) { return(true); } } } int runs = 2 * dim - (seeds == null?0:seeds.Length); for (int i = 0; i < runs; i++) { RpropResult r = RPropLoopSimple(null); rResults.Add(r); if (r.finalUtil > 0.75) { return(true); } } int adit = 0; while (!EvalResults() && adit++ < 20) { RpropResult r = RPropLoopSimple(null); rResults.Add(r); if (r.finalUtil > 0.75) { return(true); } } if (adit > 20) { Console.WriteLine("Failed to satisfy heuristic!"); } return(false); }
protected double[] InitialPointFromSeed(RpropResult res, double[] seed) { Tuple <double[], double> tup; res.initialValue = new double[dim]; res.finalValue = new double[dim]; for (int i = 0; i < dim; i++) { if (Double.IsNaN(seed[i])) { res.initialValue[i] = rand.NextDouble() * ranges[i] + limits[i, 0]; } else { res.initialValue[i] = Math.Min(Math.Max(seed[i], limits[i, 0]), limits[i, 1]); } } tup = term.Differentiate(res.initialValue); res.initialUtil = tup.Item2; res.finalUtil = tup.Item2; Buffer.BlockCopy(res.initialValue, 0, res.finalValue, 0, sizeof(double) * dim); return(tup.Item1); }
public double[] SolveTest(AD.Term equation, AD.Variable[] args, double[,] limits) { #if (GSOLVER_LOG) InitLog(); #endif rResults.Clear(); double[] res = null; this.dim = args.Length; this.limits = limits; this.ranges = new double[dim]; for (int i = 0; i < dim; i++) { this.ranges[i] = (this.limits[i, 1] - this.limits[i, 0]); } term = AD.TermUtils.Compile(equation, args); this.rpropStepWidth = new double[dim]; this.samplePoint = new double[dim]; this.Runs = 1; //this.Runs = 0; this.FEvals = 0; //int runs = 1000000; RpropResult rfirst = RPropLoop(null, false, true); if (rfirst.finalUtil > 0.75) { res = rfirst.finalValue; } else { while (true) { this.Runs++; //RpropResult r = RPropLoopSimple(null); RpropResult r = RPropLoop(null, false, false); //Console.WriteLine("Run: {0} Util: {1}",i,r.finalUtil); /*for(int k=0; k<dim; k++) { * Console.Write("{0}\t",r.finalValue[k]); * } * Console.WriteLine();*/ if (r.finalUtil > 0.75) { res = r.finalValue; break; } } } #if (GSOLVER_LOG) CloseLog(); #endif return(res); }
public double[] SolveTest(AD.Term equation, AD.Variable[] args, double[,] limits, int maxRuns, out bool found) { #if (GSOLVER_LOG) InitLog(); #endif found = false; rResults.Clear(); double[] res = null; this.dim = args.Length; this.limits = limits; this.ranges = new double[dim]; for (int i = 0; i < dim; i++) { this.ranges[i] = (this.limits[i, 1] - this.limits[i, 0]); } term = AD.TermUtils.Compile(equation, args); this.rpropStepWidth = new double[dim]; this.rpropStepConvergenceThreshold = new double[dim]; this.Runs = 0; this.FEvals = 0; while (this.Runs < maxRuns) { this.Runs++; //RpropResult r = RPropLoopSimple(null); RpropResult r = RPropLoop(null, false); //Console.WriteLine("Run: {0} Util: {1}",i,r.finalUtil); /*for(int k=0; k<dim; k++) { * Console.Write("{0}\t",r.finalValue[k]); * } * Console.WriteLine();*/ if (r.finalUtil > 0.75) { res = r.finalValue; found = true; break; } } #if (GSOLVER_LOG) CloseLog(); #endif return(res); }
public bool ProbeForSolution(List <CNSAT.Var> decisions, out double[] solution) { probeCount++; /*Console.Write("SAT proposed({0}): ", decisions.Count); * foreach(CNSAT.Var v in decisions) { * v.Print(); * Console.Write(" "); * } * Console.WriteLine();*/ solution = null; for (int i = 0; i < dim; i++) { // Console.WriteLine("[{0}..{1}]",this.limits[i,0],this.limits[i,1]); this.ranges[i] = (this.limits[i, 1] - this.limits[i, 0]); } for (int i = 0; i < decisions.Count; i++) { decisions[i].CurTerm = (decisions[i].Assignment == CNSAT.Assignment.True?decisions[i].PositiveTerm:decisions[i].NegativeTerm); } //int idx = Math.Max(0,ss.DecisionLevel.Count-1); //r1 = RPropFindFeasible(decisions, ss.DecisionLevel[idx].Seed); r1 = RPropFindFeasible(decisions, lastSeed); if (r1.finalUtil < 0.5) { r1 = RPropFindFeasible(decisions, null); } if (r1.finalUtil < 0.5) { //Probe was not successfull -> assignment not valid //Console.Write("."); //Console.WriteLine("Could not find point for {0}",constraint); CNSAT.Clause learnt = new CNSAT.Clause(); foreach (CNSAT.Var v in decisions) { learnt.Add(new CNSAT.Lit(v, v.Assignment == CNSAT.Assignment.True ? CNSAT.Assignment.False : CNSAT.Assignment.True)); } ss.addTClause(learnt); return(false); } //ss.DecisionLevel[ss.DecisionLevel.Count-1].Seed = r1.finalValue; lastSeed = r1.finalValue; solution = r1.finalValue; successProbeCount++; return(true); }
protected double[] InitialPoint(RpropResult res) { Tuple <double[], double> tup; bool found = true; res.initialValue = new double[dim]; res.finalValue = new double[dim]; do { for (int i = 0; i < dim; i++) { //double range = limits[i,1]-limits[i,0]; res.initialValue[i] = rand.NextDouble() * ranges[i] + limits[i, 0]; } this.FEvals++; tup = term.Differentiate(res.initialValue); for (int i = 0; i < dim; i++) { if (Double.IsNaN(tup.Item1[i])) { //Console.WriteLine("NaN in Gradient, retrying"); found = false; break; } else { found = true; } } } while(!found); res.initialUtil = tup.Item2; res.finalUtil = tup.Item2; Buffer.BlockCopy(res.initialValue, 0, res.finalValue, 0, sizeof(double) * dim); return(tup.Item1); }
protected RpropResult RPropLoopSimple(double[] seed) { InitialStepSize(); double[] curGradient; RpropResult ret = new RpropResult(); if (seed != null) { curGradient = InitialPointFromSeed(ret, seed); } else { curGradient = InitialPoint(ret); } double curUtil = ret.initialUtil; if (ret.initialUtil > 0.75) { return(ret); } double[] formerGradient = new double[dim]; double[] curValue = new double[dim]; Tuple <double[], double> tup; Buffer.BlockCopy(ret.initialValue, 0, curValue, 0, sizeof(double) * dim); formerGradient = curGradient; //Buffer.BlockCopy(curGradient,0,formerGradient,0,sizeof(double)*dim); int itcounter = 0; int badcounter = 0; //Log(curUtil,curValue); while (itcounter++ < 40 && badcounter < 6) { for (int i = 0; i < dim; i++) { if (curGradient[i] * formerGradient[i] > 0) { rpropStepWidth[i] *= 1.3; } else if (curGradient[i] * formerGradient[i] < 0) { rpropStepWidth[i] *= 0.5; } rpropStepWidth[i] = Math.Max(0.0001, rpropStepWidth[i]); if (curGradient[i] > 0) { curValue[i] += rpropStepWidth[i]; } else if (curGradient[i] < 0) { curValue[i] -= rpropStepWidth[i]; } if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } } tup = term.Differentiate(curValue); bool allZero = true; for (int i = 0; i < dim; i++) { if (Double.IsNaN(tup.Item1[i])) { Console.WriteLine("NaN in gradient, aborting!"); ret.aborted = false; //true; //HACK! return(ret); } allZero &= (tup.Item1[i] == 0); } curUtil = tup.Item2; formerGradient = curGradient; curGradient = tup.Item1; //Log(curUtil,curValue); //Console.WriteLine("CurUtil: {0} Final {1}",curUtil,ret.finalUtil); if (curUtil > ret.finalUtil) { badcounter = 0; ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); if (curUtil > 0.75) { return(ret); } } else { badcounter++; } if (allZero) { //Console.WriteLine("All Zero!"); ret.aborted = false; return(ret); } } ret.aborted = false; return(ret); }
protected RpropResult RPropLoop(double[] seed, bool precise) { //Console.WriteLine("RpropLoop"); InitialStepSize(); double[] curGradient; RpropResult ret = new RpropResult(); if (seed != null) { curGradient = InitialPointFromSeed(ret, seed); } else { curGradient = InitialPoint(ret); } double curUtil = ret.initialUtil; double oldUtil = curUtil; double[] formerGradient = new double[dim]; double[] curValue = new double[dim]; double[] testValue = new double[dim]; double lambda = 0.1; Tuple <double[], double> tup; Buffer.BlockCopy(ret.initialValue, 0, curValue, 0, sizeof(double) * dim); formerGradient = curGradient; //Buffer.BlockCopy(curGradient,0,formerGradient,0,sizeof(double)*dim); int itcounter = 0; int badcounter = 0; /*Console.WriteLine("Initial Sol:"); * for(int i=0; i<dim;i++) { * Console.Write("{0} ",curValue[i]); * } * Console.WriteLine(); * Console.WriteLine("Initial Util: {0}",curUtil); */ #if (GSOLVER_LOG) Log(curUtil, curValue); #endif int maxIter = 60; int maxBad = 30; double minStep = 1E-11; if (precise) { maxIter = 120; //110 maxBad = 60; //60 minStep = 1E-15; //15 } int convergendDims = 0; while (itcounter++ < maxIter && badcounter < maxBad) { convergendDims = 0; //First Order resp. approximated Second Order Gradient for (int i = 0; i < dim; i++) { if (curGradient[i] * formerGradient[i] > 0) { rpropStepWidth[i] *= 1.3; } else if (curGradient[i] * formerGradient[i] < 0) { rpropStepWidth[i] *= 0.5; } rpropStepWidth[i] = Math.Max(minStep, rpropStepWidth[i]); //rpropStepWidth[i] = Math.Max(0.000001,rpropStepWidth[i]); if (curUtil > 0.0) { //if (curGradient[i] > 0) curValue[i] += rpropStepWidth[i]; //else if (curGradient[i] < 0) curValue[i] -= rpropStepWidth[i]; } else { //linear assumption //curValue[i] += -curUtil/curGradient[i]; //quadratic assumption /*double ypSquare = 0; * for(int j=0; j<dim; j++) { * ypSquare += curGradient[j]*curGradient[j]; * } * double m=ypSquare/curUtil; * curValue[i] = -curGradient[i]/(2*m) + curValue[i];*/ } if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } if (rpropStepWidth[i] < rpropStepConvergenceThreshold[i]) { ++convergendDims; } } //Abort if all dimensions are converged if (!precise && convergendDims >= dim) { if (curUtil > ret.finalUtil) { ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); } return(ret); } // Conjugate Gradient if (curUtil < 0.5) { DotNetMatrix.GeneralMatrix X = new DotNetMatrix.GeneralMatrix(dim * 2 + 1, dim); DotNetMatrix.GeneralMatrix Y = new DotNetMatrix.GeneralMatrix(dim * 2 + 1, 1); for (int n = 0; n < dim; n++) { X.SetElement(0, n, curValue[n]); } Y.SetElement(0, 0, 0); for (int j = 0; j < dim * 2; j++) { for (int n = 0; n < dim; n++) { double rVal = rand.NextDouble() * rpropStepConvergenceThreshold[n] * 1000.0; testValue[n] = curValue[n] + rVal; } tup = term.Differentiate(testValue); for (int n = 0; n < dim; n++) { X.SetElement(j + 1, n, tup.Item1[n]); } Y.SetElement(j + 1, 0, tup.Item2 - curUtil); } DotNetMatrix.GeneralMatrix JJ = X.Transpose().Multiply(X); /*if(curUtil>oldUtil) lambda *= 10; * else lambda *= 0.1;*/ //DotNetMatrix.GeneralMatrix B = JJ.Add(GeneralMatrix.Identity(dim, dim).Multiply(lambda)).Inverse().Multiply(X.Transpose()).Multiply(Y); DotNetMatrix.GeneralMatrix B = JJ.Add(JJ.SVD().S.Multiply(lambda)).Inverse().Multiply(X.Transpose()).Multiply(Y); //DotNetMatrix.GeneralMatrix B = JJ.Inverse().Multiply(X.Transpose()).Multiply(Y); for (int j = 0; j < dim; j++) { curValue[j] += 0.01 * B.GetElement(j, 0); } Console.WriteLine(curUtil); Console.Write(B.Transpose()); Console.WriteLine(); } ///////////////////////// this.FEvals++; tup = term.Differentiate(curValue); bool allZero = true; for (int i = 0; i < dim; i++) { if (Double.IsNaN(tup.Item1[i])) { ret.aborted = true; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } allZero &= (tup.Item1[i] == 0); } oldUtil = curUtil; curUtil = tup.Item2; formerGradient = curGradient; curGradient = tup.Item1; #if (GSOLVER_LOG) Log(curUtil, curValue); #endif //Console.WriteLine("CurUtil: {0} Final {1}",curUtil,ret.finalUtil); if (curUtil > ret.finalUtil) { badcounter = 0; //Math.Max(0,badcounter-1); //if (curUtil-ret.finalUtil < 0.00000000000001) { //Console.WriteLine("not better"); // badcounter++; //} else { //badcounter = 0; //} ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); //ret.finalValue = curValue; #if (ALWAYS_CHECK_THRESHOLD) if (curUtil > utilityThreshold) { return(ret); } #endif } else { //if (curUtil < ret.finalUtil || curUtil > 0) badcounter++; badcounter++; } if (allZero) { //Console.WriteLine("All Zero!"); /*Console.WriteLine("Util {0}",curUtil); * Console.Write("Vals: "); * for(int i=0; i < dim; i++) { * Console.Write("{0}\t",curValue[i]); * } * Console.WriteLine();*/ ret.aborted = false; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } } #if (GSOLVER_LOG) LogStep(); #endif ret.aborted = false; return(ret); }
public double[] Solve(AD.Term equation, AD.Variable[] args, double[,] limits, double[][] seeds, double sufficientUtility, out double util) { this.FEvals = 0; this.Runs = 0; util = 0; this.utilityThreshold = sufficientUtility; #if (GSOLVER_LOG) InitLog(); #endif rResults.Clear(); ulong begin = RosCS.RosSharp.Now(); this.dim = args.Length; this.limits = limits; this.ranges = new double[dim]; for (int i = 0; i < dim; i++) { this.ranges[i] = (this.limits[i, 1] - this.limits[i, 0]); } #if AGGREGATE_CONSTANTS equation = equation.AggregateConstants(); #endif term = AD.TermUtils.Compile(equation, args); AD.ConstraintUtility cu = (AD.ConstraintUtility)equation; bool utilIsConstant = (cu.Utility is AD.Constant); if (utilIsConstant) { this.utilityThreshold = 0.75; } bool constraintIsConstant = (cu.Constraint is AD.Constant); if (constraintIsConstant) { if (((AD.Constant)cu.Constraint).Value < 0.25) { util = ((AD.Constant)cu.Constraint).Value; double[] ret = new double[dim]; for (int i = 0; i < dim; i++) { ret[i] = this.ranges[i] / 2.0 + this.limits[i, 0]; } return(ret); } } //Optimize given seeds this.rpropStepWidth = new double[dim]; this.rpropStepConvergenceThreshold = new double[dim]; if (seeds != null) { this.Runs++; //Run with prefered cached seed RpropResult rpfirst = RPropLoop(seeds[0], true); if (rpfirst.finalUtil > this.utilityThreshold) { util = rpfirst.finalUtil; //Console.WriteLine("FEvals: {0}",this.FEvals); return(rpfirst.finalValue); } rResults.Add(rpfirst); //run with seeds of all other agends for (int i = 1; i < seeds.Length; i++) { if (begin + this.maxSolveTime < RosCS.RosSharp.Now() || this.FEvals > this.MaxFEvals) { break; //do not check any further seeds } this.Runs++; RpropResult rp = RPropLoop(seeds[i], false); if (rp.finalUtil > this.utilityThreshold) { util = rp.finalUtil; //Console.WriteLine("FEvals: {0}",this.FEvals); return(rp.finalValue); } rResults.Add(rp); } } //Here: Ignore all constraints search optimum if (begin + this.maxSolveTime > RosCS.RosSharp.Now() && this.FEvals < this.MaxFEvals) { //if time allows, do an unconstrained run if (!constraintIsConstant && !utilIsConstant && seedWithUtilOptimum) { AD.ICompiledTerm curProb = term; term = AD.TermUtils.Compile(((AD.ConstraintUtility)equation).Utility, args); this.Runs++; double[] utilitySeed = RPropLoop(null).finalValue; term = curProb; //Take result and search with constraints RpropResult ru = RPropLoop(utilitySeed, false); /*if (ru.finalUtil > this.utilityThreshold) { * util = ru.finalUtil; * return ru.finalValue; * }*/ rResults.Add(ru); } } do //Do runs until termination criteria, running out of time, or too many function evaluations { this.Runs++; RpropResult rp = RPropLoop(null, false); if (rp.finalUtil > this.utilityThreshold) { util = rp.finalUtil; //Console.WriteLine("FEvals: {0}",this.FEvals); return(rp.finalValue); } rResults.Add(rp); } while(begin + this.maxSolveTime > RosCS.RosSharp.Now() && this.FEvals < this.MaxFEvals); //return best result int resIdx = 0; RpropResult res = rResults[0]; for (int i = 1; i < rResults.Count; i++) { if (Double.IsNaN(res.finalUtil) || rResults[i].finalUtil > res.finalUtil) { if (resIdx == 0 && seeds != null && !Double.IsNaN(res.finalUtil)) { if (rResults[i].finalUtil - res.finalUtil > utilitySignificanceThreshold && rResults[i].finalUtil > 0.75) { res = rResults[i]; resIdx = i; } } else { res = rResults[i]; resIdx = i; } } } //Console.WriteLine("ResultIndex: {0} Delta {1}",resIdx,res.finalUtil-rResults[0].finalUtil); #if (GSOLVER_LOG) CloseLog(); #endif // Console.Write("Found: "); // for(int i=0; i<dim; i++) { // Console.Write("{0}\t",res.finalValue[i]); // } // Console.WriteLine(); // //Console.WriteLine("Runs: {0} FEvals: {1}",this.Runs,this.FEvals); util = res.finalUtil; return(res.finalValue); }
protected RpropResult RPropLoop(double[] seed, bool precise) { //Console.WriteLine("RpropLoop"); InitialStepSize(); double[] curGradient; RpropResult ret = new RpropResult(); if (seed != null) { curGradient = InitialPointFromSeed(ret, seed); } else { curGradient = InitialPoint(ret); } double curUtil = ret.initialUtil; double[] formerGradient = new double[dim]; double[] curValue = new double[dim]; Tuple <double[], double> tup; Buffer.BlockCopy(ret.initialValue, 0, curValue, 0, sizeof(double) * dim); formerGradient = curGradient; //Buffer.BlockCopy(curGradient,0,formerGradient,0,sizeof(double)*dim); int itcounter = 0; int badcounter = 0; /*Console.WriteLine("Initial Sol:"); * for(int i=0; i<dim;i++) { * Console.Write("{0} ",curValue[i]); * } * Console.WriteLine(); * Console.WriteLine("Initial Util: {0}",curUtil); */ #if (GSOLVER_LOG) Log(curUtil, curValue); #endif int maxIter = 60; int maxBad = 30; double minStep = 1E-11; if (precise) { maxIter = 120; //110 maxBad = 60; //60 minStep = 1E-15; //15 } int convergendDims = 0; while (itcounter++ < maxIter && badcounter < maxBad) { //Console.WriteLine("Iteration {0}",itcounter); //Console.WriteLine("Val: "); /*if (curUtil < 0.5 && rand.NextDouble()< 0.05) { //JUMP! * //Console.WriteLine("JUMPING!"); * for (int i=0; i<dim; i++) { * curValue[i] += curGradient[i]; * if (curValue[i] > limits[i,1]) curValue[i] = limits[i,1]; * else if (curValue[i] < limits[i,0]) curValue[i] = limits[i,0]; * } * InitialStepSize(); * } else {*/ convergendDims = 0; for (int i = 0; i < dim; i++) { if (curGradient[i] * formerGradient[i] > 0) { rpropStepWidth[i] *= 1.3; } else if (curGradient[i] * formerGradient[i] < 0) { rpropStepWidth[i] *= 0.5; } rpropStepWidth[i] = Math.Max(minStep, rpropStepWidth[i]); //rpropStepWidth[i] = Math.Max(0.000001,rpropStepWidth[i]); if (curGradient[i] > 0) { curValue[i] += rpropStepWidth[i]; } else if (curGradient[i] < 0) { curValue[i] -= rpropStepWidth[i]; } if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } //Console.Write("{0}\t",curValue[i]); if (rpropStepWidth[i] < rpropStepConvergenceThreshold[i]) { ++convergendDims; } } //Abort if all dimensions are converged if (!precise && convergendDims >= dim) { if (curUtil > ret.finalUtil) { ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); } return(ret); } //} //Console.WriteLine(); this.FEvals++; tup = term.Differentiate(curValue); bool allZero = true; //Console.WriteLine("Grad: "); for (int i = 0; i < dim; i++) { if (Double.IsNaN(tup.Item1[i])) { //Console.Error.WriteLine("NaN in gradient, aborting!"); ret.aborted = true; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } allZero &= (tup.Item1[i] == 0); //Console.Write("{0}\t",tup.Item1[i]); } //Console.WriteLine(); curUtil = tup.Item2; formerGradient = curGradient; curGradient = tup.Item1; #if (GSOLVER_LOG) Log(curUtil, curValue); #endif //Console.WriteLine("CurUtil: {0} Final {1}",curUtil,ret.finalUtil); if (curUtil > ret.finalUtil) { badcounter = 0; //Math.Max(0,badcounter-1); //if (curUtil-ret.finalUtil < 0.00000000000001) { //Console.WriteLine("not better"); // badcounter++; //} else { //badcounter = 0; //} ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); //ret.finalValue = curValue; #if (ALWAYS_CHECK_THRESHOLD) if (curUtil > utilityThreshold) { return(ret); } #endif } else { //if (curUtil < ret.finalUtil || curUtil > 0) badcounter++; badcounter++; } if (allZero) { //Console.WriteLine("All Zero!"); /*Console.WriteLine("Util {0}",curUtil); * Console.Write("Vals: "); * for(int i=0; i < dim; i++) { * Console.Write("{0}\t",curValue[i]); * } * Console.WriteLine();*/ ret.aborted = false; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } } #if (GSOLVER_LOG) LogStep(); #endif ret.aborted = false; return(ret); }
protected RpropResult RPropLoop(double[] seed, bool precise, bool useQEstimate) { //Console.WriteLine("RpropLoop"); InitialStepSize(); double[] curGradient; RpropResult ret = new RpropResult(); if (seed != null) { curGradient = InitialPointFromSeed(ret, seed); } else { curGradient = InitialPoint(ret); } double curUtil = ret.initialUtil; double[] formerGradient = new double[dim]; double[] curValue = new double[dim]; double[] otherSamplePoint = new double[dim]; Tuple <double[], double> tup = null; Buffer.BlockCopy(ret.initialValue, 0, curValue, 0, sizeof(double) * dim); formerGradient = curGradient; //Buffer.BlockCopy(curGradient,0,formerGradient,0,sizeof(double)*dim); int itcounter = 0; int badcounter = 0; /*Console.WriteLine("Initial Sol:"); * for(int i=0; i<dim;i++) { * Console.Write("{0} ",curValue[i]); * } * Console.WriteLine(); * Console.WriteLine("Initial Util: {0}",curUtil); */ #if (GSOLVER_LOG) Log(curUtil, curValue, 1); #endif int maxIter = 60; int maxBad = 30; double minStep = 1E-11; if (precise) { maxIter = 110; maxBad = 60; minStep = 1E-15; } while (itcounter++ < maxIter && badcounter < maxBad) { if (useQEstimate && tup != null) { for (int i = 0; i < dim; i++) { otherSamplePoint[i] = curValue[i] + Math.Sign(curGradient[i]) * Math.Max(1, rpropStepWidth[i] / 3.0); } double oval = term.Evaluate(otherSamplePoint); getNewSamplePoint(oval, tup.Item2, curValue, otherSamplePoint, tup.Item1); Tuple <double[], double> tup2 = term.Differentiate(samplePoint); this.FEvals += 2; if (tup2.Item2 > tup.Item2) { //useQEstimate = false; //Console.WriteLine("y"); curUtil = tup2.Item2; formerGradient = curGradient; curGradient = tup2.Item1; bool allZero1 = true; for (int i = 0; i < dim; i++) { allZero1 &= curGradient[i] == 0; curValue[i] = samplePoint[i]; if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } } #if (GSOLVER_LOG) Log(curUtil, curValue, 2); #endif if (curUtil > ret.finalUtil) { badcounter = 0; //Math.Max(0,badcounter-1); ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); } if (allZero1) { ret.aborted = false; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } } } for (int i = 0; i < dim; i++) { if (curGradient[i] * formerGradient[i] > 0) { rpropStepWidth[i] *= 1.3; } else if (curGradient[i] * formerGradient[i] < 0) { rpropStepWidth[i] *= 0.5; } rpropStepWidth[i] = Math.Max(minStep, rpropStepWidth[i]); //rpropStepWidth[i] = Math.Max(0.000001,rpropStepWidth[i]); if (curGradient[i] > 0) { curValue[i] += rpropStepWidth[i]; } else if (curGradient[i] < 0) { curValue[i] -= rpropStepWidth[i]; } if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } } this.FEvals++; tup = term.Differentiate(curValue); bool allZero = true; //Console.WriteLine("Grad: "); for (int i = 0; i < dim; i++) { if (Double.IsNaN(tup.Item1[i])) { //Console.Error.WriteLine("NaN in gradient, aborting!"); ret.aborted = true; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } allZero &= (tup.Item1[i] == 0); //Console.Write("{0}\t",tup.Item1[i]); } //Console.WriteLine(); curUtil = tup.Item2; formerGradient = curGradient; curGradient = tup.Item1; #if (GSOLVER_LOG) Log(curUtil, curValue, 1); #endif //Console.WriteLine("CurUtil: {0} Final {1}",curUtil,ret.finalUtil); if (curUtil > ret.finalUtil) { badcounter = 0; //Math.Max(0,badcounter-1); //if (curUtil-ret.finalUtil < 0.00000000000001) { //Console.WriteLine("not better"); // badcounter++; //} else { //badcounter = 0; //} ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); //ret.finalValue = curValue; } else { //if (curUtil < ret.finalUtil || curUtil > 0) badcounter++; badcounter++; } if (allZero) { //Console.WriteLine("All Zero!"); /*Console.WriteLine("Util {0}",curUtil); * Console.Write("Vals: "); * for(int i=0; i < dim; i++) { * Console.Write("{0}\t",curValue[i]); * } * Console.WriteLine();*/ ret.aborted = false; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } } #if (GSOLVER_LOG) LogStep(); #endif ret.aborted = false; return(ret); }
public double[] Solve(AD.Term equation, AD.Variable[] args, double[,] limits, double[][] seeds, out double util) { //this.FEvals = 0; util = 0; #if (GSOLVER_LOG) InitLog(); #endif rResults.Clear(); this.dim = args.Length; this.limits = limits; this.ranges = new double[dim]; for (int i = 0; i < dim; i++) { this.ranges[i] = (this.limits[i, 1] - this.limits[i, 0]); } equation = equation.AggregateConstants(); term = AD.TermUtils.Compile(equation, args); AD.ConstraintUtility cu = (AD.ConstraintUtility)equation; bool utilIsConstant = (cu.Utility is AD.Constant); bool constraintIsConstant = (cu.Constraint is AD.Constant); if (constraintIsConstant) { if (((AD.Constant)cu.Constraint).Value < 0.25) { util = ((AD.Constant)cu.Constraint).Value; double[] ret = new double[dim]; for (int i = 0; i < dim; i++) { ret[i] = this.ranges[i] / 2.0 + this.limits[i, 0]; } return(ret); } } this.rpropStepWidth = new double[dim]; this.samplePoint = new double[dim]; if (seeds != null) { RpropResult rpfirst = RPropLoop(seeds[0], true, false); if (utilIsConstant && rpfirst.finalUtil > 0.75) { util = rpfirst.finalUtil; //Console.WriteLine("FEvals: {0}",this.FEvals); return(rpfirst.finalValue); } rResults.Add(rpfirst); for (int i = 1; i < seeds.Length; i++) { RpropResult rp = RPropLoop(seeds[i], false, false); if (utilIsConstant && rp.finalUtil > 0.75) { util = rp.finalUtil; //Console.WriteLine("FEvals: {0}",this.FEvals); return(rp.finalValue); } rResults.Add(rp); } } if (!constraintIsConstant && !utilIsConstant && seedWithUtilOptimum) { AD.ICompiledTerm curProb = term; term = AD.TermUtils.Compile(((AD.ConstraintUtility)equation).Utility, args); double[] utilitySeed = RPropLoop(null).finalValue; /*Console.WriteLine("Unconstraint Seed:"); * Console.Write("S: "); * foreach(double d in utilitySeed) Console.Write("{0} ",d); * Console.WriteLine(); */ term = curProb; rResults.Add(RPropLoop(utilitySeed, false, false)); } int runs = Math.Max(3, 1 * dim - (seeds == null?0:seeds.Length)); //runs = 10; RpropResult rpQS = RPropLoop(null, false, true); if (utilIsConstant && rpQS.finalUtil > 0.75) { util = rpQS.finalUtil; return(rpQS.finalValue); } rResults.Add(rpQS); for (int i = 1; i < runs; i++) { RpropResult rp = RPropLoop(null, false, false); if (utilIsConstant && rp.finalUtil > 0.75) { util = rp.finalUtil; //Console.WriteLine("FEvals: {0}",this.FEvals); return(rp.finalValue); } rResults.Add(rp); } int resIdx = 0; RpropResult res = rResults[0]; for (int i = 1; i < rResults.Count; i++) { if (Double.IsNaN(res.finalUtil) || rResults[i].finalUtil > res.finalUtil) { if (resIdx == 0 && seeds != null && !Double.IsNaN(res.finalUtil)) { if (rResults[i].finalUtil - res.finalUtil > utilitySignificanceThreshold && rResults[i].finalUtil > 0.75) { res = rResults[i]; resIdx = i; } } else { res = rResults[i]; resIdx = i; } } } //Console.WriteLine("ResultIndex: {0} Delta {1}",resIdx,res.finalUtil-rResults[0].finalUtil); #if (GSOLVER_LOG) CloseLog(); #endif // Console.Write("Found: "); // for(int i=0; i<dim; i++) { // Console.Write("{0}\t",res.finalValue[i]); // } // Console.WriteLine(); // //Console.WriteLine("FEvals: {0}",this.FEvals); util = res.finalUtil; return(res.finalValue); }
protected double[] InitialPoint(List <CNSAT.Var> constraints, RpropResult res) { Tuple <double[], double> tup; bool found = true; res.initialValue = new double[dim]; res.finalValue = new double[dim]; double[] gradient; do { gradient = new double[dim]; found = true; res.initialUtil = 1; for (int i = 0; i < dim; i++) { res.initialValue[i] = rand.NextDouble() * ranges[i] + limits[i, 0]; } this.fevalsCount++; for (int i = 0; i < constraints.Count; i++) { if (constraints[i].Assignment == CNSAT.Assignment.True) { if (constraints[i].PositiveTerm == null) { constraints[i].PositiveTerm = TermUtils.Compile(constraints[i].Term, this.currentArgs); } constraints[i].CurTerm = constraints[i].PositiveTerm; } else { if (constraints[i].NegativeTerm == null) { constraints[i].NegativeTerm = TermUtils.Compile(constraints[i].Term.Negate(), this.currentArgs); } constraints[i].CurTerm = constraints[i].NegativeTerm; } tup = constraints[i].CurTerm.Differentiate(res.initialValue); for (int j = 0; j < dim; j++) { if (Double.IsNaN(tup.Item1[j])) { found = false; break; } gradient[j] += tup.Item1[j]; } if (!found) { break; } if (tup.Item2 <= 0.0) { if (res.initialUtil > 0.0) { res.initialUtil = tup.Item2; } else { res.initialUtil += tup.Item2; } } } //tup = term.Differentiate(res.initialValue); } while(!found); res.finalUtil = res.initialUtil; Buffer.BlockCopy(res.initialValue, 0, res.finalValue, 0, sizeof(double) * dim); return(gradient); }
protected RpropResult RPropOptimizeFeasible(List <CNSAT.Var> constraints, AD.Term ut, AD.Variable[] args, double[] seed, bool precise) { //Compiled Term zusammenbauen AD.Term constr = AD.Term.True; foreach (CNSAT.Var v in constraints) { if (v.Assignment == Alica.Reasoner.CNSAT.Assignment.True) { constr &= v.Term; } else { constr &= ConstraintBuilder.Not(v.Term); } } AD.ConstraintUtility cu = new AD.ConstraintUtility(constr, ut); AD.ICompiledTerm term = AD.TermUtils.Compile(cu, args); Tuple <double[], double> tup; //fertig zusammengebaut runCount++; InitialStepSize(); double[] curGradient; RpropResult ret = new RpropResult(); // curGradient = InitialPoint(constraints, ret); if (seed != null) { curGradient = InitialPointFromSeed(constraints, ret, seed); } else { curGradient = InitialPoint(constraints, ret); } double curUtil = ret.initialUtil; double[] formerGradient = new double[dim]; double[] curValue = new double[dim]; //Tuple<double[],double> tup; Buffer.BlockCopy(ret.initialValue, 0, curValue, 0, sizeof(double) * dim); formerGradient = curGradient; int itcounter = 0; int badcounter = 0; #if (GSOLVER_LOG) Log(curUtil, curValue); #endif int maxIter = 60; int maxBad = 30; double minStep = 1E-11; if (precise) { maxIter = 120; //110 maxBad = 60; //60 minStep = 1E-15; //15 } int convergendDims = 0; while (itcounter++ < maxIter && badcounter < maxBad) { convergendDims = 0; for (int i = 0; i < dim; i++) { if (curGradient[i] * formerGradient[i] > 0) { rpropStepWidth[i] *= 1.3; } else if (curGradient[i] * formerGradient[i] < 0) { rpropStepWidth[i] *= 0.5; } rpropStepWidth[i] = Math.Max(minStep, rpropStepWidth[i]); //rpropStepWidth[i] = Math.Max(0.000001,rpropStepWidth[i]); if (curGradient[i] > 0) { curValue[i] += rpropStepWidth[i]; } else if (curGradient[i] < 0) { curValue[i] -= rpropStepWidth[i]; } if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } //Console.Write("{0}\t",curValue[i]); if (rpropStepWidth[i] < rpropStepConvergenceThreshold[i]) { ++convergendDims; } } //Abort if all dimensions are converged if (!precise && convergendDims >= dim) { return(ret); } this.fevalsCount++; formerGradient = curGradient; tup = term.Differentiate(curValue); bool allZero = true; for (int i = 0; i < dim; i++) { if (Double.IsNaN(tup.Item1[i])) { ret.aborted = false; //true; //HACK! #if (GSOLVER_LOG) LogStep(); #endif return(ret); } allZero &= (tup.Item1[i] == 0); } curUtil = tup.Item2; formerGradient = curGradient; curGradient = tup.Item1; #if (GSOLVER_LOG) Log(curUtil, curValue); #endif //Console.WriteLine("CurUtil: {0} Final {1}",curUtil,ret.finalUtil); if (curUtil > ret.finalUtil) { badcounter = 0; //Math.Max(0,badcounter-1); ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); //ret.finalValue = curValue; if (curUtil > 0.75) { return(ret); } } else { badcounter++; } if (allZero) { ret.aborted = false; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } } #if (GSOLVER_LOG) LogStep(); #endif ret.aborted = false; return(ret); }
protected RpropResult RPropFindFeasible(List <CNSAT.Var> constraints, double[] seed) { runCount++; InitialStepSize(); double[] curGradient; RpropResult ret = new RpropResult(); // curGradient = InitialPoint(constraints, ret); if (seed != null) { curGradient = InitialPointFromSeed(constraints, ret, seed); } else { curGradient = InitialPoint(constraints, ret); } double curUtil = ret.initialUtil; if (curUtil > 0.5) { return(ret); } double[] formerGradient = new double[dim]; double[] curValue = new double[dim]; //Tuple<double[],double> tup; Buffer.BlockCopy(ret.initialValue, 0, curValue, 0, sizeof(double) * dim); formerGradient = curGradient; int itcounter = 0; int badcounter = 0; #if (GSOLVER_LOG) Log(curUtil, curValue); #endif int maxIter = 60; int maxBad = 30; double minStep = 1E-11; while (itcounter++ < maxIter && badcounter < maxBad) { for (int i = 0; i < dim; i++) { if (curGradient[i] * formerGradient[i] > 0) { rpropStepWidth[i] *= 1.3; } else if (curGradient[i] * formerGradient[i] < 0) { rpropStepWidth[i] *= 0.5; } rpropStepWidth[i] = Math.Max(minStep, rpropStepWidth[i]); if (curGradient[i] > 0) { curValue[i] += rpropStepWidth[i]; } else if (curGradient[i] < 0) { curValue[i] -= rpropStepWidth[i]; } if (curValue[i] > limits[i, 1]) { curValue[i] = limits[i, 1]; } else if (curValue[i] < limits[i, 0]) { curValue[i] = limits[i, 0]; } } this.fevalsCount++; formerGradient = curGradient; Differentiate(constraints, curValue, out curGradient, out curUtil); bool allZero = true; for (int i = 0; i < dim; i++) { if (Double.IsNaN(curGradient[i])) { //Console.Error.WriteLine("NaN in gradient, aborting!"); ret.aborted = true; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } allZero &= (curGradient[i] == 0); } #if (GSOLVER_LOG) Log(curUtil, curValue); #endif //Console.WriteLine("CurUtil: {0} Final {1}",curUtil,ret.finalUtil); if (curUtil > ret.finalUtil) { badcounter = 0; //Math.Max(0,badcounter-1); ret.finalUtil = curUtil; Buffer.BlockCopy(curValue, 0, ret.finalValue, 0, sizeof(double) * dim); //ret.finalValue = curValue; if (curUtil > 0.75) { return(ret); } } else { badcounter++; } if (allZero) { ret.aborted = false; #if (GSOLVER_LOG) LogStep(); #endif return(ret); } } #if (GSOLVER_LOG) LogStep(); #endif ret.aborted = false; return(ret); }
public double[] Solve(AD.Term equation, AD.Variable[] args, double[,] limits, double[][] seeds, out double util) { lastSeed = null; probeCount = 0; successProbeCount = 0; intervalCount = 0; successIntervalCount = 0; fevalsCount = 0; runCount = 0; this.begin = RosCS.RosSharp.Now(); //this.FEvals = 0; util = 0; #if (GSOLVER_LOG) InitLog(); #endif //ft.Reset(); rResults.Clear(); currentArgs = args; this.dim = args.Length; this.limits = limits; this.ranges = new double[dim]; this.rpropStepWidth = new double[dim]; this.rpropStepConvergenceThreshold = new double[dim]; equation = equation.AggregateConstants(); AD.ConstraintUtility cu = (AD.ConstraintUtility)equation; bool utilIsConstant = (cu.Utility is AD.Constant); bool constraintIsConstant = (cu.Constraint is AD.Constant); if (constraintIsConstant) { if (((AD.Constant)cu.Constraint).Value < 0.25) { util = ((AD.Constant)cu.Constraint).Value; double[] ret = new double[dim]; for (int i = 0; i < dim; i++) { ret[i] = (this.limits[i, 1] + this.limits[i, 0]) / 2.0; //this.ranges[i]/2.0+this.limits[i,0]; } return(ret); } } ss = new CNSAT.CNSat(); ss.UseIntervalProp = this.UseIntervalProp; //Console.WriteLine(cu.Constraint); LinkedList <CNSAT.Clause> cnf = ft.TransformToCNF(cu.Constraint, ss); /*Console.WriteLine("Atoms: {0}, Occurrence: {1}",ft.Atoms.Count,ft.AtomOccurrence); * Console.WriteLine("Clauses: {0}",cnf.Count); * foreach(AD.Term atom in ft.Atoms.Keys) { * Console.WriteLine("-------"); * Console.WriteLine(atom); * Console.WriteLine("-------"); * }*/ /* * int litc=1; * List<AD.Term> terms = new List<AD.Term>(ft.Atoms); * * currentAtoms = new Dictionary<int, Term>(); * * foreach(AD.Term t in terms) { * foreach(Literal l in ft.References[t]) { * l.Id = litc; * } * currentAtoms.Add(litc,t); * litc++; * }*/ if (UseIntervalProp) { ip.SetGlobalRanges(args, limits, ss); } foreach (CNSAT.Clause c in cnf) { if (!c.IsTautologic) { if (c.Literals.Count == 0) { util = Double.MinValue; double[] ret = new double[dim]; for (int i = 0; i < dim; i++) { ret[i] = (this.limits[i, 1] + this.limits[i, 0]) / 2.0; } return(ret); } //Post Clause Here //Console.Write("\nAdding Clause with "+c.Literals.Count+" Literals\n"); //c.Print(); ss.addBasicClause(c); } } ss.CNSMTGSolver = this; ss.Init(); //PRE-Propagation: if (UseIntervalProp) { #if DO_PREPROPAGATION if (!ip.PrePropagate(ss.Variables)) { Console.WriteLine("Unsatisfiable (unit propagation)"); return(null); } #endif } //END-PrePropagation //Console.WriteLine("Variable Count: " + ss.Variables.Count); bool solutionFound = false; ss.UnitDecissions = ss.Decisions.Count; do { if (!solutionFound) { ss.EmptySATClause(); ss.EmptyTClause(); ss.backTrack(ss.UnitDecissions); } solutionFound = ss.solve(); if (Optimize) { r1 = RPropOptimizeFeasible(ss.Decisions, ((AD.ConstraintUtility)equation).Utility, args, r1.finalValue, false); } if (!solutionFound && r1.finalUtil > 0) { r1.finalUtil = -1; } util = r1.finalUtil; if (!Optimize && solutionFound) { return(r1.finalValue); } else if (Optimize) { //optimization case rResults.Add(r1); CNSAT.Clause c = new Alica.Reasoner.CNSAT.Clause(); foreach (CNSAT.Var v in ss.Decisions) { c.Add(new CNSAT.Lit(v, v.Assignment == CNSAT.Assignment.True ? CNSAT.Assignment.False : CNSAT.Assignment.True)); } //ss.addBasicClause(c); ss.addIClause(c); ss.backTrack(ss.Decisions[ss.Decisions.Count - 1].DecisionLevel); solutionFound = false; } } while (!solutionFound && this.begin + this.maxSolveTime > RosCS.RosSharp.Now() /*&& this.runCount < this.MaxFEvals*/); //Console.WriteLine("Probes: {0}/{1}\tIntervals: {2}/{3}",successProbeCount,probeCount,successIntervalCount,intervalCount); //ip.PrintStats(); //Console.WriteLine("Rprop Runs: {0}\t FEvals {1}\t Solutions Found: {2}",this.runCount,this.fevalsCount, rResults.Count); //return best result if (rResults.Count > 0) { foreach (RpropResult rp in rResults) { if (rp.finalUtil > util) { util = rp.finalUtil; r1 = rp; } } return(r1.finalValue); } Console.WriteLine("Unsatisfiable"); return(null); }