package core;
import java.io.Serializable;
import java.util.*;
import org.apache.commons.collections4.queue.CircularFifoQueue;
/**
* Premise: All states have the complete action space
*/
public class DeterministicStateActionTable implements StateActionTable, Serializable {
private final Map> table;
private DiscreteActionSpace discreteActionSpace;
private Queue>> latestChanges;
public DeterministicStateActionTable(DiscreteActionSpace discreteActionSpace){
table = new LinkedHashMap<>();
this.discreteActionSpace = discreteActionSpace;
latestChanges = new CircularFifoQueue<>(10);
}
/**
* If the state is not present in the table at the time of
* calling this method the DEFAULT_VALUE gets returned BUT
* no the missing state is not inserted into the table!
*
* Inserting of missing states is ONLY done in "setValue()"
* method.
*
* @param state given state
* @param action given action
* @return estimate value of state-action pair
*/
@Override
public double getValue(State state, A action) {
final Map actionValues = table.get(state);
if (actionValues != null) {
return actionValues.get(action);
}
return DEFAULT_VALUE;
}
/**
* Update the value of an action for a specific state.
* If the state is not present in the table yet,
* it will get stored in combination with every action
* from the action space initialized with the default value.
*
* @param state given state
* @param action given action
* @param value new estimate of the state-action pair
*/
@Override
public void setValue(State state, A action, double value) {
final Map actionValues;
if (table.containsKey(state)) {
actionValues = table.get(state);
} else {
actionValues = createDefaultActionValues();
table.put(state, actionValues);
}
latestChanges.add(new AbstractMap.SimpleEntry<>(state, actionValues));
actionValues.put(action, value);
}
/**
* @param state given state
* @return all available action in given state and their corresponding estimated values
*/
@Override
public Map getActionValues(State state) {
if(table.get(state) == null){
table.put(state, createDefaultActionValues());
}
return table.get(state);
}
@Override
public Queue>> getFirstStateEntriesForView() {
return latestChanges;
}
/**
* @return Map with initial values for every available action
*/
private Map createDefaultActionValues(){
final Map defaultActionValues = new LinkedHashMap<>();
for(A action: discreteActionSpace){
defaultActionValues.put(action, DEFAULT_VALUE);
}
return defaultActionValues;
}
@Override
public int getStateCount(){
return table.size();
}
}