Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
The Brown-UMBC Reinforcement Learning and Planning (BURLAP) Java code library is for the use and
development of single or multi-agent planning and learning algorithms and domains to accompany them. The library
uses a highly flexible state/observation representation where you define states with your own Java classes, enabling
support for domains that discrete, continuous, relational, or anything else. Planning and learning algorithms range from classic forward search
planning to value-function-based stochastic planning and learning algorithms.
package burlap.domain.stochasticgames.gridgame;
import burlap.debugtools.RandomFactory;
import burlap.mdp.core.action.Action;
import burlap.mdp.core.Domain;
import burlap.mdp.core.StateTransitionProb;
import burlap.mdp.core.oo.state.OOState;
import burlap.mdp.core.oo.state.ObjectInstance;
import burlap.mdp.core.oo.state.generic.GenericOOState;
import burlap.mdp.core.state.MutableState;
import burlap.mdp.core.state.State;
import burlap.mdp.stochasticgames.JointAction;
import burlap.mdp.stochasticgames.model.FullJointModel;
import java.util.*;
/**
* This class defines the standard transition dynamics for a grid game. By default, the dynamics set a 0.5 probability of agents being able to
* move through semi-walls. The semi-wall pass through probability, however, may be changed by a parameter to a constructor.
* If two agents adjacent agents try to move into each others locations, no one will move. If an agent tries
* to move into a cell that the other agent is leaving, then they both will move. If two agents try to move into the same location,
* then only one of them will randomly make it, while the other will be unmoved in their position.
* @author James MacGlashan
*
*/
public class GridGameStandardMechanics implements FullJointModel {
Random rand;
Domain domain;
double pMoveThroughSWall;
/**
* Initializes the mechanics for the given domain and sets the semi-wall pass through probability to 0.5;
* @param d the domain object
*/
public GridGameStandardMechanics(Domain d){
rand = RandomFactory.getMapped(0);
domain = d;
pMoveThroughSWall = 0.5;
}
/**
* Initializes the mechanics for the given domain and sets the semi-wall pass through probability to semiWallPassThroughProb.
* @param d d the domain object
* @param semiWallPassThroughProb the probability that an agent will pass through a semi-wall.
*/
public GridGameStandardMechanics(Domain d, double semiWallPassThroughProb){
rand = RandomFactory.getMapped(0);
domain = d;
pMoveThroughSWall = semiWallPassThroughProb;
}
@Override
public List stateTransitions(State s, JointAction ja) {
List tps = new ArrayList();
//need to force no movement when trying to enter space of a noop agent
List previousLocations = new ArrayList();
List noopLocations = new ArrayList();
int pn = 0;
for(Action gsa : ja){
Location2 loc = this.getLocation((OOState)s, this.agentName(pn, (OOState)s));
previousLocations.add(loc);
if(gsa.actionName().equals(GridGame.ACTION_NOOP)){
noopLocations.add(loc);
}
pn++;
}
List > possibleOutcomes = new ArrayList>();
for(int i = 0; i < ja.size(); i++){
Location2 loc = previousLocations.get(i);
Action gsa = ja.action(i);
possibleOutcomes.add(this.getPossibleLocationsFromWallCollisions((OOState)s, loc, this.attemptedDelta(gsa.actionName()), noopLocations));
}
List outcomeSets = this.getAllLocationSets(possibleOutcomes);
for(LocationSetProb sp : outcomeSets){
//resolve collisions from attempted swaps, which is deterministic and does not need to be recursed
List basicMoveResults = this.resolvePositionSwaps(previousLocations, sp.locs);
//finally, we need to find all stochastic outcomes from cell competition
List cOutcomeSets = this.getPossibleCollisionOutcomes(previousLocations, basicMoveResults);
//turn them into states with probabilities
for(LocationSetProb csp : cOutcomeSets){
GenericOOState ns = (GenericOOState)s.copy();
for(int i = 0; i < csp.locs.size(); i++){
Action gsa = ja.action(i);
Location2 loc = csp.locs.get(i);
String agentName = this.agentName(i, (OOState)s);
ObjectInstance agent = ns.touch(agentName);
((MutableState)agent).set(GridGame.VAR_X, loc.x);
((MutableState)agent).set(GridGame.VAR_Y, loc.y);
}
double totalProb = sp.p * csp.p;
StateTransitionProb tp = new StateTransitionProb(ns, totalProb);
tps.add(tp);
}
}
return this.combineDuplicateTransitionProbabilities(tps);
}
@Override
public State sample(State s, JointAction ja) {
s = s.copy();
//need to force no movement when trying to enter space of a noop agent
List previousLocations = new ArrayList();
List noopLocations = new ArrayList();
int pn = 0;
for(Action gsa : ja){
Location2 loc = this.getLocation((OOState)s, this.agentName(pn, (OOState)s));
previousLocations.add(loc);
if(gsa.actionName().equals(GridGame.ACTION_NOOP)){
noopLocations.add(loc);
}
pn++;
}
List basicMoveResults = new ArrayList();
for(int i = 0; i < ja.size(); i++){
Location2 loc = previousLocations.get(i);
Action gsa = ja.action(i);
basicMoveResults.add(this.sampleBasicMovement((OOState)s, loc, this.attemptedDelta(gsa.actionName()), noopLocations));
}
//resolve swaps
basicMoveResults = this.resolvePositionSwaps(previousLocations, basicMoveResults);
List finalPositions = this.resolveCollisions(previousLocations, basicMoveResults);
for(int i = 0; i < finalPositions.size(); i++){
Action gsa = ja.action(i);
Location2 loc = finalPositions.get(i);
String agentName = this.agentName(i, (OOState)s);
ObjectInstance agent = ((GenericOOState)s).touch(agentName);
((MutableState)agent).set(GridGame.VAR_X, loc.x);
((MutableState)agent).set(GridGame.VAR_Y, loc.y);
}
return s;
}
/**
* Returns the x-y position of an agent stored in a Location2 object.
* @param s the state in which the agent exists
* @param agentName the name of the agent.
* @return a {@link GridGameStandardMechanics.Location2} object containing the agents position in the world.
*/
protected Location2 getLocation(OOState s, String agentName){
ObjectInstance a = s.object(agentName);
Location2 loc = new Location2((Integer)a.get(GridGame.VAR_X), (Integer)a.get(GridGame.VAR_Y));
return loc;
}
/**
* Returns the attempted change in position by the agent for the given action. For instance, if the action is north,
* it would result in an attempted position change of (0, +1).
* @param actionName the action taken.
* @return the attempted change in position for the given action.
*/
protected Location2 attemptedDelta(String actionName){
if(actionName.equals(GridGame.ACTION_NORTH)){
return new Location2(0, 1);
}
else if(actionName.equals(GridGame.ACTION_SOUTH)){
return new Location2(0, -1);
}
else if(actionName.equals(GridGame.ACTION_EAST)){
return new Location2(1, 0);
}
else if(actionName.equals(GridGame.ACTION_WEST)){
return new Location2(-1, 0);
}
else if(actionName.equals(GridGame.ACTION_NOOP)){
return new Location2(0, 0);
}
throw new RuntimeException("Error: Unknown action named '" + actionName + "' that GridGameStandardMechanics cannot handle");
}
/**
* Returns the position of each agent after accounting for collisions that are a result of agents
* trying to move into each others previous locations.
* @param originalPositions the original position of the agents before their actions were taken.
* @param desiredPositions the new position the agents are trying to go into
* @return the positions of the agents accounting for collisions.
*/
protected List resolvePositionSwaps(List originalPositions, List desiredPositions){
List resolvedPositions = new ArrayList(desiredPositions);
List newNoopPositions = new ArrayList();
for(int i = 0; i < originalPositions.size(); i++){
Location2 a1op = originalPositions.get(i);
Location2 a1dp = resolvedPositions.get(i);
for(int j = i+1; j < resolvedPositions.size(); j++){
Location2 a2op = originalPositions.get(j);
Location2 a2dp = resolvedPositions.get(j);
if(a1op.equals(a2dp) && a1dp.equals(a2op)){
//swap collision!
resolvedPositions.set(i, new Location2(a1op));
resolvedPositions.set(j, new Location2(a2op));
newNoopPositions.add(a1op);
newNoopPositions.add(a2op);
break;
}
}
}
if(!newNoopPositions.isEmpty()){
return this.backupNoOps(originalPositions, resolvedPositions, newNoopPositions);
}
return resolvedPositions;
}
/**
* Backups position changes by agents which can no longer move to their desired location. That is, if agent a wanted to move
* to cell z, but failed for some reason (e.g., direct collision with another agent), then z would be added to the noops list
* and this method would back up the effect of a's ability to change position to any agents that wanted to move into
* a's position.
* @param originalPositions the original position of agents in the previous state
* @param desiredPositions the desired position where the agents want to go
* @param noops the locations in which agents have been forced to stay from other events
* @return the new resolved locations of all agents
*/
protected List backupNoOps(List originalPositions, List desiredPositions, List noops){
List resolved = new ArrayList(desiredPositions);
boolean needsUpdating = true;
while(needsUpdating){
needsUpdating = false;
for(int i = 0; i < resolved.size(); i++){
Location2 dl = resolved.get(i);
Location2 ol = originalPositions.get(i);
if(!dl.equals(ol) && noops.contains(dl)){
resolved.set(i, ol);
noops.add(ol);
needsUpdating = true;
}
}
}
return resolved;
}
/**
* Resolves collisions that occur when two or more agents try to enter the same cell, in which case only one
* agent will make it into the position and the rest will stay in place
* @param originalPositions the positions of the agents in the original state before their actions were taken
* @param desiredPositions the desired locations of the agents
* @return a list of the resulting positions having accounted for collisions.
*/
protected List resolveCollisions(List originalPositions, List desiredPositions){
//get movement collisions
Map > collissionSets = this.getColissionSets(desiredPositions);
if(collissionSets.size() == 0){
return desiredPositions; //no resolutions needed
}
//resolve attempted movement collisions
List finalPoses = new ArrayList();
Map winners = this.getWinningAgentMovements(collissionSets);
for(int i = 0; i < originalPositions.size(); i++){
if(winners.containsKey(i)){
if(winners.get(i) != i){
//this player lost and stays in place
finalPoses.add(originalPositions.get(i));
}
else{
//this player wins and gets to go to desired location
finalPoses.add(desiredPositions.get(i));
}
}
else{
//no competitors so the agent goes where it wants
finalPoses.add(desiredPositions.get(i));
}
}
//it's possible that a losing collision means the agent's spot is no longer available, causing another collision
//in this case all agents affected by loser are pushed back
collissionSets = this.getColissionSets(finalPoses);
while(collissionSets.size() > 0){
Set pushedBackAgents = collissionSets.keySet();
for(Integer aid : pushedBackAgents){
finalPoses.set(aid, originalPositions.get(aid));
}
collissionSets = this.getColissionSets(finalPoses);
}
return finalPoses;
}
protected List getPossibleCollisionOutcomes(List originalPositions, List desiredPositions){
//get movement collisions
Map > collissionSets = this.getColissionSets(desiredPositions);
if(collissionSets.size() == 0){
//then this is trivially just the set of desired positions
List outcomes = new ArrayList(1);
outcomes.add(new LocationSetProb(new ArrayList(desiredPositions), 1.));
return outcomes;
}
List allOutcomes = new ArrayList();
List