예제 #1
0
        public static Var DecideVariableCountBased(List <Var> variables, CNSat solver)
        {
            int vars     = variables.Count;
            Lit l        = null;
            int maxCount = Int32.MaxValue;
            int minCount = -1;

            for (int i = 0; i < vars; i++)
            {
                if (variables[i].Assignment != Assignment.Unassigned)
                {
                    continue;
                }
                for (int j = 0; j < variables[i].WatchList.Count; j++)
                {
                    if (!variables[i].WatchList[j].Clause.Satisfied)
                    {
                        /*if(maxCount>variables[i].WatchList[j].Lit.VariableCount) {
                         *      l = variables[i].WatchList[j].Lit;
                         *      maxCount = l.VariableCount;
                         * }*/
                        if (minCount < variables[i].WatchList[j].Lit.VariableCount)
                        {
                            l        = variables[i].WatchList[j].Lit;
                            minCount = l.VariableCount;
                        }
                    }
                }
            }
            if (l == null)
            {
                return(null);
            }
            Assignment ass;
            Var        v = l.Var;

            ass = l.Sign;

            DecisionLevel d = new DecisionLevel(solver.Decisions.Count);

            solver.DecisionLevel.Add(d);
            v.Assignment = ass;
            solver.Decisions.Add(v);
            v.Reason        = null;
            v.DecisionLevel = d;

            return(v);
        }
예제 #2
0
        public LinkedList <Clause> TransformToCNF(Term formula, CNSat solver)
        {
            this.solver = solver;
            Reset();
            LinkedList <Clause> clauses = new LinkedList <Clause>();
            Clause initial = new Clause();

            initial.Literals.Add(new Lit(formula, Assignment.Unassigned, true));

            clauses.AddFirst(initial);

            DoTransform(clauses);
#if FORMULATRANS_DEBUG
            Console.WriteLine("Clauses: {0} Lits: {1} Vars: {2}", clauses.Count, this.AtomOccurrence, solver.Variables.Count);
#endif

            return(clauses);
        }
예제 #3
0
        public static Var DecideActivityBased(List <Var> variables, CNSat solver)
        {
            int    vars = variables.Count;
            Random r = solver.r;
            int    init = r.Next(vars);
            Var    v = null, next = null;
            int    maxActivity = 0;

            //Search Lit with highest Activity
            if (solver.CNSMTGSolver == null)
            {
                for (int i = 0; i < vars; i++)
                {
                    int p = (init + i) % vars;
                    if (p < 0 || p >= vars)
                    {
                        Console.WriteLine("p = " + p);
                    }
                    v = variables[p];
                    if (v.Assignment == Assignment.Unassigned)
                    {
                        if (maxActivity <= v.Activity)
                        {
                            maxActivity = v.Activity;
                            next        = v;
                        }
                    }
                }
                //Decide it
                if (next != null)
                {
                    DecisionLevel d = new DecisionLevel(solver.Decisions.Count);
                    solver.DecisionLevel.Add(d);

                    double rel = next.PositiveAppearance + next.NegativeAppearance;
                    if (rel != 0)
                    {
                        rel = ((double)next.PositiveAppearance) / rel;
                    }
                    else
                    {
                        rel = 0.5;
                    }

                    next.Assignment = (r.NextDouble() < rel) ? Assignment.True : Assignment.False;
                    solver.Decisions.Add(next);
                    next.Reason        = null;
                    next.DecisionLevel = d;
                    return(next);
                }
            }
            else
            {
                init = r.Next(solver.Clauses.Count);
                for (int i = 0; i < solver.Clauses.Count; i++)
                {
                    Clause c = solver.Clauses[(i + init) % solver.Clauses.Count];
                    if (!c.Satisfied && c.Literals.Count > 1)
                    {
                        if (!c.watcher[0].Lit.Satisfied())
                        {
                            next = c.watcher[0].Lit.Var;
                            DecisionLevel d = new DecisionLevel(solver.Decisions.Count);
                            solver.DecisionLevel.Add(d);

                            next.Assignment = c.watcher[0].Lit.Sign;
                            solver.Decisions.Add(next);
                            next.Reason        = null;
                            next.DecisionLevel = d;
                            return(next);
                        }
                        else if (!c.watcher[1].Lit.Satisfied())
                        {
                            DecisionLevel d = new DecisionLevel(solver.Decisions.Count);
                            solver.DecisionLevel.Add(d);
                            next = c.watcher[1].Lit.Var;

                            next.Assignment = c.watcher[1].Lit.Sign;
                            solver.Decisions.Add(next);
                            next.Reason        = null;
                            next.DecisionLevel = d;
                            return(next);
                        }
                        else
                        {
                            Console.WriteLine("This shoud Never Happen!!");
                        }
                    }
                }
            }

            return(null);
        }
예제 #4
0
        public static Var DecideRangeBased(List <Var> variables, CNSat solver)
        {
            List <Lit> choices = new List <Lit>();
            int        vars    = variables.Count;

            for (int i = 0; i < vars; i++)
            {
                if (variables[i].Assignment != Assignment.Unassigned)
                {
                    continue;
                }
                bool hT = false;
                bool hF = false;
                for (int j = 0; j < variables[i].WatchList.Count; j++)
                {
                    if (!variables[i].WatchList[j].Clause.Satisfied)
                    {
                        if (variables[i].WatchList[j].Lit.Sign == Assignment.True)
                        {
                            if (!hT)
                            {
                                choices.Add(variables[i].WatchList[j].Lit);
                            }
                            hT = true;
                        }
                        else
                        {
                            if (!hF)
                            {
                                choices.Add(variables[i].WatchList[j].Lit);
                            }
                            hF = true;
                        }
                    }
                    if (hT && hF)
                    {
                        break;
                    }
                }
            }
            if (choices.Count == 0)
            {
                return(null);
            }

            choices.Sort(LitRangeCompare);

            /*Console.WriteLine("======");
            *  foreach(Lit l in choices) {
            *       Console.WriteLine("{0}",(l.Sign == Assignment.True ? l.Var.PositiveRangeSize:l.Var.NegativeRangeSize));
            *  }
            *  Console.WriteLine("======");*/
            //Choices are now in ascending order!
            Var        v;
            Assignment ass;

            //Uniform:
            //int idx = solver.Rand.Next(choices.Count);
            //smallest range:
            //int idx = 0;
            //largest range:
            int idx = choices.Count - 1;

            //Prefer smaller:

            /*int idx = choices.Count-1;
             * double r = solver.Rand.NextDouble();
             * double q = 0;
             * for(int i=0; i<choices.Count; i++) {
             *      q += 1.0/(i+2);
             *      if (q > r) {
             *              idx = i;
             *              break;
             *      }
             * }*/
            //Prefer larger:

            /*int idx = 0;
             * double r = solver.Rand.NextDouble();
             * double q = 0;
             * for(int i=0; i<choices.Count; i++) {
             *      q += 1.0/(i+2);
             *      if (q > r) {
             *              idx = choices.Count-i-1;
             *              break;
             *      }
             * }*/
            //Pick middle:
            //int idx = choices.Count/2;

            v   = choices[idx].Var;
            ass = choices[idx].Sign;

            DecisionLevel d = new DecisionLevel(solver.Decisions.Count);

            solver.DecisionLevel.Add(d);
            v.Assignment = ass;
            solver.Decisions.Add(v);
            v.Reason        = null;
            v.DecisionLevel = d;

            return(v);
        }
예제 #5
0
        //Stripped down method for simpler testing
        public double[] SolveTest(AD.Term equation, AD.Variable[] args, double[,] limits)
        {
            lastSeed             = null;
            probeCount           = 0;
            successProbeCount    = 0;
            intervalCount        = 0;
            successIntervalCount = 0;
            fevalsCount          = 0;
            runCount             = 0;

            //this.FEvals = 0;
            double util = 0;

            this.begin = RosCS.RosSharp.Now();
#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();



            ss = new CNSAT.CNSat();

            ss.UseIntervalProp = this.UseIntervalProp;
            //Console.WriteLine(cu.Constraint);
            LinkedList <CNSAT.Clause> cnf = ft.TransformToCNF(equation, 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++;
             * }*/


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


            solutionFound = ss.solve();
            //Console.WriteLine("Solution Found!!!!!");

            if (!solutionFound && r1.finalUtil > 0)
            {
                r1.finalUtil = -1;
            }
            util = r1.finalUtil;
            //if(util>this.utilitySignificanceThreshold) return r1.finalValue;
            return(r1.finalValue);
        }
예제 #6
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);
        }