Python-runSimulation函数中的无限循环
这是一项任务,我们正在模拟roomba真空吸尘器机器人。无论如何,我真的非常感谢对runSimulation函数的一些帮助。它在while循环处启动为无限循环。据我所知,它在while循环条件下计算的值是正确的,但它们是否在每次测试while循环时都进行了初始化?我不这么认为,但可能是错的。因此,这个模拟函数实例化了一个房间的宽度和高度以及num_机器人的机器人,模拟运行直到地板被清洁,直到达到最小覆盖率。runSimulation的结果是达到最小覆盖率所需的平均时间步长。提前谢谢Python-runSimulation函数中的无限循环,python,class,loops,instance,infinite,Python,Class,Loops,Instance,Infinite,这是一项任务,我们正在模拟roomba真空吸尘器机器人。无论如何,我真的非常感谢对runSimulation函数的一些帮助。它在while循环处启动为无限循环。据我所知,它在while循环条件下计算的值是正确的,但它们是否在每次测试while循环时都进行了初始化?我不这么认为,但可能是错的。因此,这个模拟函数实例化了一个房间的宽度和高度以及num_机器人的机器人,模拟运行直到地板被清洁,直到达到最小覆盖率。runSimulation的结果是达到最小覆盖率所需的平均时间步长。提前谢谢 Simul
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()
模拟机器人
输入数学
随机输入
导入ps2_可视化
进口派拉布
从ps2验证移动27导入测试机器人移动
类位置(对象):
"""
位置表示二维房间中的位置。
"""
定义初始化(self,x,y):
"""
使用坐标(x,y)初始化位置。
"""
self.x=x
self.y=y
def getX(自我):
返回self.x
def getY(自我):
回归自我
def getNewPosition(自身、角度、速度):
"""
计算并返回单个时钟滴答声结束后的新位置
已传递,将此对象作为当前位置,并使用
指定的角度和速度。
不测试返回的位置是否适合室内。
角度:以度表示角度的数字,0
高度:一个大于0的整数
"""
self.width=宽度
自我高度=高度
self.tiles=[[False]*范围内i的self.height(self.width)]
def CLEANTILEAT位置(自身,位置):
"""
将位置位置下方的瓷砖标记为已清洁。
假设POS表示此房间内的有效位置。
pos:a Position-pos是一个元组(x,y)
"""
(x_-tile,y_-tile)=(int(数学地板(pos.getX())),int(数学地板(pos.getY()))
#打印(x_平铺,y_平铺)
self.tiles[x_tile][y_tile]=True
def ISTILECLEAN(自身、m、n):
"""
如果瓷砖(m,n)已清理,则返回True。
假设(m,n)表示房间内的有效瓷砖。
m:一个整数
n:一个整数
返回:如果(m,n)已清除,则为True,否则为False
"""
self.m=m
self.n=n
如果self.tiles[self.m][self.n]==True:
返回真值
其他:
返回错误
def getNumTiles(self):
"""
返回房间中瓷砖的总数。
返回:一个整数
"""
返回自宽*自高
def GetNumCleanedFiles(自):
"""
返回房间中干净瓷砖的总数。
返回:一个整数
"""
numCleanTiles=0
对于范围内的行(自身宽度):
对于范围内的列(自身高度):
如果self.tiles[行][列]==True:
numCleanTiles+=1
返回numCleanTiles
def getRandomPosition(自):
"""
返回房间内的任意位置。
返回:位置对象。
"""
#
返回位置(random.randrange(0,自宽),random.randrange(0,自高))
def位置室(自身、位置):
"""
如果pos在房间内,则返回True。
位置:一个位置对象。
返回:如果pos在房间中,则返回True,否则返回False。
"""
如果使用1
的num_robots
参数调用runSimulation
时,0,则它实际上根本不会生成任何机器人,因此不会清理任何东西
罪魁祸首是这个循环:
for n in range(num_robots-1):
robot[n] = robot_type(room1, speed)
这几乎全错了。无法为robot
列表中的任何索引赋值,因为它的开头为空。而且你总是比应该的少循环一次(如果num\u robots
是1
,则循环次数为零)。您可能想要更像:
for _ in range(num_robots):
robot.append(robot_type(room1, speed))