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); }
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); }