def _makeLightToggleAction(self, agent): """ Action to toggle the light switch in a loc that has one. Toggling a switch in a loc affects the light status in all rooms that share its light """ locKey = stateKey(agent.name, 'loc') locsWithLights = set(self.sharedLights.keys()) ## Legal if I'm in a room with a light switch legalityTree = makeTree({ 'if': equalRow(locKey, locsWithLights), True: True, False: False }) action = agent.addAction({'verb': 'toggleLight'}, makeTree(legalityTree)) ## Instead of iterating over locations, I'll iterate over those that have ## switches and create a tree for each affected room for switch, affected in self.sharedLights.items(): for aff in affected: affFlag = stateKey(WORLD, 'light' + str(aff)) txnTree = { 'if': equalRow(locKey, switch), True: { 'if': equalRow(affFlag, True), True: setToConstantMatrix(affFlag, False), False: setToConstantMatrix(affFlag, True) }, False: noChangeMatrix(affFlag) } self.world.setDynamics(affFlag, action, makeTree(txnTree)) self.lightActions[agent.name] = action
def get_reward_tree(agent, my_dec, other_dec): reward_key = rewardKey(agent.name) return makeTree({ 'if': equalRow(my_dec, NOT_DECIDED), # if I have not decided True: setToConstantMatrix(reward_key, INVALID), False: { 'if': equalRow(other_dec, NOT_DECIDED), # if other has not decided True: setToConstantMatrix(reward_key, INVALID), False: { 'if': equalRow(my_dec, COOPERATED), # if I cooperated True: { 'if': equalRow(other_dec, COOPERATED), # if other cooperated True: setToConstantMatrix(reward_key, MUTUAL_COOP), # both cooperated False: setToConstantMatrix(reward_key, SUCKER) }, False: { 'if': equalRow(other_dec, COOPERATED), # if I defected and other cooperated True: setToConstantMatrix(reward_key, TEMPTATION), False: setToConstantMatrix(reward_key, PUNISHMENT) } } } })
def makeRandomFOVDistr(self, agent): fov_key = stateKey(agent.name, FOV_FEATURE) tree = { 'if': equalRow(stateKey(agent.name, 'loc'), self.world_map.all_locations), None: noChangeMatrix(fov_key) } for il, loc in enumerate(self.world_map.all_locations): if loc not in self.victimClrCounts.keys(): tree[il] = setToConstantMatrix(fov_key, 'none') continue sub_tree, leaves = self._make_fov_color_dist(loc, 0) for dist in leaves: prob_dist = Distribution(dist) prob_dist.normalize() dist.clear() weights = [(setToConstantMatrix(fov_key, c), p) for c, p in prob_dist.items() if p > 0] if len(weights) == 1: weights.append((noChangeMatrix(fov_key), 0)) dist['distribution'] = weights tree[il] = sub_tree return tree
def set_action_legality(agent, action, legality=True, models=None): """ Sets legality for an action for the given agent and model. :param Agent agent: the agent whose model(s) we want to set the action legality. :param ActionSet action: the action for which to set the legality. :param bool legality: whether to set this action legal (True) or illegal (False) :param list[str] models: the list of models for which to set the action legality. None will set to the agent itself. """ # tests for "true" model if models is None or len(models) == 0: agent.setLegal(action, makeTree(legality)) return model_key = modelKey(agent.name) # initial tree (end condition is: 'not legality') tree = not legality # recursively builds legality tree by comparing the model's key with the index of the model in the state/vector for model in models: tree = { 'if': equalRow(model_key, agent.model2index(model)), True: legality, False: tree } agent.setLegal(action, makeTree(tree))
def get_reward_tree(agent, my_side, other_side): reward_key = rewardKey(agent.name) return makeTree({ 'if': equalRow(my_side, NOT_DECIDED), # if I have not decided True: setToConstantMatrix(reward_key, INVALID), False: { 'if': equalRow(other_side, INVALID), # if other has not decided True: setToConstantMatrix(reward_key, INVALID), False: { 'if': equalFeatureRow(my_side, other_side), # if my_side == other_side True: setToConstantMatrix(reward_key, SAME_SIDE_RWD), False: setToConstantMatrix(reward_key, DIFF_SIDES_RWD) } } })
def _makeMoveActions(self, agent): """ N/E/S/W actions Legality: if current location has a neighbor in the given direction Dynamics: 1) change human's location; 2) set the seen flag for new location to True 3) Set the observable victim variables to the first victim at the new location, if any 4) Reset the crosshair/approached vars to none """ self.moveActions[agent.name] = [] locKey = stateKey(agent.name, 'loc') for direction in Directions: # Legal if current location has a neighbor in the given direction locsWithNbrs = set(self.neighbors[direction.value].keys()) legalityTree = makeTree({ 'if': equalRow(locKey, locsWithNbrs), True: True, False: False }) action = agent.addAction({ 'verb': 'move', 'object': direction.name }, legalityTree) self.moveActions[agent.name].append(action) # Dynamics of this move action: change the agent's location to 'this' location lstlocsWithNbrs = list(locsWithNbrs) tree = {'if': equalRow(locKey, lstlocsWithNbrs)} for il, loc in enumerate(lstlocsWithNbrs): tree[il] = setToConstantMatrix( locKey, self.neighbors[direction.value][loc]) self.world.setDynamics(locKey, action, makeTree(tree)) # move increments the counter of the location we moved to for dest in self.all_locations: destKey = stateKey(agent.name, 'locvisits_' + str(dest)) tree = makeTree({ 'if': equalRow(makeFuture(locKey), dest), True: incrementMatrix(destKey, 1), False: noChangeMatrix(destKey) }) self.world.setDynamics(destKey, action, tree) # increment time self.world.setDynamics( self.world.time, action, makeTree(incrementMatrix(self.world.time, MOVE_TIME_INC)))
def set_reward(self, agent, weight, model=None): rwd_feat = rewardKey(agent.name) # compares agent's current location rwd_tree = {'if': equalRow(self.location_feat, self.all_locations), None: noChangeMatrix(rwd_feat)} # get visitation count according to location for i, loc in enumerate(self.all_locations): loc_freq_feat = get_num_visits_location_key(agent, loc) rwd_tree[i] = dynamicsMatrix(rwd_feat, {self.time_feat: 1., loc_freq_feat: -1.}) \ if self.inverse else setToFeatureMatrix(rwd_feat, loc_freq_feat) agent.setReward(makeTree(rwd_tree), weight * self.normalize_factor, model)
def _createSensorDyn(self, human): for d in Directions: beepKey = stateKey(human.name, 'sensor_' + d.name) locsWithNbrs = list(self.world_map.neighbors[d.value].keys()) tree = { 'if': equalRow(makeFuture(stateKey(human.name, 'loc')), locsWithNbrs), None: setToConstantMatrix(beepKey, 'none') } for il, loc in enumerate(locsWithNbrs): nbr = self.world_map.neighbors[d.value][loc] tree[il] = self._sense1Location(beepKey, nbr) self.world.setDynamics(beepKey, True, makeTree(tree))
def set_reward(self, agent, weight, model=None): rwd_feat = rewardKey(agent.name) # compares agent's current location rwd_tree = {'if': equalRow(self.location_feat, self.all_locations), None: noChangeMatrix(rwd_feat)} # get binary value according to visitation of location for i, loc in enumerate(self.all_locations): loc_freq_feat = get_num_visits_location_key(agent, loc) rwd_tree[i] = {'if': thresholdRow(loc_freq_feat, 1), True: setToConstantMatrix(rwd_feat, 1), False: setToConstantMatrix(rwd_feat, 0)} agent.setReward(makeTree(rwd_tree), weight * self.normalize_factor, model)
def _make_fov_color_dist(self, loc, cur_idx): if cur_idx == len(self.color_names): dist = {'none': 1} return dist, [dist] color = self.color_names[cur_idx] clr_counter = stateKey(WORLD, 'ctr_' + loc + '_' + color) tree = {'if': equalRow(clr_counter, 0)} branch, branch_leaves = self._make_fov_color_dist(loc, cur_idx + 1) for dist in branch_leaves: dist[color] = 0 tree[True] = branch tree_leaves = branch_leaves branch, branch_leaves = self._make_fov_color_dist(loc, cur_idx + 1) for dist in branch_leaves: dist[color] = 2 tree[False] = branch tree_leaves.extend(branch_leaves) return tree, tree_leaves
def _createTriageAction(self, agent, color): loc_key = stateKey(agent.name, 'loc') # legal only if any "active" victim of given color is in the same loc tree = { 'if': equalRow(loc_key, self.world_map.all_locations), None: False } for i, loc in enumerate(self.world_map.all_locations): vicsInLocOfClrKey = stateKey(WORLD, 'ctr_' + loc + '_' + color) tree[i] = { 'if': thresholdRow(vicsInLocOfClrKey, 0), True: True, False: False } action = agent.addAction({'verb': 'triage_' + color}, makeTree(tree)) # different triage time thresholds according to victim type threshold = 7 if color == GREEN_STR else 14 long_enough = differenceRow(makeFuture(self.world.time), self.world.time, threshold) # make triage dynamics for counters of each loc for loc in self.world_map.all_locations: # successful triage conditions conds = [equalRow(loc_key, loc), long_enough] # location-specific counter of vics of this color: if successful, decrement vicsInLocOfClrKey = stateKey(WORLD, 'ctr_' + loc + '_' + color) tree = makeTree( anding(conds, incrementMatrix(vicsInLocOfClrKey, -1), noChangeMatrix(vicsInLocOfClrKey))) self.world.setDynamics(vicsInLocOfClrKey, action, tree) # white: increment vicsInLocOfClrKey = stateKey(WORLD, 'ctr_' + loc + '_' + WHITE_STR) tree = makeTree( anding(conds, incrementMatrix(vicsInLocOfClrKey, 1), noChangeMatrix(vicsInLocOfClrKey))) self.world.setDynamics(vicsInLocOfClrKey, action, tree) # Color saved counter: increment saved_key = stateKey(agent.name, 'numsaved_' + color) tree = { 'if': long_enough, True: incrementMatrix(saved_key, 1), False: noChangeMatrix(saved_key) } self.world.setDynamics(saved_key, action, makeTree(tree)) # Color saved: according to difference diff = {makeFuture(saved_key): 1, saved_key: -1} saved_key = stateKey(agent.name, 'saved_' + color) self.world.setDynamics(saved_key, action, makeTree(dynamicsMatrix(saved_key, diff))) self.world.setDynamics( saved_key, True, makeTree(setFalseMatrix(saved_key))) # default: set to False # increment time self.world.setDynamics( self.world.time, action, makeTree(incrementMatrix(self.world.time, threshold))) self.triageActs[agent.name][color] = action
world.setFeature(dec, NOT_DECIDED) agents_dec.append(dec) # define agents' actions inspired on TIT-FOR-TAT: first decision is open, then retaliate non-cooperation. # as soon as one agent defects it will always defect from there on for i, agent in enumerate(agents): my_dec = agents_dec[i] other_dec = agents_dec[0 if i == 1 else 1] # defect (not legal if other has cooperated before, legal only if agent itself did not defect before) action = agent.addAction({ 'verb': '', 'action': 'defect' }, makeTree({ 'if': equalRow(other_dec, COOPERATED), True: { 'if': equalRow(my_dec, DEFECTED), True: True, False: False }, False: True })) tree = makeTree(setToConstantMatrix(my_dec, DEFECTED)) world.setDynamics(my_dec, action, tree) # cooperate (not legal if other or agent itself defected before) action = agent.addAction({ 'verb': '', 'action': 'cooperate' },
int, lo=0, hi=100) world.setFeature(var_ask_amnt, 0) var_rcv_amnt = world.defineState(ag_consumer.name, 'received amount', int, lo=0, hi=100) world.setFeature(var_rcv_amnt, 0) # add producer actions # produce capacity: if half capacity then 0.5*asked amount else asked amount) act_prod = ag_producer.addAction({'verb': '', 'action': 'produce'}) tree = makeTree({ 'if': equalRow(var_half_cap, True), True: multi_set_matrix(var_rcv_amnt, {var_ask_amnt: 0.5}), False: setToFeatureMatrix(var_rcv_amnt, var_ask_amnt) }) world.setDynamics(var_rcv_amnt, act_prod, tree) # add consumer actions (ask more = 10 / less = 5) act_ask_more = ag_consumer.addAction({'verb': '', 'action': 'ask_more'}) tree = makeTree(setToConstantMatrix(var_ask_amnt, 10)) world.setDynamics(var_ask_amnt, act_ask_more, tree) act_ask_less = ag_consumer.addAction({'verb': '', 'action': 'ask_less'}) tree = makeTree(setToConstantMatrix(var_ask_amnt, 5)) world.setDynamics(var_ask_amnt, act_ask_less, tree) # defines payoff for consumer agent: if received amount > 5 then 10 - rcv_amnt (penalty) else rcv_amount (reward)
def _createTriageAction(self, agent, color): fov_key = stateKey(agent.name, FOV_FEATURE) loc_key = stateKey(agent.name, 'loc') legal = {'if': equalRow(fov_key, color), True: True, False: False} action = agent.addAction({'verb': 'triage_' + color}, makeTree(legal)) if color == GREEN_STR: threshold = 7 else: threshold = 14 longEnough = differenceRow(makeFuture(self.world.time), self.world.time, threshold) for loc in self.world_map.all_locations: # successful triage conditions conds = [ equalRow(fov_key, color), equalRow(loc_key, loc), longEnough ] # location-specific counter of vics of this color: if successful, decrement vicsInLocOfClrKey = stateKey(WORLD, 'ctr_' + loc + '_' + color) tree = makeTree( anding(conds, incrementMatrix(vicsInLocOfClrKey, -1), noChangeMatrix(vicsInLocOfClrKey))) self.world.setDynamics(vicsInLocOfClrKey, action, tree) # white: increment vicsInLocOfClrKey = stateKey(WORLD, 'ctr_' + loc + '_' + WHITE_STR) tree = makeTree( anding(conds, incrementMatrix(vicsInLocOfClrKey, 1), noChangeMatrix(vicsInLocOfClrKey))) self.world.setDynamics(vicsInLocOfClrKey, action, tree) # Fov update to white tree = { 'if': longEnough, True: setToConstantMatrix(fov_key, WHITE_STR), False: noChangeMatrix(fov_key) } self.world.setDynamics(fov_key, action, makeTree(tree)) # Color saved counter: increment saved_key = stateKey(agent.name, 'numsaved_' + color) tree = { 'if': longEnough, True: incrementMatrix(saved_key, 1), False: noChangeMatrix(saved_key) } self.world.setDynamics(saved_key, action, makeTree(tree)) # Color saved: according to difference diff = {makeFuture(saved_key): 1, saved_key: -1} saved_key = stateKey(agent.name, 'saved_' + color) self.world.setDynamics(saved_key, action, makeTree(dynamicsMatrix(saved_key, diff))) self.world.setDynamics( saved_key, True, makeTree(setFalseMatrix(saved_key))) # default: set to False # increment time self.world.setDynamics( self.world.time, action, makeTree(incrementMatrix(self.world.time, threshold))) self.triageActs[agent.name][color] = action