Package teamwork :: Package multiagent :: Module sequential
[hide private]
[frames] | no frames]

Source Code for Module teamwork.multiagent.sequential

 1  import copy 
 2  from types import * 
 3   
 4  from PsychAgents import * 
 5  from teamwork.math.matrices import epsilon 
 6   
7 -class SequentialAgents(PsychAgents):
8 """A utility class that supports sequential turns by a group of agents. The order is determined by the ordering methods on the component agent classes. 9 @warning: sequentiality is required, so don't try having multiple agents act at the same time. 10 """
11 - def generateOrder(self,entities=None):
12 """Creates a new order vector. Orders the agents according to the comparison method on the member agents 13 @param entities: the ordered list of entities to use (if omitted, defaults to the sorted list of active members) 14 @type entities: L{teamwork.agent.Agent.Agent}[] 15 @return: the turn state vector suitable for the initial state of the simulation 16 @rtype: L{KeyedVector} 17 """ 18 self._turnDynamics.clear() 19 if entities is None: 20 entities = self.activeMembers() 21 entities.sort() 22 order = KeyedVector() 23 self.positions = {} 24 for index in range(len(entities)): 25 agent = entities[index] 26 value = 1./pow(2,index) * self.threshold + epsilon 27 self.positions[agent.name] = value 28 order[StateKey({'entity':agent.name, 29 'feature':self.turnFeature})] = value 30 order[keyConstant] = 1. 31 order.freeze() 32 return order
33
34 - def createTurnDynamics(self,actions):
35 """Computes the change in turn due to the specified actions 36 @param actions: the actions being performed, indexed by actor name 37 @type actions: C{dict:strS{->}L{teamwork.action.PsychActions.Action}[]} 38 @return: a decision tree representing the changes to the standing turn order vector based on the specified actions 39 @rtype: L{KeyedTree} 40 """ 41 assert(len(actions) == 1) 42 # Unless the actor is taking another turn, then no change 43 unchangedMatrix = KeyedMatrix() 44 for key in self.order.keys(): 45 row = KeyedVector() 46 row[key] = 1. 47 unchangedMatrix[key] = row 48 row = KeyedVector() 49 row[keyConstant] = 1. 50 unchangedMatrix[keyConstant] = row 51 # Check whether anyone ever has a turn 52 if len(self) == 0: 53 tree = KeyedTree() 54 tree.makeLeaf(unchangedMatrix) 55 return tree 56 actor = actions.keys()[0] 57 # Test whether anybody's left to act after these new actions 58 resetWeights = KeyedVector() 59 for key in self.order.keys(): 60 if isinstance(key,StateKey) and not actions.has_key(key['entity']): 61 resetWeights[key] = 1. 62 resetPlane = KeyedPlane(resetWeights,0.0001) 63 # If so, move the leftover actors up in the turn order 64 updateMatrix = KeyedMatrix() 65 for key in self.order.keys(): 66 row = KeyedVector() 67 if isinstance(key,StateKey): 68 if actions.has_key(key['entity']): 69 # Reset activation 70 value = pow(2,len(self.activeMembers())-1) 71 row[keyConstant] = 1./value*self.threshold + epsilon 72 else: 73 # Move up in the order 74 row[key] = 2. 75 else: 76 # Constant 77 row[key] = 1. 78 updateMatrix[key] = row 79 # Test whether actor is sneaking in a second turn 80 alreadyActed = ThresholdRow(keys=[{'entity':actor, 81 'feature':self.turnFeature}]) 82 updateTree = KeyedTree() 83 updateTree.branch(KeyedPlane(alreadyActed,0.), 84 unchangedMatrix,updateMatrix) 85 # If nobody left to act, start the turn order from the beginning 86 resetMatrix = KeyedMatrix() 87 for key in self.order.keys(): 88 row = KeyedVector() 89 if isinstance(key,StateKey): 90 row[keyConstant] = self.positions[key['entity']] 91 else: 92 row[keyConstant] = 1. 93 resetMatrix[key] = row 94 # Create branch on number of people left to act 95 tree = KeyedTree() 96 tree.branch(resetPlane,resetMatrix,updateTree) 97 return tree
98