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); }
public CNSat() { UseIntervalProp = true; this.CNSMTGSolver = null; decisionLevelNull = new DecisionLevel(0); UnitDecissions = 0; r = new Random(); }
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); }
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); }
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); }
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); }
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); } } }