///<summary> /// transit prop appears as a negative literal in clause from true -> false, /// OR prop appears as a positive literal in clause from false -> true /// </summary> public override void UpdateTrueNegativeAndFalsePositive(BooleanSolver b) { if (b.TrueDisjunctCount[Index] == 0) { // We just satisfied it b.UnsatisfiedClauses.Remove(Index); } b.TrueDisjunctCount[Index]++; }
///<summary> /// transit prop appears as a negative literal in clause from false -> true, /// OR prop appears as a positive literal in clause from true -> false /// </summary> public override void UpdateTruePositiveAndFalseNegative(BooleanSolver b) { var dCount = --b.TrueDisjunctCount[Index]; if (dCount == 0) { // It just transitioned from satisfied to unsatisfied b.UnsatisfiedClauses.Add(Index); } }
///<summary> /// transit prop appears as a negative literal in clause from true -> false, /// OR prop appears as a positive literal in clause from false -> true /// </summary> public override void UpdateTrueNegativeAndFalsePositive(BooleanSolver b) { var dCount = b.TrueDisjunctCount[Index]++; if (OneTooFewDisjuncts(dCount)) { // We just satisfied it b.UnsatisfiedClauses.Remove(Index); } else if (OneTooManyDisjuncts((ushort)(dCount + 1))) { // It just transitioned from satisfied to unsatisfied b.UnsatisfiedClauses.Add(Index); } }
///<summary> /// transit prop appears as a negative literal in clause from true -> false, /// OR prop appears as a positive literal in clause from false -> true /// </summary> public override void UpdateTrueNegativeAndFalsePositive(BooleanSolver b) { var dCount = ++b.TrueDisjunctCount[Index]; var isEnabled = IsEnabled(b.Solution); if (b.UnsatisfiedClauses.Contains(Index)) { if (OneTooFewDisjuncts((ushort)(dCount - 1)) || !isEnabled) { // We just satisfied it or it was disabled b.UnsatisfiedClauses.Remove(Index); } } // I think this needs to be !IsSatisfied rather than OneTooManyDisjuncts to handle // the case where the clause becomes enabled while it's satisfied by not at OneTooManyDisjuncts. else if (!IsSatisfied(dCount) && isEnabled) { // It just transitioned from satisfied to unsatisfied, or condition just enabled b.UnsatisfiedClauses.Add(Index); } }
/// <summary> /// Find the proposition from the specified clause that will do the least damage to the clauses that are already satisfied. /// </summary> /// <param name="b">Current BooleanSolver</param> /// <returns>Index of the prop to flip</returns> public ushort GreedyFlip(BooleanSolver b) { // If true, the clause has too few disjuncts true bool increaseTrueDisjuncts = IsNormalDisjunction ? b.TrueDisjunctCount[Index] <= 0 : b.TrueDisjunctCount[Index] <= MinDisjunctsMinusOne; //Signed indices of the disjuncts of the clause List <short> disjuncts = UnPredeterminedDisjuncts; //Variable that was last chosen for flipping in this clause ushort lastFlipOfThisClause = b.LastFlip[Index]; var bestCount = int.MaxValue; var best = 0; //Walk disjuncts in a reasonably random order var dCount = (uint)disjuncts.Count; var index = Random.InRange(dCount); uint prime; do { prime = Random.Prime(); } while (prime <= dCount); for (var i = 0; i < dCount; i++) { var value = disjuncts[(int)index]; index = (index + prime) % dCount; var selectedVar = (ushort)Math.Abs(value); var truth = b.Propositions[selectedVar]; if (value < 0) { truth = !truth; } if (truth == increaseTrueDisjuncts) { // This is already the right polarity continue; } if (selectedVar == lastFlipOfThisClause) { continue; } var threatCount = b.UnsatisfiedClauseDelta(selectedVar); if (threatCount <= 0) { // Fast path - we've found an improvement; take it // Real WalkSAT would continue searching for the best possible choice, but this // gives better performance in my tests // TODO - see if a faster way of computing ThreatenedClauseCount would improve things. return(selectedVar); } if (threatCount < bestCount) { best = selectedVar; bestCount = threatCount; } } if (best == 0) { return((ushort)Math.Abs(disjuncts.RandomElement())); } return((ushort)best); }
///<summary> /// transit prop appears as a negative literal in clause from true -> false, /// OR prop appears as a positive literal in clause from false -> true /// </summary> public abstract void UpdateTrueNegativeAndFalsePositive(BooleanSolver b);