def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution. You may also want to use util.manhattanDistance to calculate the distance between a particle and Pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** MODIFIED CODE HERE ***" noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() allPossible = util.Counter() if noisyDistance == None: allPossible[self.getJailPosition()] = 1.0 else: allPossible = util.Counter() for p in self.particleList: dist = util.manhattanDistance(p, pacmanPosition) allPossible[p] += emissionModel[dist] if allPossible.totalCount() == 0: self.initializeUniformly(gameState) return allPossible.normalize() self.beliefs = allPossible for i in range(self.numParticles): newPos = util.sample(self.beliefs) self.particleList[i] = newPos
def observe(self, observation, gameState): "Update beliefs based on the given distance observation." emissionModel = busters.getObservationDistribution(observation) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" weights = util.Counter() hasNonZero = False for p in self.particles: distance = util.manhattanDistance(p, pacmanPosition) prob = emissionModel[distance] weights[p] += prob if(prob > 0): hasNonZero = True if (not hasNonZero): newParticles = [] for i in range(self.numParticles): ghostPos = random.choice(self.legalPositions) newParticles.append(ghostPos) self.particles = newParticles return resampledParticles = [] for i in range(self.numParticles): resampledParticles.append(util.sample(weights)) self.particles = resampledParticles
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position (2 * i + 1, 1), where "i" is the 0-based index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of 999 (a noisy distance of 999 will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. """ pacmanPos = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] jailed = [ noisy == 999 for noisy in noisyDistances ] partials = [ tuple() ] * self.numParticles for g in xrange(self.numGhosts): weighted = util.Counter() if jailed[g]: # handle the jailed ghost jailLocation = (2 * g + 1, 1) for i in xrange(self.numParticles): partials[i] += (jailLocation, ) continue for oldAssign, counts in self.sampledCounts.iteritems(): for assign, oldCount in counts.iteritems(): if oldCount <= 0: continue trueDistance = util.manhattanDistance(pacmanPos, assign[g]) delta = abs(trueDistance - noisyDistances[g]) if emissionModels[g][trueDistance] > 0 and delta <= MAX_DIST_DELTA: # no need to normalize by constant pTrue = math.exp( -delta ) weighted[assign[g]] = oldCount * emissionModels[g][trueDistance] * pTrue / self.proposals[oldAssign][assign] totalWeight = weighted.totalCount() if totalWeight != 0: weighted.normalize() for i in xrange(self.numParticles): if totalWeight == 0: # handle the zero weights case partials[i] += (random.choice(self.legalPositions), ) else: partials[i] += (util.sample(weighted), ) self.particles = CounterFromIterable(partials)
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, **all** particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution You may also want to use util.manhattanDistance to calculate the distance between a particle and pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" newBeliefs = util.Counter() beliefs = self.getBeliefDistribution() # Special Case #1 # this will handle the case when pacman captures a ghost, it will update the # particles to reflect this change if noisyDistance == None: newBeliefs[self.getJailPosition()] = 1 # go through all the legal positions and calculate their manhattan distance # to pacman's position else: for p in self.legalPositions: distance = util.manhattanDistance(p, pacmanPosition) # if the probability of that distance is greater than zero, than recalculate # the new beliefs as accounting for that probability if emissionModel[distance] > 0: newBeliefs[p] = emissionModel[distance] * beliefs[p] newBeliefs.normalize() # Special Case #2 # when all the particles have a weight of 0, we reinitialize if newBeliefs.totalCount() == 0: self.initializeUniformly(self.numParticles) return self.particles = [util.sample(newBeliefs) for _ in range(self.numParticles)]
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" #first special case for i in xrange(self.numGhosts): if noisyDistances[i]==None: for x, y in enumerate(self.particles): self.particles[x] = self.getParticleWithGhostInJail(y, i) #create a weighted particle distribution weightedParticleDistri = util.Counter() for particle in self.particles: product = 1 for i in xrange(self.numGhosts): if noisyDistances[i]!=None: trueDistance = util.manhattanDistance(particle[i], pacmanPosition) product *= emissionModels[i][trueDistance] weightedParticleDistri[particle] += product # second special case if weightedParticleDistri.totalCount()==0: self.initializeParticles() #change all particles with all the eaten ghosts' positions changed to their respective jail positions for i in xrange(self.numGhosts): if noisyDistances[i]==None: for x, y in enumerate(self.particles): self.particles[x] = self.getParticleWithGhostInJail(y, i) else: # resampling self.particles = [util.sample(weightedParticleDistri) for particle in self.particles]
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. Remember to change particles to jail if called for. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() # check if all weights are zero def zeroWeights(weights): return all(w == 0 for w in weights.values()) prevBelief = self.getBeliefDistribution() allPossible = util.Counter() nextParticles = [] # ghost captured if noisyDistance is None: jailPosition = self.getJailPosition() # put ghost to jail for i in range(self.numParticles): nextParticles.append(jailPosition) self.particles = nextParticles else: # update beliefs for pos in self.legalPositions: trueDistance = util.manhattanDistance(pos, pacmanPosition) allPossible[pos] += emissionModel[trueDistance] * prevBelief[pos] # weights all zero if zeroWeights(allPossible): self.initializeUniformly(gameState) else: # resample particles for i in range(self.numParticles): nextParticles.append(util.sample(allPossible)) self.particles = nextParticles
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of 0) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" weighted, particles = util.Counter(), list() for particle in self.particles: ghostPositions, weight = list(particle), 1 for ghost in range(self.numGhosts): manhattan = util.manhattanDistance(ghostPositions[ghost], pacmanPosition) if noisyDistances[ghost] is None: particle = self.getParticleWithGhostInJail(particle, ghost) else: weight *= emissionModels[ghost][manhattan] weighted[particle] += weight weighted.normalize() if weighted.totalCount() != 0: for i in range(self.numParticles): particles.append(util.sampleFromCounter(weighted)) else: self.initializeParticles() particles = self.particles for ghost in range(self.numGhosts): if noisyDistances[ghost] is None: for i in range(self.numParticles): particles[i] = self.getParticleWithGhostInJail(self.particles[i], ghost) self.particles = particles
def observe(self, observation, gameState): """ Updates beliefs based on the distance observation and Pacman's position. The noisyDistance is the estimated manhattan distance to the ghost you are tracking. The emissionModel below stores the probability of the noisyDistance for any true distance you supply. That is, it stores P(noisyDistance | TrueDistance). self.legalPositions is a list of the possible ghost positions (you should only consider positions that are in self.legalPositions). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() # Replace this code with a correct observation update updatedBeliefs = util.Counter() if(noisyDistance != 999): for p in self.legalPositions: trueDistance = util.manhattanDistance(p, pacmanPosition) if emissionModel[trueDistance] > 0: updatedBeliefs[p] = emissionModel[trueDistance] * self.beliefs[p] else: # Must take care of this base case - as autograder seems to ask for it. # Setting the probability of the ghost jail cell to be 1 and rest to be 0 ghostJailPos = (2 * self.ghostAgent.index - 1, 1) updatedBeliefs[ghostJailPos] = 1.0 # MUST normalize ! updatedBeliefs.normalize() self.beliefs = updatedBeliefs
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution. You may also want to use util.manhattanDistance to calculate the distance between a particle and Pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() # First check if we ate the ghost, make all particles be the jail position if noisyDistance is None: self.particles = [self.getJailPosition() for i in range(self.numParticles)] else: new_particles = [] # This will update our beliefs weights = util.Counter() # For old particle, use the emission data to inform the new particles counted = Counter(self.particles) FoundElt = 0 for key in counted: distance = util.manhattanDistance(key, pacmanPosition) # Basically the weight to sample at from at different locations is # the number of particles at that location * P(noisydist | true dist) weights[key] = counted[key] * emissionModel[distance] if weights[key] > 0: FoundElt = 1 weights.normalize() # If we didn't get all zeroes if FoundElt: # Forward sample, only consider emission self.particles = [] for i in range(self.numParticles): self.particles.append(util.sample(weights)) else: self.initializeUniformly(gameState)
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" indexOfGhosts = [i for i in range(self.numGhosts) if noisyDistances[i] == None] allPos = util.Counter() for elem in self.particles: for i in range (len(indexOfGhosts)): elem = self.getParticleWithGhostInJail(elem, indexOfGhosts[i]) prob = 1 for i in range(self.numGhosts): if noisyDistances[i] is not None: distance = util.manhattanDistance(elem[i], pacmanPosition) prob *= emissionModels[i][distance] allPos[elem] += prob allPos.normalize() self.beliefs = allPos if allPos.totalCount() == 0: self.initializeParticles() else: for i in range(len(self.particles)): self.particles[i] = util.sample(self.beliefs)
def observe(self, observation, gameState): """ Updates beliefs based on the distance observation and Pacman's position. The noisyDistance is the estimated manhattan distance to the ghost you are tracking. The emissionModel below stores the probability of the noisyDistance for any true distance you supply. That is, it stores P(noisyDistance | TrueDistance). aka given the observation noisyDistance, what is the prob of TrueDistance? self.legalPositions is a list of the possible ghost positions (you should only consider positions that are in self.legalPositions). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() # print # print "TEST" # print newBeliefs = util.Counter() for p in self.beliefs: #for p in self.beliefs trueDis = util.manhattanDistance(p, pacmanPosition) #get the true distance from pacman to that position newBeliefs[p] = emissionModel[trueDis]*self.beliefs[p] #inference equation = old belief for that position times current belief for that position in the emission model newBeliefs.normalize() #normalize that probability self.beliefs = newBeliefs
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. Remember to change ghosts' positions to jail if called for. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] #print "pacmanPostion=",pacmanPosition #print "noisyDistances = ",noisyDistances #print "emissionModels = ",emissionModels "*** YOUR CODE HERE ***" beliefs = self.getBeliefDistribution() #print "beliefs = ",beliefs for i in range(self.numGhosts): if noisyDistances[i] != None: for particle in beliefs: ghostItemPos = particle[i] trueDis = util.manhattanDistance(ghostItemPos,pacmanPosition) beliefs[particle]*=emissionModels[i][trueDis] for i in range(self.numGhosts): if noisyDistances[i] == None: new_dis = util.Counter() for key in beliefs: #print "key=",key newKey = [] for j in range(self.numGhosts): if j == i: newKey.append(self.getJailPosition(i)) else: newKey.append(key[j]) #print "newKey is ",newKey new_dis[tuple(newKey)]+=beliefs[key] beliefs = new_dis if beliefs.totalCount() == 0: self.initializeParticles() else: for i in range(self.numParticles): self.particles[i] = util.sample(beliefs)
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] updated = [] for i in range(self.numGhosts): # print(noisyDistances) if noisyDistances[i] == None: for index, particle in enumerate(self.particleList): self.particleList[index] = self.getParticleWithGhostInJail(particle, i) weights = util.Counter() for particle in self.particleList: totalprob = 1 for i in range(self.numGhosts): if noisyDistances[i] != None: dist = util.manhattanDistance(particle[i], pacmanPosition) prob = emissionModels[i][dist] totalprob = totalprob * prob weights[particle] += totalprob # print(weights) weights.normalize() keys = weights.keys() distribution = weights.values() if all(val == 0 for val in distribution): self.initializeParticles() else: self.particleList = util.nSample(distribution, keys, len(self.particleList))
def observe(self, observation, gameState): "Update beliefs based on the given distance observation." emissionModel = busters.getObservationDistribution(observation) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" noisyDistance = observation newBeliefs = util.Counter() beliefs = self.getBeliefDistribution() for pos in self.legalPositions: trueDistance = util.manhattanDistance(pacmanPosition, pos) if emissionModel[trueDistance] > 0: newBeliefs[pos] = emissionModel[trueDistance] * beliefs[pos] newBeliefs.normalize() if newBeliefs.totalCount() == 0: self.initializeUniformly(gameState, self.numParticles) else: self.particles = [] for i in range (0, self.numParticles): self.particles.append(util.sampleFromCounter(newBeliefs)) if noisyDistance == 999: self.particles = [] for i in range (0, self.numParticles): self.particles.append(self.getJailPosition())
def observe(self, observation, gameState): """ Updates beliefs based on the distance observation and Pacman's position. The noisyDistance is the estimated manhattan distance to the ghost you are tracking. The emissionModel below stores the probability of the noisyDistance for any true distance you supply. That is, it stores P(noisyDistance | TrueDistance). self.legalPositions is a list of the possible ghost positions (you should only consider positions that are in self.legalPositions). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" # Replace this code with a correct observation update allPossible = util.Counter() for p in self.legalPositions: trueDistance = util.manhattanDistance(p, pacmanPosition) if emissionModel[trueDistance] > 0: allPossible[p] = self.beliefs[p] allPossible[p] *= emissionModel[trueDistance] allPossible.normalize() self.beliefs = allPossible
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances]
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, **all** particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution You may also want to use util.manhattanDistance to calculate the distance between a particle and pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" ''' print "Noisy Distance: ", noisyDistance print "Emission Model: ", emissionModel print "pacman Position: ", pacmanPosition print "self.particles: ", self.particles ''' allPossible = util.Counter() belief = self.getBeliefDistribution() #ghost has been captured if noisyDistance is None: self.particles = [] for index in range(0, self.numParticles): self.particles.append(self.getJailPosition()) else: #weighting and testing if the weights are 0 for position in self.legalPositions: trueDistance = util.manhattanDistance(position, pacmanPosition) allPossible[position] = emissionModel[trueDistance] * belief[position] if allPossible.totalCount() == 0: self.initializeUniformly(gameState) return #resampling allPossible.normalize() self.particles = [] for index in range(0, self.numParticles): newP = util.sample(allPossible) self.particles.append(newP)
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, **all** particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution You may also want to use util.manhattanDistance to calculate the distance between a particle and pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" util.raiseNotDefined()
def observe(self, observation, gameState): """ Updates beliefs based on the distance observation and Pacman's position. The noisyDistance is the estimated manhattan distance to the ghost you are tracking. The emissionModel below stores the probability of the noisyDistance for any true distance you supply. That is, it stores P(noisyDistance | TrueDistance). self.legalPositions is a list of the possible ghost positions (you should only consider positions that are in self.legalPositions). A correct implementation will handle the following special case: * When a ghost is captured by Pacman, all beliefs should be updated so that the ghost appears in its prison cell, position self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() # Replace this code with a correct observation update # Be sure to handle the jail. if noisyDistance is None: self.beliefs = util.Counter() self.beliefs[self.getJailPosition()]=1.0 else: for p in self.legalPositions: trueDistance = util.manhattanDistance(p, pacmanPosition) self.beliefs[p] = emissionModel[trueDistance]*self.beliefs[p] self.beliefs.normalize()
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position (2 * i + 1, 1), where "i" is the 0-based index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of 999 (a noisy distance of 999 will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***"
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. Remember to change particles to jail if called for. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() util.raiseNotDefined()
def observe(self, observation, gameState): noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" weights = util.Counter() i = 0 if noisyDistance == None: self.particle_positions = [] while i != self.numParticles: self.particle_positions.append(self.getJailPosition()) i += 1 else: for p in self.particle_positions: trueDistance = util.manhattanDistance(p, pacmanPosition) #maybe more than one particle per position weights[p] += emissionModel[trueDistance] if weights.totalCount() != 0: self.particle_positions = [] while i != self.numParticles: self.particle_positions.append(util.sample(weights)) i += 1 else: self.initializeUniformly(gameState)
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" counter = util.Counter() for particle in self.particles: # weight = 0 weight = 1 for i in range(0, self.numGhosts): if noisyDistances[i] != None: manDistance = util.manhattanDistance(particle[i],pacmanPosition) weight = weight * emissionModels[i][manDistance] else: listP = list(particle) listP[i] = self.getJailPosition(i) particle = tuple(listP) counter[particle] = counter[particle] + weight if any(counter.values()): particles = [] for i in range(0, self.numParticles): particles.append(util.sample(counter)) self.particles=particles else: self.initializeParticles()
def observe(self, observation, gameState): """ Updates beliefs based on the distance observation and Pacman's position. The noisyDistance is the estimated Manhattan distance to the ghost you are tracking. The emissionModel below stores the probability of the noisyDistance for any true distance you supply. That is, it stores P(noisyDistance | TrueDistance). self.legalPositions is a list of the possible ghost positions (you should only consider positions that are in self.legalPositions). A correct implementation will handle the following special case: * When a ghost is captured by Pacman, all beliefs should be updated so that the ghost appears in its prison cell, position self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() # print 'noisyDistance : ', noisyDistance # print 'emissionModel : ', emissionModel # print 'pacmanPosition : ', pacmanPosition # print '' "*** Q1 CODE STARTS HERE ***" # util.raiseNotDefined() # Replace this code with a correct observation update # Be sure to handle the "jail" edge case where the ghost is eaten # and noisyDistance is None # allPossible = util.Counter() # for p in self.legalPositions: # trueDistance = util.manhattanDistance(p, pacmanPosition) # if emissionModel[trueDistance] > 0: # allPossible[p] = 1.0 allPossibleParticle = util.Counter() for p in self.legalPositions: distance = util.manhattanDistance(p, pacmanPosition) if emissionModel[distance] > 0: allPossibleParticle[p] = emissionModel[distance] * self.beliefs[p] if noisyDistance is None: jailedGhostBelief = util.Counter() jailedGhostBelief[(2 * self.index - 1, 1)] = 1 allPossibleParticle = jailedGhostBelief "*** Q1 CODE ENDS HERE ***" allPossibleParticle.normalize() self.beliefs = allPossibleParticle
def observeState(self, gameState): pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" weights = util.Counter() for i in range(len(self.particle_positions)): temp = 1 for ghost_idx in range(self.numGhosts): if noisyDistances[ghost_idx] == None: new_particle = self.getParticleWithGhostInJail(self.particle_positions[i],ghost_idx) self.particle_positions[i] = new_particle else: trueDistance = util.manhattanDistance(self.particle_positions[i][ghost_idx],pacmanPosition) model = emissionModels[ghost_idx] temp *= model[trueDistance] weights[self.particle_positions[i]] += temp i = 0 if weights.totalCount() != 0: self.particle_positions = [] while i != self.numParticles: self.particle_positions.append(util.sample(weights)) i += 1 else: self.initializeParticles()
def observe(self, observation, gameState): """ Updates beliefs based on the distance observation and Pacman's position. The noisyDistance is the estimated manhattan distance to the ghost you are tracking. The emissionModel below stores the probability of the noisyDistance for any true distance you supply. That is, it stores P(noisyDistance | TrueDistance). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" allPossible = util.Counter() for p in self.legalPositions: trueDistance = util.manhattanDistance(p, pacmanPosition) if emissionModel[trueDistance] > 0: #allPossible[p] = 1 allPossible[p] = emissionModel[trueDistance]*self.beliefs[p] #strengthen the belief based on the positive probability vales of the possible locations of ghosts "*** YOUR CODE HERE ***" allPossible.normalize() self.beliefs = allPossible
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of 0) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() # before was a single noisyDistance if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] # before was a single one: emissionModel = busters.getObservationDistribution(noisyDistance) "*** YOUR CODE HERE ***" newWeightCounter = util.Counter() for particle in self.particleList: newWeightForParticle = 1 for index in range(0, self.numGhosts): if(noisyDistances[index] == None): particle = self.getParticleWithGhostInJail(particle, index) else: ghostsDistanceProduct = util.manhattanDistance(particle[index], pacmanPosition) newWeightForParticle *= emissionModels[index][ghostsDistanceProduct] newWeightCounter[particle] = newWeightCounter[particle] + newWeightForParticle if(not newWeightCounter.totalCount() == 0): newWeightCounter.normalize() for x in range(0, self.numParticles): self.particleList[x] = util.sample(newWeightCounter) else: #all particles receive 0 weight self.initializeParticles() for x in range(0, len(self.particleList)): for index in range(0, self.numGhosts): if(noisyDistances[index] == None): self.particleList[x] = self.getParticleWithGhostInJail(self.particleList[x], index)
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution. You may also want to use util.manhattanDistance to calculate the distance between a particle and Pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" # References: Textbook pp. 598-599 # jail edge case if noisyDistance == None: pos = self.getJailPosition() self.particles = [pos]*self.numParticles return # Step 1: calculate weightss weights = util.Counter() for pos,prob in self.getBeliefDistribution().items(): trueDistance = util.manhattanDistance(pos, pacmanPosition) weights[pos] = emissionModel[trueDistance]*prob weights.normalize() # Step 2: resample based on the weights if weights.totalCount() == 0: self.initializeUniformly(gameState) # edge case else: distribution = [] values = [] for pos, prob in weights.items(): values.append(pos) distribution.append(prob) self.particles = util.nSample(distribution, values, self.numParticles)
def observe(self, observation, gameState): """ Updates beliefs based on the distance observation and Pacman's position. The noisyDistance is the estimated Manhattan distance to the ghost you are tracking. The emissionModel below stores the probability of the noisyDistance for any true distance you supply. That is, it stores P(noisyDistance | TrueDistance). self.legalPositions is a list of the possible ghost positions (you should only consider positions that are in self.legalPositions). A correct implementation will handle the following special case: * When a ghost is captured by Pacman, all beliefs should be updated so that the ghost appears in its prison cell, position self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" """ print "############" print noisyDistance print emissionModel print pacmanPosition print self.beliefs print "############" """ # Replace this code with a correct observation update # Be sure to handle the "jail" edge case where the ghost is eaten # and noisyDistance is None allPossible = util.Counter() if(noisyDistance != None): priors = self.beliefs for p in self.legalPositions: trueDistance = util.manhattanDistance(p, pacmanPosition) priorBelief = priors[p] if emissionModel[trueDistance] > 0: allPossible[p] = priorBelief * emissionModel[trueDistance] else: for p in self.legalPositions: allPossible[p] = 0 allPossible[self.getJailPosition()] = 1 "*** END YOUR CODE HERE ***" allPossible.normalize() self.beliefs = allPossible
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. Remember to change ghosts' positions to jail if called for. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" allPossible = util.Counter() for oldParticle in self.particles: tempDist = 1.0 for i in range(self.numGhosts): if noisyDistances[i] == None: tempList = list(oldParticle) tempList[i] = self.getJailPosition(i) oldParticle = tuple(tempList) else: trueDistance = util.manhattanDistance(oldParticle[i], pacmanPosition) tempDist *= emissionModels[i][trueDistance] allPossible[oldParticle] += tempDist allPossible.normalize() # check if all particles have zero weight if list(allPossible) == [0]: self.initializeParticles() else: # resample particles tempList = [] for x in range(self.numParticles): tempList.append(util.sample(allPossible)); self.particles = tempList
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of 0) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" #check for capture for i in range(self.numGhosts): if (noisyDistances[i] == None): # Ghost is captured newList = [] for par in self.particleList: newList.append(self.getParticleWithGhostInJail(par, i)) self.particleList = newList #weight the particles weightedCounter = util.Counter() for par in self.particleList: prob = 1 for i in range(self.numGhosts): if (noisyDistances[i] == None): continue #iterative through ghost trueDistance = util.manhattanDistance(par[i], pacmanPosition) prob = prob * emissionModels[i][trueDistance] weightedCounter[par] += prob if (weightedCounter.totalCount() == 0): self.initializeParticles() return #resample newList = [] for i in range(self.numParticles): newList.append(util.sample(weightedCounter)) self.particleList = newList return
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] # iterate over all particles and then all ghosts # if ghost noisyDistances is none then it should go to prison jail # otherwise we should count probability of this ghost being in specific sell based on ebservation # and multiply all of them and add to counter allPossible = util.Counter() for index in range(0, len(self.particles)): sample = self.particles[index] probability = 1 for i in range(self.numGhosts): if noisyDistances[i] is None: self.particles[index] = self.getParticleWithGhostInJail( sample, i) sample = self.particles[index] else: trueDistance = util.manhattanDistance( sample[i], pacmanPosition) probability = probability * emissionModels[i][trueDistance] allPossible[sample] += probability if (allPossible.totalCount() == 0): self.initializeParticles() return # choose randomly from particles based on their weights self.particles = [] for i in range(self.numParticles): self.particles.append(util.sample(allPossible))
def observeState(self, gameState): """Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When all particles get weight 0 due to the observation, a new set of particles need to be generated from the initial prior distribution by calling initializeParticles. 2) Otherwise after all new particles have been generated by resampling you must check if any ghosts have been captured by packman (noisyDistances[i] will be None if ghost i has ben captured). For each captured ghost, you need to change the i'th component of every particle (remember that the particles contain a position for every ghost---so you need to change the component associated with the i'th ghost.). In particular, if ghost i has been captured then the i'th component of every particle must be changed so the i'th ghost is in its prison cell (position self.getJailPosition(i)) Note that more than one ghost might be captured---you need to ensure that every particle puts every captured ghost in its prison cell. self.getParticleWithGhostInJail is a helper method to help you edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. Note that this function creates a new particle, that has to replace the old particle in your list of particles. HINT1. The weight of every particle is the product of the probabilities of associated with each ghost's noisyDistance observation HINT2. When computing the weight of a particle by looking at each ghost's noisyDistance observation make sure you check if the ghost has been captured. Captured ghost's are ignored in the weight computation (the particle's component for the captured ghost is updated the precise position later---so this corresponds to multiplying the weight by probability 1 """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" jIndex = [] for i in range(self.numGhosts): if noisyDistances[i] is None: jIndex.append(i) counter = util.Counter() for particle in self.particles: for j in jIndex: particle = self.getParticleWithGhostInJail(particle,j) prob = 1 for i in range(self.numGhosts): if i not in jIndex: model = emissionModels[i] ghostPos = particle[i] dist = util.manhattanDistance(ghostPos,pacmanPosition) prob = prob * model[dist] counter[particle] = counter[particle] + prob self.beliefs = counter if counter.totalCount() != 0: self.beliefs.normalize() for i in range(len(self.particles)): newPos = util.sample(self.beliefs) self.particles[i] = newPos else: self.initializeParticles() "*** END YOUR CODE HERE ***"
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of 0) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" # damn this list comprehension is self explainatory jailedGhosts = [ i for i in range(self.numGhosts) if noisyDistances[i] is None ] allPossible = util.Counter() for particle in self.particles: newParticle = particle # most of jailed ghosts are captured in previous runs, but there might also be # a new captured ghost so we need to mark it as jailed for jailed in jailedGhosts: newParticle = self.getParticleWithGhostInJail( newParticle, jailed) # we start with probability 1 and then multiply for each non-jailed ghost # with the probability of it being at a certain distance newProb = 1.0 for ghost in range(self.numGhosts): if ghost not in jailedGhosts: # same as in exact inference trueDistance = util.manhattanDistance( pacmanPosition, newParticle[ghost]) newProb *= emissionModels[ghost][trueDistance] allPossible[newParticle] += newProb self.beliefs = allPossible self.beliefs.normalize() # make new particles from obtained beliefs if self.beliefs.totalCount() == 0: self.initializeParticles() else: self.particles = [ util.sample(self.beliefs) for i in range(self.numParticles) ]
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" # Checking if noisyDistance is None i.e prison cell and hence making the probability of the belief of prison cell 1 for i in range(self.numGhosts): if noisyDistances[i] == None: self.particles = [ self.getParticleWithGhostInJail(p, i) for p in self.particles ] weightedParticles = util.Counter() allPossible = util.Counter() #changing the probability of beliefs using formula (new_prob = old_prob * conditional_prob) same as bayes net P(h/D) = P(D/h)*P(h) for p in self.particles: weightedParticles[p] = 1 for i in range(self.numGhosts): if noisyDistances[i] != None: trueDistance = util.manhattanDistance(p[i], pacmanPosition) weightedParticles[p] *= emissionModels[i][trueDistance] weightedParticles.normalize() self.particleWeights = util.Counter() for p in self.particles: self.particleWeights[p] += 1.0 for p in self.particles: if p not in allPossible: allPossible[p] = weightedParticles[p] * self.particleWeights[p] allPossible.normalize() self.beliefs = allPossible if self.beliefs.totalCount() == 0: self.initializeParticles() for i in range(self.numGhosts): if noisyDistances[i] == None: self.particles = [ self.getParticleWithGhostInJail(p, i) for p in self.particles ] else: self.particles = [ util.sample(self.beliefs) for i in range(self.numParticles) ]
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" weight = util.Counter() for p in self.particles: particleList = list(p) particleWeight = 1 for i in range(self.numGhosts): trueDistance = util.manhattanDistance(particleList[i], pacmanPosition) if noisyDistances[i] == None: p = self.getParticleWithGhostInJail(p, i) emission = 1 particleWeight *= emission else: emission = emissionModels[i] particleWeight *= emission[trueDistance] weight[p] += particleWeight weight.normalize() tempList = [] tempList2 = [] if weight.totalCount() == 0: self.initializeParticles() tempList = self.particles for i in range(self.numGhosts): if noisyDistances[i] == None: for p in range(self.numParticles): tempList[p] = self.getParticleWithGhostInJail( self.particles[p], i) self.particles = tempList else: for i in range(self.numParticles): tempList2.append(util.sampleFromCounter(weight)) self.particles = tempList2
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] currentDistribution = self.getBeliefDistribution() # Create new distribution model newDistribution = util.Counter() for state, stateProb in currentDistribution.iteritems(): newProb = stateProb for ghostIndex in range(self.numGhosts): # If ghost is in jail if noisyDistances[ghostIndex] == None: state = self.getParticleWithGhostInJail(state, ghostIndex) else: trueDistance = util.manhattanDistance(state[ghostIndex], pacmanPosition) newProb *= emissionModels[ghostIndex][trueDistance] newDistribution[state] = newProb # Handle some edge cases if newDistribution.totalCount() == 0.0: self.initializeParticles() newDistribution = self.getBeliefDistribution() # Using new distribution sample particles items = sorted(newDistribution.items()) distribution = [i[1] for i in items] values = [i[0] for i in items] newListOfSamples = util.nSample(distribution, values, self.numParticles) self.particles = newListOfSamples
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ def jailGhosts(particle): newParticle = list(particle) for ghost in range(self.numGhosts): if noisyDistances[ghost] is None: newParticle[ghost] = self.getJailPosition(ghost) return tuple(newParticle) pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] # Distribution of particles distribution = util.Counter() for particle in self.particles: prob = 1.0 for ghost in range(self.numGhosts): if noisyDistances[ghost] is not None: distance = util.manhattanDistance(pacmanPosition, particle[ghost]) prob *= emissionModels[ghost][distance] distribution[particle] += prob # If all particles have 0 weight, recreate from the prior distribution if distribution.totalCount() == 0: self.initializeParticles() self.particles = map(jailGhosts, self.particles) return newParticles = [] for i in range(self.numParticles): particle = util.sample(distribution) particle = jailGhosts(particle) newParticles.append(tuple(particle)) self.particles = newParticles
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" # instanciate grid world grid = util.Counter() for particle in self.particles: prob = 1.0 # loop throgh ghots for index in range(self.numGhosts): # ghost is in jail if noisyDistances[index] == None: particle = self.getParticleWithGhostInJail(particle, index) # get distance from ghost and update prob elif prob != 0: man_distance = util.manhattanDistance(particle[index], pacmanPosition) prob = prob * emissionModels[index][man_distance] # update grid grid[particle] = grid[particle] + prob # all ghosts are in jail if sum(grid.values()) == 0: self.initializeParticles() return # normalyze geid world and instanciate relevant grid.normalize() self.particles = [] counter = 0 # resample particles based on state of the grid while counter < self.numParticles: particle = util.sample(grid) self.particles.append(particle) counter = counter + 1
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. Remember to change ghosts' positions to jail if called for. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" """allPossible = util.Counter() for p in self.particlesList: for i in range(self.numGhosts): if noisyDistances[i] == None: listP = list(particle) listP[g] = self.getJailPosition(g) particle = tuple(listP) else: trueDistance = util.manhattanDistance(p[i], pacmanPosition) weight *= emissionModels[i][trueDistance] allPossible[p] += weight if allPossible.totalCount() == 0: self.initializeUniformly(gameState) else: self.particlesList = [] for i in range(self.numParticles): self.particlesList.append(util.sample(allPossible)) """ beliefDis = self.getBeliefDistribution() for i in range(self.numGhosts): if noisyDistances[i] != None: for particle in beliefDis: ghost_pos = particle[i] trueDistance = util.manhattanDistance( ghost_pos, pacmanPosition) beliefDis[particle] *= emissionModels[i][trueDistance] for i in range(self.numGhosts): if noisyDistances[i] == None: new_dis = util.Counter() for particle in beliefDis: new_dis[self.getParticleWithGhostInJail( particle, i)] += beliefDis[particle] beliefDis = new_dis if beliefDis.totalCount() == 0: self.initializeParticles() else: for i in xrange(self.numParticles): self.particles[i] = util.sample(beliefDis)
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" allPossible = util.Counter() #updates the weight for each particle for part in self.particles: weight = 1 for i in range(self.numGhosts): #ghost in jail, changes particle location to jail if noisyDistances[i] == None: part = self.getParticleWithGhostInJail(part, i) else: #ghost not in jail #updates weightrs weight = weight * emissionModels[i][util.manhattanDistance( part[i], pacmanPosition)] #if ghost in jail, weight is now in Jail #if ghost is not in jail, weight is updated nomrally with the particle allPossible[part] = allPossible[part] + weight #checks if all particles are valued at 0, and resets if sum(allPossible.values()) == 0: self.initializeParticles() else: allPossible.normalize() self.particles = [] for i in range(self.numParticles): self.particles.append(tuple(util.sample(allPossible)))
def observeState(self, gameState): """Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When all particles get weight 0 due to the observation, a new set of particles need to be generated from the initial prior distribution by calling initializeParticles. 2) Otherwise after all new particles have been generated by resampling you must check if any ghosts have been captured by packman (noisyDistances[i] will be None if ghost i has ben captured). For each captured ghost, you need to change the i'th component of every particle (remember that the particles contain a position for every ghost---so you need to change the component associated with the i'th ghost.). In particular, if ghost i has been captured then the i'th component of every particle must be changed so the i'th ghost is in its prison cell (position self.getJailPosition(i)) Note that more than one ghost might be captured---you need to ensure that every particle puts every captured ghost in its prison cell. self.getParticleWithGhostInJail is a helper method to help you edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. Note that this function creates a new particle, that has to replace the old particle in your list of particles. HINT1. The weight of every particle is the product of the probabilities of associated with each ghost's noisyDistance observation HINT2. When computing the weight of a particle by looking at each ghost's noisyDistance observation make sure you check if the ghost has been captured. Captured ghost's are ignored in the weight computation (the particle's component for the captured ghost is updated the precise position later---so this corresponds to multiplying the weight by probability 1 """ # emissionModel[dist(p)] = Pr(et|xt=p). pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" # for each distinct particle, compute weight as sum of weights of all the same particle # for each particle, compute weight as product of porobability of each postion in that particle. weights = util.Counter() for particle in self.particles: product = 1.0 for i in range(self.numGhosts): if noisyDistances[i] == None: particle = self.getParticleWithGhostInJail(particle, i) else: product *= emissionModels[i][util.manhattanDistance( particle[i], pacmanPosition)] weights[particle] += product if weights.totalCount() > 0: weights.normalize() for i in range(self.numParticles): self.particles[i] = util.sample(weights) else: # case 1 self.initializeParticles() for index, particle in enumerate(self.particles): # case 2 for i in range(self.numGhosts): if noisyDistances[i] == None: self.particles[index] = self.getParticleWithGhostInJail( particle, i) "*** END YOUR CODE HERE ***"
def observe(self, observation, gameState): """Updates beliefs based on the distance observation and Pacman's position. When we enter this function pacman's distribution over possible locations of the ghost are stored in self.beliefs For any position p: self.beliefs[p] = Pr(Xt=p | e_{t-1}, e_{t-2}, ..., e_1) That is, pacman's distribution has already been updated by all prior observations already. This function should update self.beliefs[p] so that self.beliefs[p] = Pr(Xt=p |e_t, e_{t-1}, e_{t-2}, ..., e_1) That is, it should update pacman's distribution over the ghost's locations to account for the passed observation. noisyDistance (= the next observation e_t) is the estimated Manhattan distance to the ghost you are tracking. emissionModel = busters.getObservationDistribution(noisyDistance) stores the probability of having observed noisyDistance given any true distance you supply. That is emissionModel[trueDistance] = Pr(noisyDistance | trueDistance). Since our observations have to do with manhattanDistance with no indication of direction, we take Pr(noisyDistance | Xt=p) = Pr(noisyDistance | manhattanDistance(p,packmanPosition)) That is, the probability of observing noisyDistance given that the ghost is in position p is equal to the probability of having observed noisyDistance given the trueDistance between p and the pacman's current position. self.legalPositions is a list of the possible ghost positions (Only positions in self.legalPositions need to have their probability updated) A correct implementation will handle the following special case: * When a ghost is captured by Pacman, all beliefs should be updated so that pacman believes the ghost to be in its prison cell with probability 1, this position is self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured, note 0 != None). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" #the code below updates pacman's beliefs so that it #has a uniform distribution over all possible positions #the ghost could be. # # Replace this code with a correct observation update # Be sure to handle the "jail" edge case where the ghost is eaten # and noisyDistance is None #print(self.getJailPosition()) #print(noisyDistance) #print(emissionModel) #print(pacmanPosition) #print(self.beliefs) #print(self.legalPositions) # The counter class is an extension of the standard pythoy dictionary type beliefs = util.Counter() if noisyDistance == None: beliefs[self.getJailPosition()] = 1.0 else: for ghostPosition in self.legalPositions: distance = util.manhattanDistance(ghostPosition, pacmanPosition) # emissionModel[trueDistance] = Pr(noisyDistance | trueDistance) = Pr(et|xt) # self.beliefs[p] = Pr(Xt=p |e_t, e_{t-1}, e_{t-2}, ..., e_1) beliefs[ghostPosition] = emissionModel[ distance] * self.beliefs[ghostPosition] "*** END YOUR CODE HERE ***" beliefs.normalize() self.beliefs = beliefs
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" newBeliefDist = util.Counter() eatenGhostsIndex = [] for i in range(self.numGhosts): if noisyDistances[i] is None: eatenGhostsIndex.append(i) for particle in self.particles: # Update for eaten Ghosts for i in eatenGhostsIndex: particle = self.getParticleWithGhostInJail(particle, i) prob = 1 # For not eaten Ghosts for i in range(self.numGhosts): if i not in eatenGhostsIndex: trueDistance = util.manhattanDistance( particle[i], pacmanPosition) prob *= (emissionModels[i])[trueDistance] newBeliefDist[particle] += prob if newBeliefDist.totalCount() == 0: self.initializeParticles() else: newBeliefDist.normalize() for pos in range(len(self.particles)): self.particles[pos] = util.sample(newBeliefDist)
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" #first special case for i in xrange(self.numGhosts): if noisyDistances[i] == None: for x, y in enumerate(self.particles): self.particles[x] = self.getParticleWithGhostInJail(y, i) #create a weighted particle distribution weightedParticleDistri = util.Counter() for particle in self.particles: product = 1 for i in xrange(self.numGhosts): if noisyDistances[i] != None: trueDistance = util.manhattanDistance( particle[i], pacmanPosition) product *= emissionModels[i][trueDistance] weightedParticleDistri[particle] += product # second special case if weightedParticleDistri.totalCount() == 0: self.initializeParticles() #change all particles with all the eaten ghosts' positions changed to their respective jail positions for i in xrange(self.numGhosts): if noisyDistances[i] == None: for x, y in enumerate(self.particles): self.particles[x] = self.getParticleWithGhostInJail( y, i) else: # resampling self.particles = [ util.sample(weightedParticleDistri) for particle in self.particles ]
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" # jail edge case for i in range(self.numGhosts): if noisyDistances[i] == None: pos = self.getJailPosition(i) for j,particle in enumerate(self.particles): self.particles[j] = self.getParticleWithGhostInJail(particle,i) # Step 1: calculate weights weights = util.Counter() for particle,N in self.getBeliefDistribution().items(): trueDistance = util.manhattanDistance(particle[i], pacmanPosition) prob = 1.0 for i in range(self.numGhosts): if noisyDistances[i] != None: distance = util.manhattanDistance(particle[i], pacmanPosition) prob *= emissionModels[i][distance] weights[particle] += prob*N weights.normalize() # Step 2: resample based on the weights if weights.totalCount() == 0: self.initializeParticles() # edge case else: distribution = [] values = [] for pos, prob in weights.items(): values.append(pos) distribution.append(prob) self.particles = util.nSample(distribution, values, self.numParticles)
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" allPossible = util.Counter() for i in range(self.numParticles): prob = 1 each = self.particleslist[i] # print("!!!!!!!!!!") # print(each) for j in range(self.numGhosts): noisydis = noisyDistances[j] emissionmod = emissionModels[j] if noisydis ==None: each = self.getParticleWithGhostInJail(each,j) else: trueDistance = util.manhattanDistance(each[j], pacmanPosition) prob *=emissionmod[trueDistance] allPossible[each]+=prob allPossible.normalize() if allPossible.totalCount()==0: self.initializeParticles() else: samplelist = [] count = 0 while count < self.numParticles: samplelist.append(util.sample(allPossible)) count +=1 self.particleslist = samplelist
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" ghostIndexJail = [] for i in range(self.numGhosts): if noisyDistances[i] == None: ghostIndexJail.append(i) newParticles = util.Counter() # Creating all particles for p in self.particles: for ghosts in ghostIndexJail: p = self.getParticleWithGhostInJail(p, ghosts) probability = 1 for i in range(self.numGhosts): if i not in ghostIndexJail: em = emissionModels[i] #true distance dist = util.manhattanDistance(p[i], pacmanPosition) probability *= em[dist] # particle newParticles[p] += probability self.beliefs = newParticles # same as previous question # If all values are zero .i.e sum should be zero # then initialze partciles if newParticles.totalCount() == 0: self.initializeParticles() else: self.beliefs.normalize() for i in range(len(self.particles)): newPos = util.sample(self.beliefs) self.particles[i] = newPos
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution. You may also want to use util.manhattanDistance to calculate the distance between a particle and Pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" allPossible = util.Counter() weightedParticles = util.Counter() particlesDistribution = util.Counter() # Checking if noisyDistance is None i.e prison cell and hence making the probability of the belief of prison cell 1 if noisyDistance == None: self.particles = [ self.getJailPosition() for i in range(self.numParticles) ] allPossible[self.getJailPosition()] = 1 self.beliefs = allPossible else: #changing the probability of beliefs using formula (new_prob = old_prob * conditional_prob) same as bayes net P(h/D) = P(D/h)*P(h) for p in self.particles: trueDistance = util.manhattanDistance(p, pacmanPosition) allPossible[ p] = self.particleWeights[p] * emissionModel[trueDistance] weightedParticles[p] += 1 allPossible.normalize() self.beliefs = allPossible self.particleWeights = weightedParticles if allPossible.totalCount() == 0: self.initializeUniformly(gameState) else: self.particles = [ util.sample(self.beliefs) for i in range(self.numParticles) ] self.particleWeights = util.Counter() for p in self.particles: self.particleWeights[p] += 1.0
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ import functools pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] particleWeights = [] #if ghost is eaten place it in jail with a probability of 1 #for p in self.particles: # for i in range(self.numGhosts): # if noisyDistances[i] == None: # p = self.getParticleWithGhostInJail(p, i) # jailGhost, res = float('inf'), self.doJailCheck(noisyDistances) # if res[1] is True: jailGhost = res[0] jailCondition = False #weighting the particles for index, p in enumerate(self.particles): listOfLocationWeights = [] # loop through all ghosts for i in range(self.numGhosts): if noisyDistances[i] != None: # find the true distance from pacman to the current ghost that we're iterating through trueDistance = util.manhattanDistance(p[i], pacmanPosition) # weight each particle by the probability of getting to that position (use emission model) # account for our current belief distribution (evidence) at this point in time listOfLocationWeights.append( emissionModels[i][trueDistance]) #* currentBeliefs[p]) else: self.particles[index] = self.getParticleWithGhostInJail( p, i) jailCondition = True break #self.particles = [self.getParticleWithGhostInJail(p, i) for p in self.particles] #continue if len(listOfLocationWeights) != 0: particleWeights.append( functools.reduce(lambda x, y: x * y, listOfLocationWeights)) else: particleWeights.append(0) #if not jailCondition: # now create a counter and count up the particle weights observed particleDictionary = util.Counter() #for i in range(self.numParticles): for index, p in enumerate(self.particles): #particleDictionary[self.particles[i]] += particleWeights[i] particleDictionary[p] += particleWeights[index] particleDictionary.normalize() # 2) if all particles have 0 weight, recreate prior distribution #print particleDictionary.totalCount() == 0 if particleDictionary.totalCount() == 0: self.initializeParticles() self.doJailCheck(noisyDistances) # otherwise, go ahead and resample based on our new beliefs else: keys = [] values = [] # find each key, value pair in our counter keys, values = zip(*particleDictionary.items()) # resample self.particles self.particles = util.nSample(values, keys, self.numParticles) self.doJailCheck(noisyDistances)
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, **all** particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution You may also want to use util.manhattanDistance to calculate the distance between a particle and pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" allPossible = util.Counter() if noisyDistance is None: # if ghost is captured, mark it so allPossible[self.getJailPosition()] = 1.0 else: for p in self.particles: # for each particle get the position and add the probability trueDistance = util.manhattanDistance(pacmanPosition, p) if emissionModel[trueDistance] > 0: # add the probability to be at distance trueDistance allPossible[p] += emissionModel[trueDistance] # make sure we have sum = 1 over probabilities allPossible.normalize() self.beliefs = allPossible newParticles = [] if self.beliefs.totalCount() == 0: # this conditional branch is pretty much stated in the requirement self.initializeUniformly(gameState) else: # the next particles will be samples from current beliefs # if a belief from the current state has a high probability, then it will happen more # often, and will have more particles in that position # the more a position appears in the particles, the higher the probability # that a ghost is there self.particles = [ util.sample(allPossible) for i in range(len(self.particles)) ]
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. Remember to change ghosts' positions to jail if called for. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" for i in range(self.numGhosts): if noisyDistances[i] is None: for ptc in self.particles[:]: ptc = list(ptc) ptc[i] = self.getJailPosition(i) self.particles.append(tuple(ptc)) weighted = util.Counter() for particle in self.particles: weighted_ptc = 1.0 for i in range(self.numGhosts): if noisyDistances[i] is not None: weighted_ptc *= emissionModels[i][util.manhattanDistance( pacmanPosition, particle[i])] weighted[particle] += weighted_ptc weighted.normalize() if weighted.totalCount() == 0: self.initializeParticles() for i in range(self.numGhosts): if noisyDistances[i] is None: for ptc in self.particles[:]: ptc = list(ptc) ptc[i] = self.getJailPosition(i) self.particles.append(tuple(ptc)) else: self.particles = [ util.sample(weighted) for i in range(self.numParticles) ]
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of 0) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" for i in range(self.numGhosts): if noisyDistances[i] is None: self.particles = [ self.getParticleWithGhostInJail(particle, i) for particle in self.particles[:] ] weightedParticles = util.Counter() for particle in self.particles: weightedParticle = 1.0 for i in range(self.numGhosts): if noisyDistances[i] is not None: weightedParticle *= emissionModels[i][ util.manhattanDistance(pacmanPosition, particle[i])] weightedParticles[particle] += weightedParticle weightedParticles.normalize() if weightedParticles.totalCount() == 0: self.initializeParticles() for i in range(self.numGhosts): if noisyDistances[i] is None: self.particles = [ self.getParticleWithGhostInJail(particle, i) for particle in self.particles[:] ] else: self.particles = [ util.sample(weightedParticles) for i in range(self.numParticles) ]
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] allPossible = util.Counter() for particle in self.particles: accrueProb = 1.0 for ghost in range(self.numGhosts): # handle a ghost in jail by updating the particle if noisyDistances[ghost] == None: particle = self.getParticleWithGhostInJail(particle, ghost) else: trueDistance = util.manhattanDistance( particle[ghost], pacmanPosition) accrueProb *= emissionModels[ghost][trueDistance] allPossible[particle] += accrueProb # handle all particles getting a weight of zero by starting again if allPossible.totalCount() == 0: self.initializeParticles() # add back the information for ghosts in jail for ghost in range(self.numGhosts): if noisyDistances[ghost] == None: for j, particle in enumerate(self.particles): self.particle[j] = self.getParticleWithGhostInJail( particle, ghost) else: # rebuild the particle list for next time! self.particles = [] allPossible.normalize() for index in range(self.numParticles): self.particles.append(util.sample(allPossible))
def observe(self, observation, gameState): """Updates beliefs based on the distance observation and Pacman's position. When we enter this function pacman's distribution over possible locations of the ghost are stored in self.beliefs For any position p: self.beliefs[p] = Pr(Xt=p | e_{t-1}, e_{t-2}, ..., e_1) That is, pacman's distribution has already been updated by all prior observations already. This function should update self.beliefs[p] so that self.beliefs[p] = Pr(Xt=p |e_t, e_{t-1}, e_{t-2}, ..., e_1) That is, it should update pacman's distribution over the ghost's locations to account for the passed observation. noisyDistance (= the next observation e_t) is the estimated Manhattan distance to the ghost you are tracking. emissionModel = busters.getObservationDistribution(noisyDistance) stores the probability of having observed noisyDistance given any true distance you supply. That is emissionModel[trueDistance] = Pr(noisyDistance | trueDistance). Since our observations have to do with manhattanDistance with no indication of direction, we take Pr(noisyDistance | Xt=p) = Pr(noisyDistance | manhattanDistance(p,packmanPosition)) That is, the probability of observing noisyDistance given that the ghost is in position p is equal to the probability of having observed noisyDistance given the trueDistance between p and the pacman's current position. self.legalPositions is a list of the possible ghost positions (Only positions in self.legalPositions need to have their probability updated) A correct implementation will handle the following special case: * When a ghost is captured by Pacman, all beliefs should be updated so that pacman believes the ghost to be in its prison cell with probability 1, this position is self.getJailPosition() You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured, note 0 != None). """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() allPossible = util.Counter() if noisyDistance is None: allPossible[self.getJailPosition] = 1 else: for p in self.legalPositions: allPossible[p] = self.beliefs[p] * \ emissionModel[util.manhattanDistance( p, pacmanPosition)] allPossible.normalize() self.beliefs = allPossible
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" allPossible = util.Counter() old_beliefs = self.getBeliefDistribution() for ind, particle in enumerate(self.particles): par = 1.0 for i in range(self.numGhosts): if (noisyDistances[i] == None): particle = self.getParticleWithGhostInJail(particle, i) else: dist = util.manhattanDistance(particle[i], pacmanPosition) par = par * emissionModels[i][dist] allPossible[particle] += par if not any(allPossible.values()): self.initializeParticles() for ind, particle in enumerate(self.particles): for i in range(self.numGhosts): if (noisyDistances[i] == None): particle = self.getParticleWithGhostInJail(particle, i) else: allPossible.normalize() temp = [] for i in range(self.numParticles): temp.append(util.sample(allPossible)) self.particles = temp
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" allPossible = util.Counter() place = 0 for number in self.particles: remainder = 1.0 for num in range(self.numGhosts): # examining case if noisyDistances[num] is None: number = self.getParticleWithGhostInJail(number, num) else: gameRange = util.manhattanDistance(number[num], pacmanPosition) remainder = remainder * emissionModels[num][gameRange] allPossible[number] = allPossible[number] + remainder place = place + 1 if not any(allPossible.values()): self.initializeParticles() place = 0 for number in self.particles: for num in range(self.numGhosts): # examining case if noisyDistances[num] is not None: break else: number = self.getParticleWithGhostInJail(number, num) place = place + 1 else: allPossible.normalize() store = [] for number in range(self.numParticles): store.append(util.sample(allPossible)) self.particles = store
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution. You may also want to use util.manhattanDistance to calculate the distance between a particle and Pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() "*** YOUR CODE HERE ***" # initialize the counter and retrieve belief distribution allPossible = util.Counter() beliefs = self.getBeliefDistribution() # Case 1 # update all particles when ghost is eaten (noisyDistance == None) if noisyDistance == None: # do this as a list because our particles are in a list jailPositionList = [self.getJailPosition()] self.particlesList = self.numParticles * jailPositionList else: # similar to q2 for p in self.legalPositions: # retrieve true distance to each location and noisy trueDistance = util.manhattanDistance(p, pacmanPosition) probabilityOfNoisyGivenTrue = emissionModel[trueDistance] # we want to keep summing them according to the particle allPossible[p] = allPossible[p] + (beliefs[p] * probabilityOfNoisyGivenTrue) # Check whether particles all have a weight of 0 and initialize uniformly if true if allPossible.totalCount() == 0: self.initializeUniformly(gameState) else: # iterate through particles particleSampleDistribution = list() # create the samples from the distribution based on new counter for _ in range(self.numParticles): particleSampleDistribution.append(util.sample(allPossible)) self.particlesList = particleSampleDistribution
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [busters.getObservationDistribution(dist) for dist in noisyDistances] "*** YOUR CODE HERE ***" # counter possibleCounter = util.Counter() for _, particle in enumerate(self.particles): prior = 1 # for each ghost for i in range(self.numGhosts): # check the first case for eaten ghost if noisyDistances[i] is None: particle = self.getParticleWithGhostInJail(particle, i) # else calculate the actual distance to get the partial/priority else: distance = util.manhattanDistance(pacmanPosition, particle[i]) noisyDistance = emissionModels[i][distance] prior = prior * noisyDistance # add prior to particle possibleCounter[particle] = possibleCounter[particle] + prior # check for counter values all = 0 if possibleCounter.totalCount() == 0: self.initializeParticles() # set particle to jailed ghost because found for particle in self.particles: for i in range(self.numGhosts): if noisyDistances[i] == None: particle = self.getParticleWithGhostInJail(particle, i) else: # else normalize and resample it for particle list possibleCounter.normalize() newParticleList = list() for _ in range(self.numParticles): newParticleList.append(util.sample(possibleCounter)) self.particles = newParticleList
def observe(self, observation, gameState): """ Update beliefs based on the given distance observation. Make sure to handle the special case where all particles have weight 0 after reweighting based on observation. If this happens, resample particles uniformly at random from the set of legal positions (self.legalPositions). A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, self.getJailPosition() As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeUniformly. The total weight for a belief distribution can be found by calling totalCount on a Counter object util.sample(Counter object) is a helper method to generate a sample from a belief distribution. You may also want to use util.manhattanDistance to calculate the distance between a particle and Pacman's position. """ noisyDistance = observation emissionModel = busters.getObservationDistribution(noisyDistance) pacmanPosition = gameState.getPacmanPosition() allPossible = util.Counter() # 1) if ghost is eaten place it in jail with a probability of 1 if noisyDistance == None: temp = [] for p in range(len(self.particles)): temp.append(self.getJailPosition()) self.particles = temp # otherwise go ahead ahead and create our counter else: currentBeliefs = self.getBeliefDistribution() for p in self.particles: # find the true distance from pacman to each particle trueDistance = util.manhattanDistance(p, pacmanPosition) if emissionModel[trueDistance] > 0: # weight each particle by the probability of getting to that position (use emission model) # account for our current belief distribution (evidence) at this point in time allPossible[ p] = emissionModel[trueDistance] * currentBeliefs[p] # 2) if all particles have 0 weight, recreate prior distribution if allPossible.totalCount() == 0: self.initializeUniformly(gameState) # otherwise, go ahead and resample based on our new beliefs else: keys = [] values = [] # find each key, value pair in our counter for key, value in allPossible.items(): keys.append(key) values.append(value) # resample self.particles self.particles = util.nSample(values, keys, self.numParticles)