All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aima.core.logic.propositional.inference.WalkSAT Maven / Gradle / Ivy

Go to download

AIMA-Java Core Algorithms from the book Artificial Intelligence a Modern Approach 3rd Ed.

The newest version!
package aima.core.logic.propositional.inference;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import aima.core.logic.propositional.kb.data.Clause;
import aima.core.logic.propositional.kb.data.Model;
import aima.core.logic.propositional.parsing.ast.PropositionSymbol;

/**
 * Artificial Intelligence A Modern Approach (3rd Edition): page 263.
*
* *
 * 
 * function WALKSAT(clauses, p, max_flips) returns a satisfying model or failure
 *   inputs: clauses, a set of clauses in propositional logic
 *           p, the probability of choosing to do a "random walk" move, typically around 0.5
 *           max_flips, number of flips allowed before giving up
 *           
 *   model <- a random assignment of true/false to the symbols in clauses
 *   for i = 1 to max_flips do
 *       if model satisfies clauses then return model
 *       clause <- a randomly selected clause from clauses that is false in model
 *       with probability p flip the value in model of a randomly selected symbol from clause
 *       else flip whichever symbol in clause maximizes the number of satisfied clauses
 *   return failure
 * 
 * 
* * Figure 7.18 The WALKSAT algorithm for checking satisfiability by randomly * flipping the values of variables. Many versions of the algorithm exist. * * @author Ciaran O'Reilly * @author Ravi Mohan * @author Mike Stampone */ public class WalkSAT { /** * WALKSAT(clauses, p, max_flips)
* * @param clauses * a set of clauses in propositional logic * @param p * the probability of choosing to do a "random walk" move, * typically around 0.5 * @param maxFlips * number of flips allowed before giving up. Note: a value < 0 is * interpreted as infinity. * * @return a satisfying model or failure (null). */ public Model walkSAT(Set clauses, double p, int maxFlips) { assertLegalProbability(p); // model <- a random assignment of true/false to the symbols in clauses Model model = randomAssignmentToSymbolsInClauses(clauses); // for i = 1 to max_flips do (Note: maxFlips < 0 means infinity) for (int i = 0; i < maxFlips || maxFlips < 0; i++) { // if model satisfies clauses then return model if (model.satisfies(clauses)) { return model; } // clause <- a randomly selected clause from clauses that is false // in model Clause clause = randomlySelectFalseClause(clauses, model); // with probability p flip the value in model of a randomly selected // symbol from clause if (random.nextDouble() < p) { model = model.flip(randomlySelectSymbolFromClause(clause)); } else { // else flip whichever symbol in clause maximizes the number of // satisfied clauses model = flipSymbolInClauseMaximizesNumberSatisfiedClauses( clause, clauses, model); } } // return failure return null; } // // SUPPORTING CODE // private Random random = new Random(); /** * Default Constructor. */ public WalkSAT() { } /** * Constructor. * * @param random * the random generator to be used by the algorithm. */ public WalkSAT(Random random) { this.random = random; } // // PROTECTED // protected void assertLegalProbability(double p) { if (p < 0 || p > 1) { throw new IllegalArgumentException("p is not a legal propbability value [0-1]: "+p); } } protected Model randomAssignmentToSymbolsInClauses(Set clauses) { // Collect the symbols in clauses Set symbols = new LinkedHashSet(); for (Clause c : clauses) { symbols.addAll(c.getSymbols()); } // Make initial set of assignments Map values = new HashMap(); for (PropositionSymbol symbol : symbols) { // a random assignment of true/false to the symbols in clauses values.put(symbol, random.nextBoolean()); } Model result = new Model(values); return result; } protected Clause randomlySelectFalseClause(Set clauses, Model model) { // Collect the clauses that are false in the model List falseClauses = new ArrayList(); for (Clause c : clauses) { if (Boolean.FALSE.equals(model.determineValue(c))) { falseClauses.add(c); } } // a randomly selected clause from clauses that is false Clause result = falseClauses.get(random.nextInt(falseClauses.size())); return result; } protected PropositionSymbol randomlySelectSymbolFromClause(Clause clause) { // all the symbols in clause Set symbols = clause.getSymbols(); // a randomly selected symbol from clause PropositionSymbol result = (new ArrayList(symbols)) .get(random.nextInt(symbols.size())); return result; } protected Model flipSymbolInClauseMaximizesNumberSatisfiedClauses( Clause clause, Set clauses, Model model) { Model result = model; // all the symbols in clause Set symbols = clause.getSymbols(); int maxClausesSatisfied = -1; for (PropositionSymbol symbol : symbols) { Model flippedModel = result.flip(symbol); int numberClausesSatisfied = 0; for (Clause c : clauses) { if (Boolean.TRUE.equals(flippedModel.determineValue(c))) { numberClausesSatisfied++; } } // test if this symbol flip is the new maximum if (numberClausesSatisfied > maxClausesSatisfied) { result = flippedModel; maxClausesSatisfied = numberClausesSatisfied; if (numberClausesSatisfied == clauses.size()) { // i.e. satisfies all clauses break; // this is our goal. } } } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy