예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        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);
        }