Skip to content

Commit f593a51

Browse files
committed
AdaptableHeuristicFunction replaced by a more general concept.
Till now, problem solving agents could approach one goal only or use uninformed search only. This is now fixed.
1 parent 99acaf3 commit f593a51

26 files changed

+1799
-1550
lines changed

aima-core/src/main/java/aima/core/environment/map/AdaptableHeuristicFunction.java

Lines changed: 0 additions & 31 deletions
This file was deleted.

aima-core/src/main/java/aima/core/environment/map/MapAgent.java

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,51 +10,66 @@
1010
import aima.core.agent.State;
1111
import aima.core.agent.impl.DynamicPercept;
1212
import aima.core.agent.impl.DynamicState;
13+
import aima.core.search.framework.EvaluationFunction;
14+
import aima.core.search.framework.HeuristicFunctionFactory;
15+
import aima.core.search.framework.ProblemSolvingAgent;
1316
import aima.core.search.framework.Search;
14-
import aima.core.search.framework.SimpleProblemSolvingAgent;
1517
import aima.core.search.framework.problem.Problem;
18+
import aima.core.search.informed.BestFirstSearch;
19+
import aima.core.search.informed.HeuristicEvaluationFunction;
20+
import aima.core.search.informed.RecursiveBestFirstSearch;
1621

1722
/**
18-
* @author Ciaran O'Reilly
23+
* Variant of {@link aima.core.environment.map.SimpleMapAgent} which works
24+
* correctly also for A* and other best-first search implementations. It can be
25+
* extended also for scenarios, in which the agent faces unforeseen events. When
26+
* using informed search and more then one goal, make sure, that a heuristic
27+
* function factory is provided!
1928
*
29+
* @author Ruediger Lunde
30+
*
2031
*/
21-
public class MapAgent extends SimpleProblemSolvingAgent {
32+
public class MapAgent extends ProblemSolvingAgent {
2233

2334
protected Map map = null;
2435
protected DynamicState state = new DynamicState();
2536

2637
// possibly null...
2738
private EnvironmentViewNotifier notifier = null;
2839
private Search search = null;
29-
private String[] goals = null;
30-
private int goalTestPos = 0;
40+
private HeuristicFunctionFactory hfFactory;
41+
protected String[] goals = null;
42+
protected int currGoalIdx = 0;
3143

32-
public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search) {
44+
public MapAgent(Map map, Search search, String goal) {
3345
this.map = map;
34-
this.notifier = notifier;
35-
this.search = search;
36-
}
37-
38-
public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search, int maxGoalsToFormulate) {
39-
super(maxGoalsToFormulate);
40-
this.map = map;
41-
this.notifier = notifier;
4246
this.search = search;
47+
this.goals = new String[] { goal };
4348
}
4449

45-
public MapAgent(Map map, EnvironmentViewNotifier notifier, Search search, String[] goals) {
46-
this(map, search, goals);
50+
public MapAgent(Map map, Search search, String goal, EnvironmentViewNotifier notifier) {
51+
this(map, search, goal);
4752
this.notifier = notifier;
4853
}
4954

5055
public MapAgent(Map map, Search search, String[] goals) {
51-
super(goals.length);
5256
this.map = map;
5357
this.search = search;
5458
this.goals = new String[goals.length];
5559
System.arraycopy(goals, 0, this.goals, 0, goals.length);
5660
}
5761

62+
public MapAgent(Map map, Search search, String[] goals, EnvironmentViewNotifier notifier) {
63+
this(map, search, goals);
64+
this.notifier = notifier;
65+
}
66+
67+
public MapAgent(Map map, Search search, String[] goals, EnvironmentViewNotifier notifier,
68+
HeuristicFunctionFactory hfFactory) {
69+
this(map, search, goals, notifier);
70+
this.hfFactory = hfFactory;
71+
}
72+
5873
//
5974
// PROTECTED METHODS
6075
//
@@ -70,16 +85,13 @@ protected State updateState(Percept p) {
7085
@Override
7186
protected Object formulateGoal() {
7287
Object goal = null;
73-
if (null == goals) {
74-
goal = map.randomlyGenerateDestination();
75-
} else {
76-
goal = goals[goalTestPos];
77-
goalTestPos++;
88+
if (currGoalIdx < goals.length) {
89+
goal = goals[currGoalIdx++];
90+
if (notifier != null)
91+
notifier.notifyViews("CurrentLocation=In(" + state.getAttribute(DynAttributeNames.AGENT_LOCATION)
92+
+ "), Goal=In(" + goal + ")");
93+
modifyHeuristicFunction(goal);
7894
}
79-
if (notifier != null)
80-
notifier.notifyViews("CurrentLocation=In(" + state.getAttribute(DynAttributeNames.AGENT_LOCATION)
81-
+ "), Goal=In(" + goal + ")");
82-
8395
return goal;
8496
}
8597

@@ -97,10 +109,10 @@ protected List<Action> search(Problem problem) {
97109
} catch (Exception ex) {
98110
ex.printStackTrace();
99111
}
112+
notifyViewOfMetrics();
100113
return result;
101114
}
102115

103-
@Override
104116
protected void notifyViewOfMetrics() {
105117
if (notifier != null) {
106118
Set<String> keys = search.getMetrics().keySet();
@@ -109,4 +121,17 @@ protected void notifyViewOfMetrics() {
109121
}
110122
}
111123
}
124+
125+
private void modifyHeuristicFunction(Object goal) {
126+
if (hfFactory != null) {
127+
EvaluationFunction ef = null;
128+
if (search instanceof BestFirstSearch)
129+
ef = ((BestFirstSearch) search).getEvaluationFunction();
130+
else if (search instanceof RecursiveBestFirstSearch)
131+
ef = ((RecursiveBestFirstSearch) search).getEvaluationFunction();
132+
if (ef instanceof HeuristicEvaluationFunction) {
133+
((HeuristicEvaluationFunction) ef).setHeuristicFunction(hfFactory.createHeuristicFunction(goal));
134+
}
135+
}
136+
}
112137
}
Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,65 @@
1-
package aima.core.environment.map;
2-
3-
import aima.core.agent.Action;
4-
import aima.core.agent.Agent;
5-
import aima.core.agent.Percept;
6-
import aima.core.agent.impl.AbstractEnvironment;
7-
import aima.core.agent.impl.DynamicPercept;
8-
9-
/**
10-
* Represents the environment a MapAgent can navigate.
11-
*
12-
* @author Ciaran O'Reilly
13-
*
14-
*/
15-
public class MapEnvironment extends AbstractEnvironment {
16-
17-
private Map map = null;
18-
private MapEnvironmentState state = new MapEnvironmentState();
19-
20-
public MapEnvironment(Map map) {
21-
this.map = map;
22-
}
23-
24-
public void addAgent(Agent a, String startLocation) {
25-
// Ensure the agent state information is tracked before
26-
// adding to super, as super will notify the registered
27-
// EnvironmentViews that is was added.
28-
state.setAgentLocationAndTravelDistance(a, startLocation, 0.0);
29-
super.addAgent(a);
30-
}
31-
32-
public String getAgentLocation(Agent a) {
33-
return state.getAgentLocation(a);
34-
}
35-
36-
public Double getAgentTravelDistance(Agent a) {
37-
return state.getAgentTravelDistance(a);
38-
}
39-
40-
@Override
41-
public void executeAction(Agent agent, Action a) {
42-
43-
if (!a.isNoOp()) {
44-
MoveToAction act = (MoveToAction) a;
45-
46-
String currLoc = getAgentLocation(agent);
47-
Double distance = map.getDistance(currLoc, act.getToLocation());
48-
if (distance != null) {
49-
double currTD = getAgentTravelDistance(agent);
50-
state.setAgentLocationAndTravelDistance(agent,
51-
act.getToLocation(), currTD + distance);
52-
}
53-
}
54-
}
55-
56-
@Override
57-
public Percept getPerceptSeenBy(Agent anAgent) {
58-
return new DynamicPercept(DynAttributeNames.PERCEPT_IN,
59-
getAgentLocation(anAgent));
60-
}
61-
62-
public Map getMap() {
63-
return map;
64-
}
1+
package aima.core.environment.map;
2+
3+
import aima.core.agent.Action;
4+
import aima.core.agent.Agent;
5+
import aima.core.agent.Percept;
6+
import aima.core.agent.impl.AbstractEnvironment;
7+
import aima.core.agent.impl.DynamicPercept;
8+
9+
/**
10+
* Represents the environment a SimpleMapAgent can navigate.
11+
*
12+
* @author Ciaran O'Reilly
13+
*
14+
*/
15+
public class MapEnvironment extends AbstractEnvironment {
16+
17+
private Map map = null;
18+
private MapEnvironmentState state = new MapEnvironmentState();
19+
20+
public MapEnvironment(Map map) {
21+
this.map = map;
22+
}
23+
24+
public void addAgent(Agent a, String startLocation) {
25+
// Ensure the agent state information is tracked before
26+
// adding to super, as super will notify the registered
27+
// EnvironmentViews that is was added.
28+
state.setAgentLocationAndTravelDistance(a, startLocation, 0.0);
29+
super.addAgent(a);
30+
}
31+
32+
public String getAgentLocation(Agent a) {
33+
return state.getAgentLocation(a);
34+
}
35+
36+
public Double getAgentTravelDistance(Agent a) {
37+
return state.getAgentTravelDistance(a);
38+
}
39+
40+
@Override
41+
public void executeAction(Agent agent, Action a) {
42+
43+
if (!a.isNoOp()) {
44+
MoveToAction act = (MoveToAction) a;
45+
46+
String currLoc = getAgentLocation(agent);
47+
Double distance = map.getDistance(currLoc, act.getToLocation());
48+
if (distance != null) {
49+
double currTD = getAgentTravelDistance(agent);
50+
state.setAgentLocationAndTravelDistance(agent,
51+
act.getToLocation(), currTD + distance);
52+
}
53+
}
54+
}
55+
56+
@Override
57+
public Percept getPerceptSeenBy(Agent anAgent) {
58+
return new DynamicPercept(DynAttributeNames.PERCEPT_IN,
59+
getAgentLocation(anAgent));
60+
}
61+
62+
public Map getMap() {
63+
return map;
64+
}
6565
}

0 commit comments

Comments
 (0)