2016-03-19 25 views
0

Bu odanın elektrik süpürgesi robotlarını simüle ettiğimiz bir atamadır. Neyse runSimulation işlevi ile ilgili bazı yardımları gerçekten takdir ediyorum. While döngüsünde sonsuz bir döngüye başlar. Zaman döngülerinin doğru olduğu durumlarda hesapladığı değerleri bildiğim kadarıyla ancak while döngüsü test edildiğinde ilklendiriliyorlar mı? Sanmıyorum ama yanılıyor olabilirim. Bu simülasyon fonksiyonu, genişlik ve yükseklik odalarını ve num_robots robotlarını başlatır ve simülasyon, min_coverage değerine ulaşılana kadar zemin temizlenene kadar çalışır. RunSimulation'ın sonucu, min_coverage'a ulaşmak için gereken ortalama zaman adımıdır. Şimdiden teşekkürler! Eğer 1 bir num_robots argümanla runSimulation çağırdığınızdaPython - Çalışmada sonsuz döngüSimülasyon işlevi

Simulating robots 

import math 
import random 

import ps2_visualize 
import pylab 


from ps2_verify_movement27 import testRobotMovement 



class Position(object): 
""" 
A Position represents a location in a two-dimensional room. 
""" 
def __init__(self, x, y): 
    """ 
    Initializes a position with coordinates (x, y). 
    """ 
    self.x = x 
    self.y = y 

def getX(self): 
    return self.x 

def getY(self): 
    return self.y 

def getNewPosition(self, angle, speed): 
    """ 
    Computes and returns the new Position after a single clock-tick has 
    passed, with this object as the current position, and with the 
    specified angle and speed. 

    Does NOT test whether the returned position fits inside the room. 

    angle: number representing angle in degrees, 0 <= angle < 360 
    speed: positive float representing speed 

    Returns: a Position object representing the new position. 
    """ 
    old_x, old_y = self.getX(), self.getY() 
    angle = float(angle) 
    # Compute the change in position 
    delta_y = speed * math.cos(math.radians(angle)) 
    delta_x = speed * math.sin(math.radians(angle)) 
    # Add that to the existing position 
    new_x = old_x + delta_x 
    new_y = old_y + delta_y 
    return Position(new_x, new_y) 

def __str__(self): 
    return "(%0.2f, %0.2f)" % (self.x, self.y) 



class RectangularRoom(object): 
""" 
A RectangularRoom represents a rectangular region containing clean or dirty 
tiles. 

A room has a width and a height and contains (width * height) tiles. At any 
particular time, each of these tiles is either clean or dirty. 
""" 
def __init__(self, width, height): 
    """ 
    Initializes a rectangular room with the specified width and height. 

    Initially, no tiles in the room have been cleaned. 

    width: an integer > 0 
    height: an integer > 0 
    """ 

    self.width = width 
    self.height = height 

    self.tiles = [[False] * self.height for i in range(self.width)] 


def cleanTileAtPosition(self, pos): 
    """ 
    Mark the tile under the position POS as cleaned. 

    Assumes that POS represents a valid position inside this room. 

    pos: a Position - pos is a tuple (x, y) 
    """ 


    (x_tile, y_tile) = (int(math.floor(pos.getX())), int(math.floor(pos.getY()))) 

    #print (x_tile, y_tile) 

    self.tiles[x_tile][y_tile] = True 



def isTileCleaned(self, m, n): 
    """ 
    Return True if the tile (m, n) has been cleaned. 

    Assumes that (m, n) represents a valid tile inside the room. 

    m: an integer 
    n: an integer 
    returns: True if (m, n) is cleaned, False otherwise 
    """ 
    self.m = m 
    self.n = n 

    if self.tiles[self.m][self.n] == True: 
     return True 
    else: 
     return False 

def getNumTiles(self): 
    """ 
    Return the total number of tiles in the room. 

    returns: an integer 
    """ 

    return self.width*self.height 

def getNumCleanedTiles(self): 
    """ 
    Return the total number of clean tiles in the room. 

    returns: an integer 
    """ 
    numCleanTiles = 0 

    for row in range(self.width): 
     for column in range(self.height): 
      if self.tiles[row][column] == True: 
       numCleanTiles +=1 

    return numCleanTiles 

def getRandomPosition(self): 
    """ 
    Return a random position inside the room. 

    returns: a Position object. 
    """ 
    # 
    return Position(random.randrange(0, self.width), random.randrange(0, self.height)) 

def isPositionInRoom(self, pos): 
    """ 
    Return True if pos is inside the room. 

    pos: a Position object. 
    returns: True if pos is in the room, False otherwise. 
    """ 
    if 0 <= pos.getX() < self.width and 0 <= pos.getY() < self.height: 
     return True 
    else: 
     return False 


class Robot(object): 
""" 
Represents a robot cleaning a particular room. 

At all times the robot has a particular position and direction in the room. 
The robot also has a fixed speed. 

Subclasses of Robot should provide movement strategies by implementing 
updatePositionAndClean(), which simulates a single time-step. 
""" 
def __init__(self, room, speed): 
    """ 
    Initializes a Robot with the given speed in the specified room. The 
    robot initially has a random direction and a random position in the 
    room. The robot cleans the tile it is on. 

    room: a RectangularRoom object. 
    speed: a float (speed > 0) 
    """ 
    #raise NotImplementedError 

    self.room = room 
    self.speed = speed 

    self.position = self.room.getRandomPosition() 

    self.direction = random.randint(0, 359) 

    self.room.cleanTileAtPosition(self.position) 

def getRobotPosition(self): 
    """ 
    Return the position of the robot. 

    returns: a Position object giving the robot's position. 
    """ 
    return self.position 

def getRobotDirection(self): 
    """ 
    Return the direction of the robot. 

    returns: an integer d giving the direction of the robot as an angle in 
    degrees, 0 <= d < 360. 
    """ 
    d = self.direction 
    return d 

def setRobotPosition(self, position): 
    """ 
    Set the position of the robot to POSITION. 

    position: a Position object. 
    """ 
    self.position = position 
    return self.position 

def setRobotDirection(self, direction): 
    """ 
    Set the direction of the robot to DIRECTION. 

    direction: integer representing an angle in degrees 
    """ 
    self.direction = direction 
    return self.direction 

def updatePositionAndClean(self): 
    """ 
    Simulate the raise passage of a single time-step. 

    Move the robot to a new position and mark the tile it is on as having 
    been cleaned. 
    """ 
    raise NotImplementedError # don't change this! 



class StandardRobot(Robot): 
""" 
A StandardRobot is a Robot with the standard movement strategy. 

At each time-step, a StandardRobot attempts to move in its current 
direction; when it would hit a wall, it *instead* chooses a new direction 
randomly. 
""" 

def updatePositionAndClean(self): 
    """ 
    Simulate the raise passage of a single time-step. 

    Move the robot to a new position and mark the tile it is on as having 
    been cleaned. 
    """ 

    newPosition = self.position.getNewPosition(self.direction, self.speed) 

    if 0 <= newPosition.getX() <= self.room.width and 0 <= newPosition.getY() <= self.room.height: 
     self.setRobotPosition(newPosition) 
     self.room.cleanTileAtPosition(self.position) 
    else: 
     self.setRobotDirection(random.randint(0, 359)) 


    # Uncomment this line to see your implementation of StandardRobot in action! 
    #testRobotMovement(StandardRobot, RectangularRoom) 



def runSimulation(num_robots, speed, width, height, min_coverage, num_trials, 
       robot_type): 
""" 
Runs NUM_TRIALS trials of the simulation and returns the mean number of 
time-steps needed to clean the fraction MIN_COVERAGE of the room. 

The simulation is run with NUM_ROBOTS robots of type ROBOT_TYPE, each with 
speed SPEED, in a room of dimensions WIDTH x HEIGHT. 

num_robots: an int (num_robots > 0) 
speed: a float (speed > 0) 
width: an int (width > 0) 
height: an int (height > 0) 
min_coverage: a float (0 <= min_coverage <= 1.0) 
num_trials: an int (num_trials > 0) 
robot_type: class of robot to be instantiated (e.g. StandardRobot or 
      RandomWalkRobot) 
""" 

numTimeStepsList = [] 

for i in range(num_trials): 
    room1 = RectangularRoom(width, height) 
    numTimeSteps = 0 
    robot = [] 

    for n in range(num_robots-1): 
     robot[n] = robot_type(room1, speed) 

    while (1.0 - float(room1.getNumCleanedTiles())/float(room1.getNumTiles())) >= min_coverage:  
     for n in range(num_robots-1): 
      robot[n].updatePositionAndClean() 
      numTimeSteps += 1 
      #print numTimeSteps 

    numTimeStepsList.append(numTimeSteps) 
#print numTimeStepsList 
return sum(numTimeStepsList)/len(numTimeStepsList)  




#raise NotImplementedError 

# Uncomment this line to see how much your simulation takes on average 
print runSimulation(1, 1.0, 10, 10, 0.75, 30, StandardRobot) 



class RandomWalkRobot(Robot): 
""" 
A RandomWalkRobot is a robot with the "random walk" movement strategy: it 
chooses a new direction at random at the end of each time-step. 
""" 
def updatePositionAndClean(self): 
    """ 
    Simulate the passage of a single time-step. 

    Move the robot to a new position and mark the tile it is on as having 
    been cleaned. 
    """ 
    raise NotImplementedError 


def showPlot1(title, x_label, y_label): 
""" 
What information does the plot produced by this function tell you? 
""" 
num_robot_range = range(1, 11) 
times1 = [] 
times2 = [] 
for num_robots in num_robot_range: 
    print "Plotting", num_robots, "robots..." 
    times1.append(runSimulation(num_robots, 1.0, 20, 20, 0.8, 20, StandardRobot)) 
    times2.append(runSimulation(num_robots, 1.0, 20, 20, 0.8, 20, RandomWalkRobot)) 
pylab.plot(num_robot_range, times1) 
pylab.plot(num_robot_range, times2) 
pylab.title(title) 
pylab.legend(('StandardRobot', 'RandomWalkRobot')) 
pylab.xlabel(x_label) 
pylab.ylabel(y_label) 
pylab.show() 


def showPlot2(title, x_label, y_label): 
""" 
What information does the plot produced by this function tell you? 
""" 
aspect_ratios = [] 
times1 = [] 
times2 = [] 
for width in [10, 20, 25, 50]: 
    height = 300/width 
    print "Plotting cleaning time for a room of width:", width, "by height:", height 
    aspect_ratios.append(float(width)/height) 
    times1.append(runSimulation(2, 1.0, width, height, 0.8, 200, StandardRobot)) 
    times2.append(runSimulation(2, 1.0, width, height, 0.8, 200, RandomWalkRobot)) 
pylab.plot(aspect_ratios, times1) 
pylab.plot(aspect_ratios, times2) 
pylab.title(title) 
pylab.legend(('StandardRobot', 'RandomWalkRobot')) 
pylab.xlabel(x_label) 
pylab.ylabel(y_label) 
pylab.show() 

cevap

0

, aslında hiç bir robot yapmaz, bu yüzden hiçbir şey temizlenmiş olur. Neredeyse hepsi yanlış

for n in range(num_robots-1): 
    robot[n] = robot_type(room1, speed) 

:

suçlu bu döngü. Boşalmaya başladığından robot listesindeki herhangi bir dizine atayamazsınız. Ve siz her zaman, gerekenden daha az zaman kaybedersiniz (num_robots1 ise sıfır kez). Muhtemelen daha fazla bir şey isteyebilirsiniz:

for _ in range(num_robots): 
    robot.append(robot_type(room1, speed)) 
+0

Aptalca! Evet tabi ki. Bunun için teşekkürler. – Berwhale