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