Exemple #1
0
        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];
        }
Exemple #2
0
        /// <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();
        }