internal BooleanSolver(Problem problem) { Problem = problem; var clausesCount = problem.Constraints.Count; TrueDisjunctCount = new ushort[clausesCount]; LastFlip = new ushort[clausesCount]; UnsatisfiedClauses = new DynamicUShortSet(clausesCount); falseLiterals = new ushort[Problem.Constraints.Count]; trueLiterals = new ushort[Problem.Constraints.Count]; }
/// <summary> /// Randomly assign values to the propositions, /// propagate through the initialization, /// and initialize the other state information accordingly. /// </summary> private void MakeRandomAssignment() { if (varInitialized == null || varInitialized.Length != Problem.SATVariables.Count) { varInitialized = new bool[Problem.SATVariables.Count]; improvablePropositions = new DynamicUShortSet(Problem.SATVariables.Count); } Array.Clear(falseLiterals, 0, falseLiterals.Length); Array.Clear(trueLiterals, 0, trueLiterals.Length); Array.Clear(varInitialized, 0, varInitialized.Length); totalUtility = 0; improvablePropositions.Clear(); var vars = Problem.SATVariables; // // Set indices to a randomly permuted series of 1 .. Propositions.Length - 1 // This gives us a random order in which to initialize the variables // var indices = new ushort[Propositions.Length - 1]; for (var i = 0; i < indices.Length; i++) { indices[i] = (ushort)(i + 1); } // Fisher-Yates shuffle algorithm (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) var lastIndex = indices.Length - 1; for (var i = 0; i < indices.Length - 2; i++) { var swapWith = Random.InRange(i, lastIndex); var temp = indices[i]; indices[i] = indices[swapWith]; indices[swapWith] = temp; } foreach (var i in indices) { if (!varInitialized[i]) { var satVar = vars[i]; var truth = satVar.IsPredetermined ? satVar.PredeterminedValue : satVar.RandomInitialState; // Skip the propagation if user specified if (!Problem.PropagateConstraintsDuringInitialization) { Propositions[i] = truth; UpdateUtility(i); } else { PropagateConstraints(i, truth); } } } foreach (var targetClause in Problem.Constraints) { // Make sure we don't change the predetermined propositions targetClause.UnPredeterminedDisjuncts.Clear(); foreach (short lit in targetClause.Disjuncts) { if (!Problem.SATVariables[(ushort)Math.Abs(lit)].IsPredetermined) { targetClause.UnPredeterminedDisjuncts.Add(lit); } } } UnsatisfiedClauses.Clear(); // Initialize trueDisjunctCount[] and unsatisfiedClauses for (ushort i = 0; i < TrueDisjunctCount.Length; i++) { var c = Problem.Constraints[i]; var satisfiedDisjuncts = c.CountDisjuncts(Solution); TrueDisjunctCount[i] = satisfiedDisjuncts; if (!c.IsSatisfied(satisfiedDisjuncts) && c.IsEnabled(Solution)) { if (c.UnPredeterminedDisjuncts.Count == 0) { // It's false, but all the disjuncts are predetermined throw new ContradictionException(Problem, c); } UnsatisfiedClauses.Add(i); } } //CheckUtility(); }