Esempio n. 1
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();
        }
Esempio n. 2
0
        /// <summary>
        /// Flip the variable at the specified index.
        /// </summary>
        /// <param name="pIndex">Index of the variable/proposition to flip</param>
        private void Flip(ushort pIndex)
        {
            var prop = Problem.SATVariables[pIndex];

            Debug.Assert(!prop.IsPredetermined, "The prop is predetermined, can't flip it.");
            var currentlyTrue = Propositions[pIndex];
            var utility       = prop.Proposition.Utility;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (utility != 0)
            {
                if (utility < 0 ^ currentlyTrue)
                {
                    // This flip lowers utility
                    improvablePropositions.Add(pIndex);
                }
                else
                {
                    // This flip increases utility
                    improvablePropositions.Remove(pIndex);
                }
            }

            {
                if (currentlyTrue)
                {
                    // Flip true -> false
                    Propositions[pIndex] = false;
                    totalUtility        -= Problem.SATVariables[pIndex].Proposition.Utility;

                    // Update the clauses in which this appears as a positive literal
                    foreach (ushort cIndex in prop.PositiveClauses)
                    {
                        // prop appears as a positive literal in clause.
                        // We just made it false, so clause now has fewer satisfied disjuncts.
                        var clause = Problem.Constraints[cIndex];
                        clause.UpdateTruePositiveAndFalseNegative(this);
                    }

                    // Update the clauses in which this appears as a negative literal
                    foreach (ushort cIndex in prop.NegativeClauses)
                    {
                        // prop appears as a negative literal in clause.
                        // We just made it false, so clause now has more satisfied disjuncts.
                        var clause = Problem.Constraints[cIndex];
                        clause.UpdateTrueNegativeAndFalsePositive(this);
                    }
                }
                else
                {
                    // Flip false -> true
                    Propositions[pIndex] = true;
                    totalUtility        += Problem.SATVariables[pIndex].Proposition.Utility;

                    // Update the clauses in which this appears as a positive literal
                    foreach (ushort cIndex in prop.PositiveClauses)
                    {
                        // prop appears as a positive literal in clause.
                        // We just made it true, so clause now has more satisfied disjuncts.
                        var clause = Problem.Constraints[cIndex];
                        clause.UpdateTrueNegativeAndFalsePositive(this);
                    }

                    // Update the clauses in which this appears as a negative literal
                    foreach (ushort cIndex in prop.NegativeClauses)
                    {
                        // prop appears as a negative literal in clause.
                        // We just made it true, so clause now has fewer satisfied disjuncts.
                        var clause = Problem.Constraints[cIndex];
                        clause.UpdateTruePositiveAndFalseNegative(this);
                    }
                }
            }
            //CheckUtility();
        }