Skip to content

Commit

Permalink
SearchDemoOsmAgenApp now supports bidirectional search.
Browse files Browse the repository at this point in the history
  • Loading branch information
ruediger.lunde@gmail.com committed Apr 21, 2016
1 parent 885ca83 commit 8cb4a09
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 64 deletions.
Expand Up @@ -2,31 +2,32 @@


import aima.core.search.framework.BidirectionalProblem; import aima.core.search.framework.BidirectionalProblem;
import aima.core.search.framework.DefaultGoalTest; import aima.core.search.framework.DefaultGoalTest;
import aima.core.search.framework.GoalTest;
import aima.core.search.framework.Problem; import aima.core.search.framework.Problem;


/** /**
* @author Ciaran O'Reilly * @author Ciaran O'Reilly
* *
*/ */
public class BidirectionalMapProblem extends Problem implements public class BidirectionalMapProblem extends Problem implements BidirectionalProblem {
BidirectionalProblem {


Map map; Map map;


Problem reverseProblem; Problem reverseProblem;


public BidirectionalMapProblem(Map map, String initialState, public BidirectionalMapProblem(Map map, String initialState, String goalState) {
String goalState) { this(map, initialState, goalState, new DefaultGoalTest(goalState));
super(initialState, MapFunctionFactory.getActionsFunction(map), }
MapFunctionFactory.getResultFunction(), new DefaultGoalTest(
goalState), new MapStepCostFunction(map)); public BidirectionalMapProblem(Map map, String initialState, String goalState, GoalTest goalTest) {
super(initialState, MapFunctionFactory.getActionsFunction(map), MapFunctionFactory.getResultFunction(),
goalTest, new MapStepCostFunction(map));


this.map = map; this.map = map;


reverseProblem = new Problem(goalState, reverseProblem = new Problem(goalState, MapFunctionFactory.getReverseActionsFunction(map),
MapFunctionFactory.getReverseActionsFunction(map), MapFunctionFactory.getResultFunction(), new DefaultGoalTest(initialState),
MapFunctionFactory.getResultFunction(), new DefaultGoalTest( new MapStepCostFunction(map));
initialState), new MapStepCostFunction(map));
} }


// //
Expand Down
26 changes: 12 additions & 14 deletions aima-core/src/main/java/aima/core/environment/map/MapAgent.java
Expand Up @@ -19,18 +19,16 @@
* *
*/ */
public class MapAgent extends SimpleProblemSolvingAgent { public class MapAgent extends SimpleProblemSolvingAgent {
private Map map = null;

private EnvironmentViewNotifier notifier = null;

private DynamicState state = new DynamicState();


protected Map map = null;
protected DynamicState state = new DynamicState();

private EnvironmentViewNotifier notifier = null;
private Search search = null; private Search search = null;

private String[] goals = null;
private String[] goalTests = null;

private int goalTestPos = 0; private int goalTestPos = 0;



public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search) { public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search) {
this.map = map; this.map = map;
this.notifier = notifier; this.notifier = notifier;
Expand All @@ -46,13 +44,13 @@ public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search,
} }


public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search, public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search,
String[] goalTests) { String[] goals) {
super(goalTests.length); super(goals.length);
this.map = map; this.map = map;
this.notifier = notifier; this.notifier = notifier;
this.search = search; this.search = search;
this.goalTests = new String[goalTests.length]; this.goals = new String[goals.length];
System.arraycopy(goalTests, 0, this.goalTests, 0, goalTests.length); System.arraycopy(goals, 0, this.goals, 0, goals.length);
} }


// //
Expand All @@ -71,10 +69,10 @@ protected State updateState(Percept p) {
@Override @Override
protected Object formulateGoal() { protected Object formulateGoal() {
Object goal = null; Object goal = null;
if (null == goalTests) { if (null == goals) {
goal = map.randomlyGenerateDestination(); goal = map.randomlyGenerateDestination();
} else { } else {
goal = goalTests[goalTestPos]; goal = goals[goalTestPos];
goalTestPos++; goalTestPos++;
} }
notifier.notifyViews("CurrentLocation=In(" notifier.notifyViews("CurrentLocation=In("
Expand Down
Expand Up @@ -16,6 +16,17 @@
*/ */
public class SearchUtils { public class SearchUtils {


public static interface NodeListener {
void onNodeExpanded(Node node);
}

/**
* All node listeners added to this list get informed whenever a node is
* expanded. This is for demonstration and debugging purposes only. Handle
* with care!
*/
public static List<NodeListener> nodeListeners = new ArrayList<NodeListener>();

/** /**
* Returns the children obtained from expanding the specified node in the * Returns the children obtained from expanding the specified node in the
* specified problem. * specified problem.
Expand All @@ -31,6 +42,9 @@ public class SearchUtils {
public static List<Node> expandNode(Node node, Problem problem) { public static List<Node> expandNode(Node node, Problem problem) {
List<Node> childNodes = new ArrayList<Node>(); List<Node> childNodes = new ArrayList<Node>();


for (NodeListener listener : nodeListeners)
listener.onNodeExpanded(node);

ActionsFunction actionsFunction = problem.getActionsFunction(); ActionsFunction actionsFunction = problem.getActionsFunction();
ResultFunction resultFunction = problem.getResultFunction(); ResultFunction resultFunction = problem.getResultFunction();
StepCostFunction stepCostFunction = problem.getStepCostFunction(); StepCostFunction stepCostFunction = problem.getStepCostFunction();
Expand Down
Expand Up @@ -6,11 +6,11 @@
import aima.core.agent.Agent; import aima.core.agent.Agent;
import aima.core.environment.map.BidirectionalMapProblem; import aima.core.environment.map.BidirectionalMapProblem;
import aima.core.environment.map.MapAgent; import aima.core.environment.map.MapAgent;
import aima.core.environment.map.MapEnvironment;
import aima.core.environment.map.MapFunctionFactory; import aima.core.environment.map.MapFunctionFactory;
import aima.core.search.framework.DefaultGoalTest; import aima.core.search.framework.Node;
import aima.core.search.framework.Problem; import aima.core.search.framework.Problem;
import aima.core.search.framework.Search; import aima.core.search.framework.SearchUtils;
import aima.core.search.framework.SearchUtils.NodeListener;
import aima.core.search.online.LRTAStarAgent; import aima.core.search.online.LRTAStarAgent;
import aima.core.search.online.OnlineSearchProblem; import aima.core.search.online.OnlineSearchProblem;
import aima.core.util.datastructure.Point2D; import aima.core.util.datastructure.Point2D;
Expand Down Expand Up @@ -90,6 +90,13 @@ private static class SDController extends OsmAgentController {
@Override @Override
public void prepare(String changedSelector) { public void prepare(String changedSelector) {
visitedStates.clear(); visitedStates.clear();
SearchUtils.nodeListeners.clear();
SearchUtils.nodeListeners.add(new NodeListener() {
@Override
public void onNodeExpanded(Node node) {
visitedStates.add(node.getState());
}
});
super.prepare(changedSelector); super.prepare(changedSelector);
} }


Expand All @@ -112,59 +119,29 @@ protected void initAgents(MessageLogger logger) {
MapAgentFrame.SelectionState state = frame.getSelection(); MapAgentFrame.SelectionState state = frame.getSelection();
switch (state.getIndex(MapAgentFrame.AGENT_SEL)) { switch (state.getIndex(MapAgentFrame.AGENT_SEL)) {
case 0: case 0:
agent = new SDMapAgent(env, search, new String[] { locs[1] }); agent = new MapAgent(map, env, search, new String[] { locs[1] });
break; break;
case 1: case 1:
Problem p = new BidirectionalMapProblem(map, null, locs[1]); Problem p = new BidirectionalMapProblem(map, null, locs[1]);
OnlineSearchProblem osp = new OnlineSearchProblem( OnlineSearchProblem osp = new OnlineSearchProblem(p.getActionsFunction(), p.getGoalTest(),
p.getActionsFunction(), p.getGoalTest(),
p.getStepCostFunction()); p.getStepCostFunction());
agent = new LRTAStarAgent(osp, agent = new LRTAStarAgent(osp, MapFunctionFactory.getPerceptToStateFunction(), heuristic);
MapFunctionFactory.getPerceptToStateFunction(),
heuristic);
break; break;
} }
env.addAgent(agent, locs[0]); env.addAgent(agent, locs[0]);
} }
} }


/** Variant of the <code>MapAgent</code>. */
private static class SDMapAgent extends MapAgent {
public SDMapAgent(MapEnvironment mapEnvironment, Search search,
String[] goalTests) {
super(mapEnvironment.getMap(), mapEnvironment, search, goalTests);
}

@Override
protected Problem formulateProblem(Object goal) {
BidirectionalMapProblem problem = (BidirectionalMapProblem) super
.formulateProblem(goal);
Problem result = new Problem(problem.getInitialState(),
problem.getActionsFunction(), problem.getResultFunction(),
new DefaultGoalTest((String) goal) {
@Override
public boolean isGoalState(Object state) {
visitedStates.add(state);
return super.isGoalState(state);
}
}, problem.getStepCostFunction());
return result;
}
}

/** /**
* Variant of the <code>DefaultMapEntityRenderer</code> which highlights way * Variant of the <code>DefaultMapEntityRenderer</code> which highlights way
* nodes mentioned in {@link SearchDemoOsmAgentApp#visitedStates}. * nodes mentioned in {@link SearchDemoOsmAgentApp#visitedStates}.
*/ */
private static class SDMapEntityRenderer extends DefaultEntityRenderer { private static class SDMapEntityRenderer extends DefaultEntityRenderer {
DefaultEntityViewInfo highlightProp = new MapStyleFactory() DefaultEntityViewInfo highlightProp = new MapStyleFactory().createPoiInfo(0, 0, 5, UColor.GREEN,
.createPoiInfo(0, 0, 5, UColor.GREEN, MapStyleFactory.createRectangle(4, UColor.GREEN), false);
MapStyleFactory.createRectangle(4, UColor.GREEN),
false);


@Override @Override
public void printWay(MapWay way, DefaultEntityViewInfo eprop, public void printWay(MapWay way, DefaultEntityViewInfo eprop, boolean asArea) {
boolean asArea) {
super.printWay(way, eprop, asArea); super.printWay(way, eprop, asArea);
if (scale >= highlightProp.minVisibleScale * displayFactor) { if (scale >= highlightProp.minVisibleScale * displayFactor) {
for (MapNode node : getWayNodes(way)) for (MapNode node : getWayNodes(way))
Expand Down

0 comments on commit 8cb4a09

Please sign in to comment.