Python 3.x 显示沿随机漫游的最短路径
我是一名CS教师,我们在课堂上编写了一些Python代码,让海龟随机游走。有人问我们是否可以画一只新乌龟,它将沿着最小路径(从起点到终点)追踪路线。当前代码如下 我想我们必须先列出坐标,然后创建某种树。我肯定已经有一个图书馆来做这件事了,只是不确定Python 3.x 显示沿随机漫游的最短路径,python-3.x,turtle-graphics,python-turtle,random-walk,algorithm-animation,Python 3.x,Turtle Graphics,Python Turtle,Random Walk,Algorithm Animation,我是一名CS教师,我们在课堂上编写了一些Python代码,让海龟随机游走。有人问我们是否可以画一只新乌龟,它将沿着最小路径(从起点到终点)追踪路线。当前代码如下 我想我们必须先列出坐标,然后创建某种树。我肯定已经有一个图书馆来做这件事了,只是不确定 import turtle import random import time from math import sqrt leo = turtle.Turtle() leo.speed(0) leo.color("green") leo.dot
import turtle
import random
import time
from math import sqrt
leo = turtle.Turtle()
leo.speed(0)
leo.color("green")
leo.dot(6) # mark the starting location
leo.color("black")
directions = ['N', 'S', 'E', 'W']
steps = 100
step_size = 10
start = time.time()
for i in range(steps):
heading = random.choice(directions)
if heading == 'N':
leo.setheading(90)
elif heading == 'S':
leo.setheading(270)
elif heading == 'E':
leo.setheading(0)
else:
leo.setheading(180)
leo.forward(step_size)
(x,y) = leo.position()
distance = sqrt( x**2 + y**2 )
end = time.time()
leo.color("red") # mark the end location
leo.dot(6)
leo.hideturtle()
# drawing the final distance: start to end
raph = turtle.Turtle()
raph.color("blue")
raph.goto(x,y)
raph.hideturtle()
print("Total time:", end - start)
print("Total steps:", steps)
print("Total distance:", distance / step_size)
方法是:1-生成一个随机行走并在画布上绘制它
2-使用该随机游动生成晶格(坐标图及其与相邻坐标的连接)。
2-使用起点和终点搜索晶格中的最短路径。此处使用宽度优先搜索,但也可以使用其他搜索。
3-在画布上,在晶格上绘制最短的路径 下面是一个叠加了最短路径的步行示例: 用于生成它的代码: (从您发布的代码扩展)
随机导入
进口海龟
班级步行者:
“”“虚拟晶格上的随机漫游器”
定义在一个方向上迈出一步的规则
记录步骤的方向顺序
"""
#四个方向
方向=('N','S','E','W')
ID=1
定义初始化(自):
self.name=f“{self.\uuuuuu class.\uuuuuuu name.\uuuuuu}编号:{Walker.ID}”
Walker.ID+=1
self.sequence_of_steps=[]#一个方向序列
def采取步骤(自我):
方向=随机选择(Walker.DIRECTIONS)
self.sequence\u of_steps.append(方向)
定义(自我):
返回f“{self.name}”
上课时间:
“”“管理步行者采取步骤”“”
定义初始化(self,walker=walker,numwalkers=1,numsteps=100):
self.numsteps=numsteps
self.numwalkers=numwalkers
self.walkers=[walker()用于范围内的(numwalkers)]
打印{self.numsteps}步骤的f'walking{self.numwalkers}{walker}
self.do_walk()
def do_步行(自我):
对于步进范围(self.numsteps):
对于self.walkers中的walker:
沃克,走一步
定义(自我):
返回'\n'.join(str(walker.sequence\u of\u步骤)
适用于自我中的步行者。步行者)
def喷漆_步行者_路径(步行者):
“”“在画布上绘制一个步行者的路径”“”
标题={'N':90,'S':270,'E':0,'W':180}
单位移动=10像素
方向\u路径=步数的步数
t=海龟。海龟()
t、 速度(“最快”)
t、 颜色(“绿色”)
t、 圆点(尺寸=10)
t=海龟。海龟()
t、 颜色(“灰色”)
report=turtle.turtle()
报告:penup()
报告:hideturtle()
报告。后藤(200200)
report.write(“步骤:”,True,字体=('courier',18,'normal'))
report.write('0',font=('courier',18',normal'))
对于idx,枚举中的方向(方向\路径):
t、 设置标题(标题[方向])
t、 前进(单位移动)
t、 圆点(尺寸=4)
report.undo()
报告:penup()
report.pendown()
report.write(f“{idx}”,font=('courier',18,'normal'))
t、 希德图尔()
t、 颜色(“红色”)
t、 dot(6)
t、 后藤(0,0)
def绘制路径(方向路径):
标题={'N':90,'S':270,'E':0,'W':180}
单位移动=10像素
t=海龟。海龟()
t、 速度(“最快”)
t、 颜色(“黑色”)
t=海龟。海龟()
t、 颜色(“黑色”)
t、 养老金(2)
对于方向_路径中的方向:
t、 设置标题(标题[方向])
t、 前进(单位移动)
t、 圆点(尺寸=4)
t、 希德图尔()
类坐标:
#偏移量为(列,行)i/e(x,y)
偏移量={'N':(0,1),'S':(0,-1),'E':(1,0),'W':(-1,0)}
COORD_TO_DIR={(0,1):(0,-1):'S',(1,0):'E',(-1,0):'W'}
定义初始化(self、col、row):
self.col=col
self.row=行
self.coord=(self.col,self.row)
def get_相邻(自身、方向):
“”“返回与自身相邻的新坐标对象。”
在给定的方向上
"""
d_col,d_row=坐标。偏移量[方向]
返回坐标(self.col+d_col,self.row+d_row)
def get_方向(自身、目的地):
“”“返回要移动的方向
从自我到目的地
offcol=destination.col-self.col
offrow=destination.row-self.row
助理秘书长(财务主任)
import random
import turtle
class Walker:
"""a random walker on a virtual lattice
defines the rules of taking a step in a direction
records the sequence of directions of the steps takem
"""
# four directions
DIRECTIONS = ('N', 'S', 'E', 'W')
ID = 1
def __init__(self):
self.name = f"{self.__class__.__name__} no.: {Walker.ID}"
Walker.ID += 1
self.sequence_of_steps = [] # a sequence of directions
def take_step(self):
direction = random.choice(Walker.DIRECTIONS)
self.sequence_of_steps.append(direction)
def __str__(self):
return f"{self.name}"
class RandomWalk:
"""manages Walkers take_step"""
def __init__(self, walker=Walker, numwalkers=1, numsteps=100):
self.numsteps = numsteps
self.numwalkers = numwalkers
self.walkers = [walker() for _ in range(numwalkers)]
print(f'walking {self.numwalkers} {walker} for {self.numsteps} steps')
self.do_walk()
def do_walk(self):
for step in range(self.numsteps):
for walker in self.walkers:
walker.take_step()
def __str__(self):
return '\n'.join(str(walker.sequence_of_steps)
for walker in self.walkers)
def paint_walker_path(walker):
"""paints the path of one walker on the canvas"""
headings = {'N': 90, 'S': 270, 'E': 0, 'W': 180}
unit_move = 10 # pixels
direction_path = walker.sequence_of_steps
t = turtle.Turtle()
t.speed('fastest')
t.color('green')
t.dot(size=10)
t = turtle.Turtle()
t.color('gray')
report = turtle.Turtle()
report.penup()
report.hideturtle()
report.goto(200, 200)
report.write("step: ", True, font=('courier', 18, 'normal'))
report.write('0', font=('courier', 18, 'normal'))
for idx, direction in enumerate(direction_path):
t.setheading(headings[direction])
t.forward(unit_move)
t.dot(size=4)
report.undo()
report.penup()
report.pendown()
report.write(f"{idx}", font=('courier', 18, 'normal'))
t.hideturtle()
t.color('red')
t.dot(6)
t.goto(0, 0)
def paint_path(direction_path):
headings = {'N': 90, 'S': 270, 'E': 0, 'W': 180}
unit_move = 10 # pixels
t = turtle.Turtle()
t.speed('fastest')
t.color('black')
t = turtle.Turtle()
t.color('black')
t.pensize(2)
for direction in direction_path:
t.setheading(headings[direction])
t.forward(unit_move)
t.dot(size=4)
t.hideturtle()
class Coordinate:
# offsets are (col, row) i/e (x, y)
OFFSETS = {'N': (0, 1), 'S': (0, -1), 'E': (1, 0), 'W': (-1, 0)}
COORD_TO_DIR = {(0, 1): 'N', (0, -1): 'S', (1, 0): 'E', (-1, 0): 'W'}
def __init__(self, col, row):
self.col = col
self.row = row
self.coord = (self.col, self.row)
def get_adjacent(self, direction):
"""returns a new Coordinate object adjacent to self
in the given direction
"""
d_col, d_row = Coordinate.OFFSETS[direction]
return Coordinate(self.col + d_col, self.row + d_row)
def get_direction(self, destination):
"""returns the direction to take in order to move
from self to destination"""
offcol = destination.col - self.col
offrow = destination.row - self.row
assert abs(offcol) <= 1 and abs(offrow) <= 1, "adjacent coordinates must be close by"
return Coordinate.COORD_TO_DIR[(offcol, offrow)]
def __hash__(self):
return hash(self.coord)
def __eq__(self, other):
return self.coord == other.coord
def __str__(self):
return f"Coordinate {self.coord}"
def __repr__(self):
return str(self)
ORIGIN = Coordinate(0, 0)
class Lattice:
def __init__(self):
self.adjacency = {}
def get_final_dest_and_merge_sequence_of_steps(self, sequence_of_steps,
origin=ORIGIN):
current_coordinate = origin
for direction in sequence_of_steps:
adjacent_coordinate = current_coordinate.get_adjacent(direction)
try:
self.adjacency[current_coordinate].add(adjacent_coordinate)
except KeyError:
self.adjacency[current_coordinate] = {adjacent_coordinate}
try:
self.adjacency[adjacent_coordinate].add(current_coordinate)
except KeyError:
self.adjacency[adjacent_coordinate] = {current_coordinate}
current_coordinate = adjacent_coordinate
return current_coordinate
@staticmethod
def extract_sequence_of_steps(seq_of_coordinates):
steps = []
current_coord = seq_of_coordinates[0]
for next_destination in seq_of_coordinates[1:]:
steps.append(current_coord.get_direction(next_destination))
current_coord = next_destination
return steps
def __str__(self):
adjacency = []
for k, v in self.adjacency.items():
adjacency.append(f'{k},: {v}\n')
return ''.join(adjacency)
class BFS:
def __init__(self, lattice, start_coord, end_coord):
self.lattice = lattice
self.start_coord = start_coord
self.end_coord = end_coord
self.shortest_path = None # a sequence of Coordinate
self.bfs()
def bfs(self):
queue = []
visited = set()
queue.append([self.start_coord])
while queue:
path = queue.pop(0)
print("queue: ", queue, "path: ", path)
node = path[-1]
if node == self.end_coord:
self.shortest_path = path
break
if node not in visited:
for adjacent in self.lattice.adjacency.get(node, []):
new_path = list(path)
new_path.append(adjacent)
queue.append(new_path)
visited.add(node)
if __name__ == '__main__':
walk = RandomWalk(walker=Walker, numsteps=1000)
print(walk)
tom = walk.walkers[0]
paint_walker_path(tom)
print("Done with turtle tom")
lattice = Lattice()
end_node = lattice.get_final_dest_and_merge_sequence_of_steps(tom.sequence_of_steps)
print(end_node)
print(lattice)
search = BFS(lattice, ORIGIN, end_node)
print('search: ', search.shortest_path)
shortest_tom = Lattice.extract_sequence_of_steps(search.shortest_path)
paint_path(shortest_tom)
turtle.done()