Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ef18bb8
commit 46a08cf
Showing
10 changed files
with
1,337 additions
and
1,355 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
270 changes: 136 additions & 134 deletions
270
aima-gui/src/main/java/aima/gui/fx/demo/search/local/GeneticMaximumFinderApp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,134 +1,136 @@ | ||
package aima.gui.fx.demo.search.local; | ||
|
||
import java.util.Collection; | ||
import java.util.Optional; | ||
import java.util.function.Function; | ||
|
||
import aima.core.search.local.Individual; | ||
import aima.gui.fx.framework.IntegrableApplication; | ||
import aima.gui.fx.framework.Parameter; | ||
import aima.gui.fx.framework.SimulationPaneBuilder; | ||
import aima.gui.fx.framework.SimulationPaneCtrl; | ||
import aima.gui.fx.views.FunctionPlotterCtrl; | ||
import javafx.application.Platform; | ||
import javafx.scene.canvas.Canvas; | ||
import javafx.scene.layout.BorderPane; | ||
import javafx.scene.layout.Pane; | ||
import javafx.scene.paint.Color; | ||
import javafx.scene.paint.Paint; | ||
|
||
|
||
/** | ||
* Demonstrates, how the genetic algorithm can be used, to find maximums in | ||
* mathematical functions. Different parameter settings can be tried out and | ||
* progress shown for each iteration. | ||
* | ||
* @author Ruediger Lunde | ||
*/ | ||
public class GeneticMaximumFinderApp extends IntegrableApplication { | ||
|
||
public static void main(String[] args) { | ||
launch(args); | ||
} | ||
|
||
public final static String PARAM_FUNC_SELECT = "funcSelect"; | ||
public final static String PARAM_MUT_PROB = "mutProb"; | ||
public final static String PARAM_POPULATION = "population"; | ||
public final static String PARAM_MAX_ITER = "maxIter"; | ||
|
||
protected FunctionPlotterCtrl funcPlotterCtrl; | ||
private SimulationPaneCtrl simPaneCtrl; | ||
private GeneticMaximumFinderProg experiment; | ||
|
||
@Override | ||
public String getTitle() { | ||
return "Genetic Maxium Finder 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(); | ||
|
||
Canvas canvas = new Canvas(); | ||
funcPlotterCtrl = new FunctionPlotterCtrl(canvas); | ||
funcPlotterCtrl.setLimits(Functions.minX, Functions.maxX, Functions.minY, Functions.maxY); | ||
Parameter[] params = createParameters(); | ||
|
||
SimulationPaneBuilder builder = new SimulationPaneBuilder(); | ||
builder.defineParameters(params); | ||
builder.defineStateView(canvas); | ||
builder.defineInitMethod(this::initialize); | ||
builder.defineSimMethod(this::simulate); | ||
simPaneCtrl = builder.getResultFor(root); | ||
|
||
return root; | ||
} | ||
|
||
protected Parameter[] createParameters() { | ||
Parameter p1 = new Parameter(PARAM_FUNC_SELECT); | ||
p1.setValues(Functions.f1, Functions.f2, Functions.f3); | ||
p1.setValueNames("f1", "f2", "f3"); | ||
Parameter p2 = new Parameter(PARAM_MUT_PROB, 0.0, 0.2, 0.5, 1.0); | ||
p2.setDefaultValueIndex(1); | ||
Parameter p3 = new Parameter(PARAM_POPULATION, 2, 10, 20, 100); | ||
p3.setDefaultValueIndex(2); | ||
Parameter p4 = new Parameter(PARAM_MAX_ITER, 100, 200, 400); | ||
p4.setDefaultValueIndex(0); | ||
return new Parameter[] {p1, p2, p3, p4}; | ||
} | ||
|
||
/** Displays the selected function on the state view. */ | ||
@Override | ||
public void initialize() { | ||
funcPlotterCtrl.setFunction((Function<Double, Double>) simPaneCtrl.getParamValue(PARAM_FUNC_SELECT)); | ||
} | ||
|
||
@Override | ||
public void finalize() { | ||
simPaneCtrl.cancelSimulation(); | ||
} | ||
|
||
/** Starts the experiment. */ | ||
public void simulate() { | ||
experiment = new GeneticMaximumFinderProg(); | ||
experiment.setFunction((Function<Double, Double>) simPaneCtrl.getParamValue(PARAM_FUNC_SELECT)); | ||
experiment.setMutationProb(simPaneCtrl.getParamAsDouble(PARAM_MUT_PROB)); | ||
experiment.setPopulationSize(simPaneCtrl.getParamAsInt(PARAM_POPULATION)); | ||
experiment.setMaxIterations(simPaneCtrl.getParamAsInt(PARAM_MAX_ITER)); | ||
experiment.startExperiment(this::updateStateView); | ||
} | ||
|
||
/** | ||
* Caution: While the background thread should be slowed down, updates of | ||
* the GUI have to be done in the GUI thread! | ||
*/ | ||
private void updateStateView(int itCount, Collection<Individual<Double>> gen) { | ||
Platform.runLater(() -> updateStateViewLater(itCount, gen)); | ||
simPaneCtrl.waitAfterStep(); | ||
} | ||
|
||
/** | ||
* Must be called by the GUI thread! | ||
*/ | ||
private void updateStateViewLater(int itCount, Collection<Individual<Double>> gen) { | ||
funcPlotterCtrl.update(); | ||
if (gen != null) { | ||
for (Individual<Double> ind : gen) { | ||
Optional<Paint> fill = Optional.empty(); | ||
if (ind.getDescendants() > 0) | ||
fill = Optional.of(Color.rgb(Math.max(255 - ind.getDescendants() * 20, 0), 0, 0)); | ||
else | ||
fill = Optional.of(Color.RED.brighter()); | ||
double x = ind.getRepresentation().get(0); | ||
funcPlotterCtrl.setMarker(x, fill); | ||
} | ||
simPaneCtrl.setStatus(experiment.getIterationInfo(itCount, gen)); | ||
} else { | ||
simPaneCtrl.setStatus(""); | ||
} | ||
} | ||
} | ||
package aima.gui.fx.demo.search.local; | ||
|
||
import java.util.Collection; | ||
import java.util.Optional; | ||
import java.util.function.Function; | ||
|
||
import aima.core.search.local.Individual; | ||
import aima.gui.fx.framework.IntegrableApplication; | ||
import aima.gui.fx.framework.Parameter; | ||
import aima.gui.fx.framework.SimulationPaneBuilder; | ||
import aima.gui.fx.framework.SimulationPaneCtrl; | ||
import aima.gui.fx.views.FunctionPlotterCtrl; | ||
import javafx.application.Platform; | ||
import javafx.scene.canvas.Canvas; | ||
import javafx.scene.layout.BorderPane; | ||
import javafx.scene.layout.Pane; | ||
import javafx.scene.paint.Color; | ||
import javafx.scene.paint.Paint; | ||
|
||
|
||
/** | ||
* Demonstrates, how the genetic algorithm can be used, to find maximums in | ||
* mathematical functions. Different parameter settings can be tried out and | ||
* progress shown for each iteration. | ||
* | ||
* @author Ruediger Lunde | ||
*/ | ||
public class GeneticMaximumFinderApp extends IntegrableApplication { | ||
|
||
public static void main(String[] args) { | ||
launch(args); | ||
} | ||
|
||
public final static String PARAM_FUNC_SELECT = "funcSelect"; | ||
public final static String PARAM_MUT_PROB = "mutProb"; | ||
public final static String PARAM_POPULATION = "population"; | ||
public final static String PARAM_MAX_ITER = "maxIter"; | ||
|
||
protected FunctionPlotterCtrl funcPlotterCtrl; | ||
private SimulationPaneCtrl simPaneCtrl; | ||
private GeneticMaximumFinderProg experiment; | ||
|
||
@Override | ||
public String getTitle() { | ||
return "Genetic Maxium Finder 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(); | ||
|
||
Canvas canvas = new Canvas(); | ||
funcPlotterCtrl = new FunctionPlotterCtrl(canvas); | ||
funcPlotterCtrl.setLimits(Functions.minX, Functions.maxX, Functions.minY, Functions.maxY); | ||
Parameter[] params = createParameters(); | ||
|
||
SimulationPaneBuilder builder = new SimulationPaneBuilder(); | ||
builder.defineParameters(params); | ||
builder.defineStateView(canvas); | ||
builder.defineInitMethod(this::initialize); | ||
builder.defineSimMethod(this::simulate); | ||
simPaneCtrl = builder.getResultFor(root); | ||
|
||
return root; | ||
} | ||
|
||
protected Parameter[] createParameters() { | ||
Parameter p1 = new Parameter(PARAM_FUNC_SELECT); | ||
p1.setValues(Functions.f1, Functions.f2, Functions.f3); | ||
p1.setValueNames("f1", "f2", "f3"); | ||
Parameter p2 = new Parameter(PARAM_MUT_PROB, 0.0, 0.2, 0.5, 1.0); | ||
p2.setDefaultValueIndex(1); | ||
Parameter p3 = new Parameter(PARAM_POPULATION, 2, 10, 20, 100); | ||
p3.setDefaultValueIndex(2); | ||
Parameter p4 = new Parameter(PARAM_MAX_ITER, 100, 200, 400); | ||
p4.setDefaultValueIndex(0); | ||
return new Parameter[] {p1, p2, p3, p4}; | ||
} | ||
|
||
/** Displays the selected function on the state view. */ | ||
@SuppressWarnings("unchecked") | ||
@Override | ||
public void initialize() { | ||
funcPlotterCtrl.setFunction((Function<Double, Double>) simPaneCtrl.getParamValue(PARAM_FUNC_SELECT)); | ||
} | ||
|
||
@Override | ||
public void finalize() { | ||
simPaneCtrl.cancelSimulation(); | ||
} | ||
|
||
/** Starts the experiment. */ | ||
@SuppressWarnings("unchecked") | ||
public void simulate() { | ||
experiment = new GeneticMaximumFinderProg(); | ||
experiment.setFunction((Function<Double, Double>) simPaneCtrl.getParamValue(PARAM_FUNC_SELECT)); | ||
experiment.setMutationProb(simPaneCtrl.getParamAsDouble(PARAM_MUT_PROB)); | ||
experiment.setPopulationSize(simPaneCtrl.getParamAsInt(PARAM_POPULATION)); | ||
experiment.setMaxIterations(simPaneCtrl.getParamAsInt(PARAM_MAX_ITER)); | ||
experiment.startExperiment(this::updateStateView); | ||
} | ||
|
||
/** | ||
* Caution: While the background thread should be slowed down, updates of | ||
* the GUI have to be done in the GUI thread! | ||
*/ | ||
private void updateStateView(int itCount, Collection<Individual<Double>> gen) { | ||
Platform.runLater(() -> updateStateViewLater(itCount, gen)); | ||
simPaneCtrl.waitAfterStep(); | ||
} | ||
|
||
/** | ||
* Must be called by the GUI thread! | ||
*/ | ||
private void updateStateViewLater(int itCount, Collection<Individual<Double>> gen) { | ||
funcPlotterCtrl.update(); | ||
if (gen != null) { | ||
for (Individual<Double> ind : gen) { | ||
Optional<Paint> fill = Optional.empty(); | ||
if (ind.getDescendants() > 0) | ||
fill = Optional.of(Color.rgb(Math.max(255 - ind.getDescendants() * 20, 0), 0, 0)); | ||
else | ||
fill = Optional.of(Color.RED.brighter()); | ||
double x = ind.getRepresentation().get(0); | ||
funcPlotterCtrl.setMarker(x, fill); | ||
} | ||
simPaneCtrl.setStatus(experiment.getIterationInfo(itCount, gen)); | ||
} else { | ||
simPaneCtrl.setStatus(""); | ||
} | ||
} | ||
} |
Oops, something went wrong.