Skip to content

Commit

Permalink
CSP application parameters improved (now forward checking supported).
Browse files Browse the repository at this point in the history
  • Loading branch information
RuedigerLunde committed Apr 27, 2017
1 parent ec79166 commit 605ac1e
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import aima.core.util.datastructure.Pair;

public class ImprovedBacktrackingStrategy extends BacktrackingStrategy {
protected Selection selectionStrategy = Selection.DEFAULT_ORDER;
protected Selection selectionStrategy = Selection.DEFAULT;
protected Inference inferenceStrategy = Inference.NONE;
protected boolean isLCVHeuristicEnabled;

Expand All @@ -20,28 +20,31 @@ public ImprovedBacktrackingStrategy() {
public ImprovedBacktrackingStrategy(boolean enableMRV, boolean enableDeg,
boolean enableAC3, boolean enableLCV) {
if (enableMRV)
setVariableSelection(enableDeg ? Selection.MRV_DEG : Selection.MRV);
set(enableDeg ? Selection.MRV_DEG : Selection.MRV);
if (enableAC3)
setInference(Inference.AC3);
set(Inference.AC3);
enableLCV(enableLCV);
}

/** Selects the algorithm for SELECT-UNASSIGNED-VARIABLE */
public void setVariableSelection(Selection sStrategy) {
public ImprovedBacktrackingStrategy set(Selection sStrategy) {
selectionStrategy = sStrategy;
return this;
}

/** Selects the algorithm for INFERENCE. */
public void setInference(Inference iStrategy) {
public ImprovedBacktrackingStrategy set(Inference iStrategy) {
inferenceStrategy = iStrategy;
return this;
}

/**
* Selects the least constraining value heuristic as implementation for
* ORDER-DOMAIN-VALUES.
*/
public void enableLCV(boolean state) {
public ImprovedBacktrackingStrategy enableLCV(boolean state) {
isLCVHeuristicEnabled = state;
return this;
}

/**
Expand Down Expand Up @@ -247,7 +250,7 @@ private boolean revise(Variable var, Constraint constraint,
// two enumerations

public enum Selection {
DEFAULT_ORDER, MRV, MRV_DEG
DEFAULT, MRV, MRV_DEG
}

public enum Inference {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,19 @@ public void initialize() {
break;
case 2: // FC
iStrategy = new ImprovedBacktrackingStrategy();
iStrategy.setInference(ImprovedBacktrackingStrategy
iStrategy.set(ImprovedBacktrackingStrategy
.Inference.FORWARD_CHECKING);
break;
case 3: // MRV + FC
iStrategy = new ImprovedBacktrackingStrategy
(true, false, false, false);
iStrategy.setInference(ImprovedBacktrackingStrategy
iStrategy.set(ImprovedBacktrackingStrategy
.Inference.FORWARD_CHECKING);
break;
case 4: // FC + LCV
iStrategy = new ImprovedBacktrackingStrategy
(false, false, false, true);
iStrategy.setInference(ImprovedBacktrackingStrategy
iStrategy.set(ImprovedBacktrackingStrategy
.Inference.FORWARD_CHECKING);
break;
case 5: // AC3
Expand Down
298 changes: 153 additions & 145 deletions aima-gui/src/main/java/aima/gui/fx/applications/search/CspNQueensApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,152 +29,160 @@
* strategies solve the N-Queens problem.
*
* @author Ruediger Lunde
*
*/
public class CspNQueensApp extends IntegrableApplication {

public static void main(String[] args) {
launch(args);
}

public final static String PARAM_STRATEGY = "strategy";
public final static String PARAM_MRV = "mrv";
public final static String PARAM_DEG = "deg";
public final static String PARAM_AC3 = "ac3";
public final static String PARAM_LCV = "lcv";

public final static String PARAM_BOARD_SIZE = "boardSize";

private NQueensViewCtrl stateViewCtrl;
private SimulationPaneCtrl simPaneCtrl;
CSP csp;
SolutionStrategy solver;
ProgressAnalyzer progressAnalyzer = new ProgressAnalyzer();

@Override
public String getTitle() {
return "CSP N-Queens App";
}

/**
* Defines state view, parameters, and call-back functions and calls the
* simulation pane builder to create layout and controller objects.
*/
@Override
public Pane createRootPane() {
BorderPane root = new BorderPane();

StackPane stateView = new StackPane();
stateViewCtrl = new NQueensViewCtrl(stateView);

List<Parameter> params = createParameters();

SimulationPaneBuilder builder = new SimulationPaneBuilder();
builder.defineParameters(params);
builder.defineStateView(stateView);
builder.defineInitMethod(this::initialize);
builder.defineSimMethod(this::simulate);
simPaneCtrl = builder.getResultFor(root);
simPaneCtrl.setParam(SimulationPaneCtrl.PARAM_SIM_SPEED, 0);

return root;
}

protected List<Parameter> createParameters() {
Parameter p1 = new Parameter(PARAM_STRATEGY, "Min-Conflicts", "Backtracking");
Parameter p2 = new Parameter(PARAM_MRV, true, false);
Parameter p3 = new Parameter(PARAM_DEG, true, false);
Parameter p4 = new Parameter(PARAM_AC3, true, false);
Parameter p5 = new Parameter(PARAM_LCV, true, false);
p2.setDependency(PARAM_STRATEGY, "Backtracking");
p3.setDependency(PARAM_STRATEGY, "Backtracking");
p4.setDependency(PARAM_STRATEGY, "Backtracking");
p5.setDependency(PARAM_STRATEGY, "Backtracking");
Parameter p6 = new Parameter(PARAM_BOARD_SIZE, 4, 8, 16, 32, 64);
p6.setDefaultValueIndex(1);
return Arrays.asList(p1, p2, p3, p4, p5, p6);
}

/** Displays the initialized board on the state view. */
@Override
public void initialize() {
csp = new NQueensCSP(simPaneCtrl.getParamAsInt(PARAM_BOARD_SIZE));
Object strategy = simPaneCtrl.getParamValue(PARAM_STRATEGY);
if (strategy.equals("Min-Conflicts"))
solver = new MinConflictsStrategy(1000);
else if (strategy.equals("Backtracking")) {
boolean mrv = (Boolean) simPaneCtrl.getParamValue(PARAM_MRV);
boolean deg = (Boolean) simPaneCtrl.getParamValue(PARAM_DEG);
boolean ac3 = (Boolean) simPaneCtrl.getParamValue(PARAM_AC3);
boolean lcv = (Boolean) simPaneCtrl.getParamValue(PARAM_LCV);
solver = new ImprovedBacktrackingStrategy(mrv, deg, ac3, lcv);
}
solver.addCSPStateListener(progressAnalyzer);
progressAnalyzer.reset();
stateViewCtrl.update(new NQueensBoard(csp.getVariables().size()));
simPaneCtrl.setStatus("");
}

@Override
public void finalize() {
simPaneCtrl.cancelSimulation();
}

/** Starts the experiment. */
public void simulate() {
Assignment solution = solver.solve(csp);
if (solution != null) {
NQueensBoard board = getBoard(solution);
stateViewCtrl.update(board);
}
simPaneCtrl.setStatus(progressAnalyzer.getResults().toString());
}

private NQueensBoard getBoard(Assignment assignment) {
NQueensBoard board = new NQueensBoard(csp.getVariables().size());
for (Variable var : assignment.getVariables()) {
int col = Integer.parseInt(var.getName().substring(1)) - 1;
int row = ((int) assignment.getAssignment(var)) - 1;
board.addQueenAt(new XYLocation(col, row));
}
return board;
}

/**
* Caution: While the background thread should be slowed down, updates of
* the GUI have to be done in the GUI thread!
*/
private void updateStateView(NQueensBoard board) {
Platform.runLater(() -> stateViewCtrl.update(board));
simPaneCtrl.waitAfterStep();
}

protected class ProgressAnalyzer implements CSPStateListener {
private int assignmentCount = 0;
private int domainCount = 0;

@Override
public void stateChanged(Assignment assignment, CSP csp) {
updateStateView(getBoard(assignment));
++assignmentCount;
}

@Override
public void stateChanged(CSP csp) {
++domainCount;
}

public void reset() {
assignmentCount = 0;
domainCount = 0;
}

public Metrics getResults() {
Metrics result = new Metrics();
result.set("assignmentChanges", assignmentCount);
if (domainCount != 0)
result.set("domainChanges", domainCount);
return result;
}
}
public static void main(String[] args) {
launch(args);
}

public final static String PARAM_STRATEGY = "strategy";
public final static String PARAM_VAR_SELECT = "varSelect";
public final static String PARAM_VAL_ORDER = "valOrder";
public final static String PARAM_INFERENCE = "inference";

public final static String PARAM_BOARD_SIZE = "boardSize";

private NQueensViewCtrl stateViewCtrl;
private SimulationPaneCtrl simPaneCtrl;
CSP csp;
SolutionStrategy solver;
ProgressAnalyzer progressAnalyzer = new ProgressAnalyzer();

@Override
public String getTitle() {
return "CSP N-Queens App";
}

/**
* Defines state view, parameters, and call-back functions and calls the
* simulation pane builder to create layout and controller objects.
*/
@Override
public Pane createRootPane() {
BorderPane root = new BorderPane();

StackPane stateView = new StackPane();
stateViewCtrl = new NQueensViewCtrl(stateView);

List<Parameter> params = createParameters();

SimulationPaneBuilder builder = new SimulationPaneBuilder();
builder.defineParameters(params);
builder.defineStateView(stateView);
builder.defineInitMethod(this::initialize);
builder.defineSimMethod(this::simulate);
simPaneCtrl = builder.getResultFor(root);
simPaneCtrl.setParam(SimulationPaneCtrl.PARAM_SIM_SPEED, 0);

return root;
}

protected List<Parameter> createParameters() {
Parameter p1 = new Parameter(PARAM_STRATEGY, "Min-Conflicts", "Backtracking");
Parameter p2 = new Parameter(PARAM_VAR_SELECT,
ImprovedBacktrackingStrategy.Selection.DEFAULT,
ImprovedBacktrackingStrategy.Selection.MRV,
ImprovedBacktrackingStrategy.Selection.MRV_DEG);
Parameter p3 = new Parameter(PARAM_VAL_ORDER, "DEFAULT", "LCV");
Parameter p4 = new Parameter(PARAM_INFERENCE,
ImprovedBacktrackingStrategy.Inference.NONE,
ImprovedBacktrackingStrategy.Inference.FORWARD_CHECKING,
ImprovedBacktrackingStrategy.Inference.AC3);
p2.setDependency(PARAM_STRATEGY, "Backtracking");
p3.setDependency(PARAM_STRATEGY, "Backtracking");
p4.setDependency(PARAM_STRATEGY, "Backtracking");
Parameter p5 = new Parameter(PARAM_BOARD_SIZE, 4, 8, 16, 32, 64);
p5.setDefaultValueIndex(1);
return Arrays.asList(p1, p2, p3, p4, p5);
}

/**
* Displays the initialized board on the state view.
*/
@Override
public void initialize() {
csp = new NQueensCSP(simPaneCtrl.getParamAsInt(PARAM_BOARD_SIZE));
Object strategy = simPaneCtrl.getParamValue(PARAM_STRATEGY);
if (strategy.equals("Min-Conflicts"))
solver = new MinConflictsStrategy(1000);
else if (strategy.equals("Backtracking")) {
ImprovedBacktrackingStrategy.Selection varSelect =
(ImprovedBacktrackingStrategy.Selection) simPaneCtrl.getParamValue(PARAM_VAR_SELECT);
ImprovedBacktrackingStrategy.Inference inference =
(ImprovedBacktrackingStrategy.Inference) simPaneCtrl.getParamValue(PARAM_INFERENCE);
String valOrder = (String) simPaneCtrl.getParamValue(PARAM_VAL_ORDER);
solver = new ImprovedBacktrackingStrategy().set(varSelect).set(inference).enableLCV(valOrder.equals("LCV"));

}
solver.addCSPStateListener(progressAnalyzer);
progressAnalyzer.reset();
stateViewCtrl.update(new NQueensBoard(csp.getVariables().size()));
simPaneCtrl.setStatus("");
}

@Override
public void finalize() {
simPaneCtrl.cancelSimulation();
}

/**
* Starts the experiment.
*/
public void simulate() {
Assignment solution = solver.solve(csp);
if (solution != null) {
NQueensBoard board = getBoard(solution);
stateViewCtrl.update(board);
}
simPaneCtrl.setStatus(progressAnalyzer.getResults().toString());
}

private NQueensBoard getBoard(Assignment assignment) {
NQueensBoard board = new NQueensBoard(csp.getVariables().size());
for (Variable var : assignment.getVariables()) {
int col = Integer.parseInt(var.getName().substring(1)) - 1;
int row = ((int) assignment.getAssignment(var)) - 1;
board.addQueenAt(new XYLocation(col, row));
}
return board;
}

/**
* Caution: While the background thread should be slowed down, updates of
* the GUI have to be done in the GUI thread!
*/
private void updateStateView(NQueensBoard board) {
Platform.runLater(() -> stateViewCtrl.update(board));
simPaneCtrl.waitAfterStep();
}

protected class ProgressAnalyzer implements CSPStateListener {
private int assignmentCount = 0;
private int domainCount = 0;

@Override
public void stateChanged(Assignment assignment, CSP csp) {
updateStateView(getBoard(assignment));
++assignmentCount;
}

@Override
public void stateChanged(CSP csp) {
++domainCount;
}

public void reset() {
assignmentCount = 0;
domainCount = 0;
}

public Metrics getResults() {
Metrics result = new Metrics();
result.set("assignmentChanges", assignmentCount);
if (domainCount != 0)
result.set("domainChanges", domainCount);
return result;
}
}
}
Loading

0 comments on commit 605ac1e

Please sign in to comment.