예제 #1
0
        public void backTrack(DecisionLevel db)
        {
            //TODO make this more efficient (linked list?)
            recentBacktrack = true;
            int ndbidx = decisionLevel.IndexOf(db) + 1;

            if (ndbidx >= decisionLevel.Count)
            {
                return;
            }
            db = decisionLevel[ndbidx];
            for (int j = db.Level; j < decisions.Count; j++)
            {
                decisions[j].Assignment = Assignment.Unassigned;
                decisions[j].Reason     = null;
                //this is expensive
                foreach (Watcher wa in decisions[j].WatchList)
                {
                    wa.Clause.Satisfied = wa.Clause.watcher[0].Lit.Satisfied() || wa.Clause.watcher[1].Lit.Satisfied();
                    //wa.Clause.Satisfied = false; //this should take other watcher into account
                }
            }
            decisions.RemoveRange(db.Level, decisions.Count - db.Level);

            //int i = decisionLevel.IndexOf(db);
            int i = ndbidx;

            i = Math.Max(1, i);
            decisionLevel.RemoveRange(i, decisionLevel.Count - i);
        }
예제 #2
0
 public CNSat()
 {
     UseIntervalProp   = true;
     this.CNSMTGSolver = null;
     decisionLevelNull = new DecisionLevel(0);
     UnitDecissions    = 0;
     r = new Random();
 }
예제 #3
0
 protected bool AssignmentInsideRange(DecisionLevel dl, double[,] range)
 {
     for (int i = dl.Level; i < decisions.Count; i++)
     {
         if (!VarAssignmentInsideRange(decisions[i], range))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
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);
        }
예제 #7
0
        public bool solve()
        {
            int restartNum = 100;

            learntNum           = 700;
            restartCount        = 0;
            double[,] curRanges = null;
            double[]      solution    = null;
            DecisionLevel evaluatedDL = null;
            //check: is already undecisdable?

            Clause c;

            while (true)
            {
                c = null;
                while ((c = propagate()) != null)                  //resolve all conflicts
                {
                    if (decisionLevel.Count == 1)
                    {
                        return(false);
                    }
                    if (conflictCount % 50 == 0 && CNSMTGSolver != null && CNSMTGSolver.begin + CNSMTGSolver.maxSolveTime < RosCS.RosSharp.Now())
                    {
                        return(false);
                    }
                    if (!resolveConflict(c))
                    {
                        return(false);
                    }
                }

                if (CNSMTGSolver != null)
                {
                    //check for conflict of Theoremprover
                    if (UseIntervalProp && !CNSMTGSolver.IntervalPropagate(decisions, out curRanges))
                    {
                        continue;
                    }
                    else
                    {
                        /*
                         * //TODO: Heuristic Decision whether or not to query the T-solver
                         * //comes in here
                         * //double satRatio = ((double)satClauseCount) / clauses.Count;
                         * //double varRatio = ((double)decisions.Count) / variables.Count;
                         * //if (recentBacktrack || varRatio < r.NextDouble()) { //|| satRatio > r.NextDouble()) {
                         * //if (recentBacktrack || satRatio > r.NextDouble()) {
                         * //if (decisionCount % 10 == 0) {
                         * //	recentBacktrack = false;
                         * //if(solution==null || !SolutionInsideRange(solution, curRanges)) {
                         * //if(!VarAssignmentInsideRange(Decisions[Decisions.Count-1],curRanges)) {
                         * //if(evaluatedDL==null || !AssignmentInsideRange(evaluatedDL, curRanges)) {
                         *      if (!CNSMTGSolver.ProbeForSolution(decisions, out solution)) {
                         *              continue;
                         *      }
                         * //	evaluatedDL = DecisionLevel[DecisionLevel.Count-1];
                         * //}
                         * //}
                         */
                        if (!CNSMTGSolver.ProbeForSolution(decisions, out solution))
                        {
                            continue;
                        }
                        int satClauseCount = 0;
                        for (int i = clauses.Count - 1; i >= 0; --i)
                        {
                            if (clauses[i].Satisfied)
                            {
                                satClauseCount++;
                            }
                        }
                        if (satClauseCount >= clauses.Count)
                        {
                            return(true);
                        }
                    }
                }
                Var next;
                //Make a decission:
                //Var next = Decider.DecideRangeBased(variables,this);
                if (CNSMTGSolver != null)
                {
                    next = Decider.DecideVariableCountBased(variables, this);
                }
                else
                {
                    next = Decider.DecideActivityBased(variables, this);
                }
                //Var next = decideRangeBased();
                //Var next = decide();
                if (next == null)                // if no unassigned vars
                {
                    Console.WriteLine("ConflictCount: " + conflictCount + " DecisionCount " + decisionCount + " LC " + this.learnedCount);
                    return(true);
                }
#if (CNSatDebug)
                Console.Write("Decision: ");
                next.Print();
                Console.WriteLine();
#endif
                ++decisionCount;
                //if(decisionCount%10000==0) PrintStatistics();
                if (decisionCount % 25 == 0 && CNSMTGSolver != null && CNSMTGSolver.begin + CNSMTGSolver.maxSolveTime < RosCS.RosSharp.Now())
                {
                    return(false);
                }
                //Forget unused clauses
                if (decisionCount % 1000 == 0)
                {
                    reduceDB(learntNum);
                    foreach (Var v in variables)
                    {
                        v.Activity /= 4;
                    }
                }


                if (false && decisionCount % restartNum == 0)
                {
                    //perform restart
                    restartNum *= 2;
                    learntNum  += learntNum / 10;
                    restartCount++;
                    for (int j = (decisionLevel[1].Level); j < decisions.Count; j++)
                    {
                        decisions[j].Assignment = Assignment.Unassigned;
                        decisions[j].Reason     = null;
                        //decisions[j].Seen = false;
                        foreach (Watcher wa in decisions[j].WatchList)
                        {
                            wa.Clause.Satisfied = false;
                        }
                    }
                    decisions.RemoveRange(decisionLevel[1].Level, decisions.Count - (decisionLevel[1].Level));

                    decisionLevel.RemoveRange(1, decisionLevel.Count - 1);
                }
            }
        }