Skip to content

Commit 729004e

Browse files
authored
Merge pull request aimacode#427 from samagra14/information_gathering_agent
Adds information gathering agent
2 parents 856bc7d + d8e59c3 commit 729004e

File tree

3 files changed

+248
-1
lines changed

3 files changed

+248
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Java implementation of algorithms from [Russell](http://www.cs.berkeley.edu/~rus
100100
|15.6|580|Fixed-Lag-Smoothing|[FixedLagSmoothing](/aima-core/src/main/java/aima/core/probability/hmm/exact/FixedLagSmoothing.java)|
101101
|15|590|Dynamic Bayesian Network|[DynamicBayesianNetwork](/aima-core/src/main/java/aima/core/probability/bayes/DynamicBayesianNetwork.java)|
102102
|15.17|598|Particle-Filtering|[ParticleFiltering](/aima-core/src/main/java/aima/core/probability/bayes/approx/ParticleFiltering.java)|
103-
|16.9|632|Information-Gathering-Agent|---|
103+
|16.9|632|Information-Gathering-Agent|[InformationGatheringAgent](/aima-core/src/main/java/aima/core/probability/InformationGatheringAgent.java)|
104104
|17|647|Markov Decision Process|[MarkovDecisionProcess](/aima-core/src/main/java/aima/core/probability/mdp/MarkovDecisionProcess.java)|
105105
|17.4|653|Value-Iteration|[ValueIteration](/aima-core/src/main/java/aima/core/probability/mdp/search/ValueIteration.java)|
106106
|17.7|657|Policy-Iteration|[PolicyIteration](/aima-core/src/main/java/aima/core/probability/mdp/search/PolicyIteration.java)|
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package aima.core.probability;
2+
3+
import aima.core.probability.bayes.BayesInference;
4+
import aima.core.probability.bayes.BayesianNetwork;
5+
import aima.core.probability.domain.FiniteDomain;
6+
import aima.core.probability.proposition.AssignmentProposition;
7+
8+
import java.util.List;
9+
10+
/**
11+
* Artificial Intelligence A Modern Approach (3rd Edition): page 626.<br>
12+
* <br>
13+
* Decision networks combine Bayesian networks
14+
* with additional node types for actions and utilities.<br>
15+
* <p>
16+
* In its most general form, a decision network represents information about the agent’s current
17+
* state, its possible actions, the state that will result from the agent’s action, and the utility of
18+
* that state.
19+
*
20+
* @author samagra
21+
*/
22+
public abstract class DecisionNetwork {
23+
24+
// The underlying Bayesian network
25+
private BayesianNetwork network;
26+
// The single decision node
27+
private RandomVariable action;
28+
// To calculate various conditional probabilities
29+
private BayesInference inferenceProcedure;
30+
31+
/**
32+
* Constructor for the decision network.
33+
*
34+
* @param network The underlying Bayesian Network.
35+
* @param action The decision node .
36+
* @param inferenceProcedure The inference procedure to be utilised for probability calculations.
37+
*/
38+
public DecisionNetwork(BayesianNetwork network,
39+
RandomVariable action, BayesInference inferenceProcedure) {
40+
this.network = network;
41+
this.action = action;
42+
this.inferenceProcedure = inferenceProcedure;
43+
}
44+
45+
// Returns the utility for a particular state
46+
public abstract double getUtilityForAction(RandomVariable action, Object value);
47+
48+
/**
49+
* Calculates the expected utility of an action in the presence of a certain random variable.
50+
*
51+
* @param action Action for which the utility is to be calculated.
52+
* @param evidence The available information.
53+
* @return
54+
*/
55+
public double getExpectedUtility(RandomVariable action,
56+
List<AssignmentProposition> evidence) {
57+
double utility = 0;
58+
CategoricalDistribution distribution = inferenceProcedure.ask((new RandomVariable[]{action}),
59+
((AssignmentProposition[]) evidence.toArray()), this.getNetwork());
60+
for (Object value :
61+
((FiniteDomain) action.getDomain()).getPossibleValues()) {
62+
utility += distribution.getValue(value) * this.getUtilityForAction(action, value);
63+
}
64+
return utility;
65+
}
66+
67+
/**
68+
* Currently the decision network supports only a single decision node and hence returns
69+
* the same action.
70+
*
71+
* @return
72+
*/
73+
public Object getBestAction() {
74+
return action;
75+
}
76+
77+
/**
78+
* Returns the underlying Bayesian Network.
79+
*
80+
* @return
81+
*/
82+
public BayesianNetwork getNetwork() {
83+
return network;
84+
}
85+
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package aima.core.probability;
2+
3+
import aima.core.agent.Action;
4+
import aima.core.agent.Agent;
5+
import aima.core.agent.Percept;
6+
import aima.core.probability.bayes.BayesInference;
7+
import aima.core.probability.domain.FiniteDomain;
8+
import aima.core.probability.proposition.AssignmentProposition;
9+
10+
import java.util.ArrayList;
11+
import java.util.Collections;
12+
import java.util.List;
13+
14+
/**
15+
* Artificial Intelligence A Modern Approach (3rd Edition): Figure 16.9, page 632.<br>
16+
* </br>
17+
* <pre>
18+
*
19+
* function INFORMATION-GATHERING-AGENT(percept) returns an action
20+
*  persistent: D, a decision network
21+
*
22+
* integrate percept into D
23+
*  j ← the value that maximizes VPI(Ej) / Cost(Ej)
24+
*  if VPI(Ej) > Cost(Ej)
25+
*    return REQUEST(Ej)
26+
*  else return the best action from D
27+
*
28+
* </pre>
29+
* <p>
30+
* Figure ?? Design of a simple information-gathering agent.
31+
* The agent works by repeatedly selecting the observation with
32+
* the highest information value, until the cost of the next
33+
* observation is greater than its expected benefit.
34+
*
35+
* @author samagra
36+
*/
37+
public abstract class InformationGatheringAgent implements Agent {
38+
39+
// To carry out conditional probability calculations
40+
private BayesInference inferenceMethod;
41+
// persistent: D, a decision network
42+
private DecisionNetwork decisionNetwork;
43+
// To store the information collected till now
44+
private List<AssignmentProposition> observedEvidence;
45+
// To store the scope of information that can be collected
46+
private List<RandomVariable> randomVars;
47+
48+
/**
49+
* Constructor for the agent.
50+
*
51+
* @param decisionNetwork The decision network which represents the problem
52+
* for which the information is to be collected
53+
* @param inferenceMethod To carry out various conditional probability calculations
54+
* @param initialEvidence The information which is available beforehand to the agent.
55+
*/
56+
public InformationGatheringAgent(DecisionNetwork decisionNetwork,
57+
BayesInference inferenceMethod,
58+
List<AssignmentProposition> initialEvidence) {
59+
this.decisionNetwork = decisionNetwork;
60+
this.inferenceMethod = inferenceMethod;
61+
this.observedEvidence = initialEvidence;
62+
this.randomVars = this.decisionNetwork.getNetwork().getVariablesInTopologicalOrder();
63+
}
64+
65+
public InformationGatheringAgent(DecisionNetwork decisionNetwork,
66+
BayesInference inferenceMethod) {
67+
this(decisionNetwork, inferenceMethod, new ArrayList<>());
68+
}
69+
70+
/**
71+
* function INFORMATION-GATHERING-AGENT(percept) returns an action
72+
*
73+
* @param percept The current percept of a sequence perceived by the Agent.
74+
* @return action to be executed by the agent
75+
*/
76+
@Override
77+
public Action execute(Percept percept) {
78+
// integrate percept into D
79+
observedEvidence = integratePercept(observedEvidence, percept);
80+
81+
// j ← the value that maximizes VPI(Ej) / Cost(Ej)
82+
List<Double> vpiPerUnitCosts = this.vpiPerUnitCost(this.randomVars);
83+
int j = vpiPerUnitCosts.indexOf(Collections.max(vpiPerUnitCosts));
84+
RandomVariable randomVar = this.randomVars.get(j);
85+
86+
// if VPI(Ej) > Cost(Ej)
87+
if (getVpi(randomVar) > getCost(randomVar)) {
88+
// return REQUEST(Ej)
89+
return this.request(randomVar);
90+
}
91+
// else return the best action from D
92+
return ((Action) decisionNetwork.getBestAction());
93+
}
94+
95+
/**
96+
* We assume that the result of
97+
* the action Request (Ej ) is that the next percept provides the value of Ej .
98+
*
99+
* @param randomVar The random variable for which the information is needed.
100+
* @return The action which leads to the agent to the value of Ej.
101+
*/
102+
protected abstract Action request(RandomVariable randomVar);
103+
104+
/**
105+
* Calculates the vpi (value of perfect information) per unit cost
106+
* for all the random variables.
107+
*
108+
* @param variablesInTopologicalOrder The variables for which information is required.
109+
* @return A list of vpi values.
110+
*/
111+
private List<Double> vpiPerUnitCost(List<RandomVariable> variablesInTopologicalOrder) {
112+
List<Double> vpiPerUnitCost = new ArrayList<>();
113+
for (RandomVariable var :
114+
variablesInTopologicalOrder) {
115+
vpiPerUnitCost.add(getVpi(var) / getCost(var));
116+
}
117+
return vpiPerUnitCost;
118+
}
119+
120+
/**
121+
* Calculates the cost of obtaining information for
122+
* a particular variable.
123+
*
124+
* @param var
125+
* @return
126+
*/
127+
abstract double getCost(RandomVariable var);
128+
129+
/**
130+
* Calculates VPI for a particular random variable.
131+
*
132+
* @param var
133+
* @return
134+
*/
135+
double getVpi(RandomVariable var) {
136+
double vpi = 0;
137+
CategoricalDistribution distribution = inferenceMethod.ask((new RandomVariable[]{var}),
138+
((AssignmentProposition[]) observedEvidence.toArray()), decisionNetwork.getNetwork());
139+
for (Object value :
140+
((FiniteDomain) var.getDomain()).getPossibleValues()) {
141+
double posterierProb = distribution.getValue(value);
142+
List<AssignmentProposition> modifiedEvidence = new ArrayList<>(observedEvidence);
143+
modifiedEvidence.add(new AssignmentProposition(var, value));
144+
double expectedUtilityForParticularValue = decisionNetwork.getExpectedUtility(var,
145+
modifiedEvidence);
146+
vpi += posterierProb * expectedUtilityForParticularValue;
147+
}
148+
vpi -= decisionNetwork.getExpectedUtility(var, observedEvidence);
149+
return vpi;
150+
}
151+
152+
/**
153+
* Extracts the information from the percepts and adds ot to our observed evidence.
154+
*
155+
* @param observedEvidence
156+
* @param percept
157+
* @return
158+
*/
159+
abstract List<AssignmentProposition> integratePercept(List<AssignmentProposition> observedEvidence, Percept percept);
160+
161+
162+
}

0 commit comments

Comments
 (0)