6.4. Практикум: Движение по случайному маршруту
В рамках этого практического задания вы увидите, сколько возможных маршрутов робот Rover может сделать на сетке координат (совершая рандомные повороты только в северном и восточном направлении) из исходной точки (0, 0) в точку (2, 2). Вы также сможете исследовать экспериментальную и теоретическую вероятность достижения этой точки при движении робота в рандомном порядке.
Вы научитесь:
- Использовать рандомное число для того, чтобы решить, в какую сторону должен поехать робот
- Определять успех или неудачу в достижении финишной точки (2,2)
- Отмечать координаты на экране
- Использовать цветовой LED индикатор, чтобы сообщать пользователю об успехе или неудаче попытки
- Повторять эксперимент несколько раз и определять, как часто робот Rover достигает цели
- Исследовать теоретическую вероятность достижения цели
Примечание для учителя: Для того чтобы программа не была слишком длинной, выражения построения маршрута на координатной плоскости можно не писать. Но помните, что модуль ti_plotlib импортируется именно для возможности использовать эти функции.
Робот Rover начинает свое движение в исходной точке (O). В каждой точке своего маршрута вездеход поочередно и в случайном порядке может двигаться только на восток (направо) или на север (вверх). Для достижения финишной точки (2, 2) существуют несколько разных вариантов маршрутов. Один из них показан красной жирной линией на рисунке справа. Как вы считаете, сколько всего существует разных способов успешного достижения финишной точки роботом? Если каждый раз направление движения выбирается рандомно, существует ли вероятность того, что вездеход Rover не достигнет своей цели?
Какова вероятность того, что робот Rover все же прибудет в финишную точку?
Смоделируйте программу для этой задачи, чтобы отследить количество раз, которое роботу Rover удается достигнуть цели, и определить процент успешных попыток.
Не забывайте о неудачных попытках. Как вы определите, что роботу Rover не удалось достигнуть цели?
Примечание для учителя: Если x=3 или y=3, можно остановить программу, а попытку засчитать как неудавшуюся, ведь робот не пришел в финишную точку (2,2) так как он перемещается только вверх и направо.
Если места для движения уже не остается (вам для этого понадобится примерно квадрат 0,5 м х 0,5 м), установите значение единицы передвижения для робота поменьше, используя выражение rv.grid_m_unit(scale_value). Значение по умолчанию равно 0,1 метра.
1. Начните работу с создания нового проекта Rover Coding.
Настройте экран с помощью функций plt, чтобы отображать позицию робота Rover по мере его перемещения по маршруту, используя меню TI PlotLib > Setup:
plt.window(-1, 4, -1, 4)
plt.grid(1, 1, "dashed")
plt.axes("on")
2. Используйте одну переменную для общего количества попыток: trials = 10
Используйте одну переменную для подсчета удачных попыток: successes = 0
Используйте две переменные для финишной точки: px, рy = 2, 2 (Да, эта запись правильная!)
Используйте цикл с оператором for, чтобы выполнять все попытки: for i in range(trials):
И начните выполнять свою первую попытку:
В блоке (block) цикла используйте две разные переменные для указания позиции робота Rover: rx, ry = 0, 0
3. Отметьте эту точку на экране координатной сетки: plt.plot(rx,ry,"o")
Примечание для учителя: Робот Rover знает, где он находится на сетке координат. Функции rv.waypoint_x() и rv.waypoint_y() говорят о его текущем положении, но учащимся лучше самим отслеживать переменные.
4. Создайте цикл с оператором while, который продолжает выполняться, пока робот Rover не находится в финишной точке и не выехал за ее пределы. Подумайте, какое условие будет говорить о том, что попытка не удалась.
Это дополнительное условие. Можете тут поупражняться.
Примечание для учителя: Неудачной считается попытка, когда робот Rover приезжает в точку, равную 3 либо на оси х, либо на оси у. Она находится "за пределами" маршрута. Так выглядит цикл с оператором while:
while (rx, ry) != (px, py) and rx < 3 and ry < 3:
5. В блоке оператора while используйте выражение randint(0, 1), которое разрешает роботу двигаться либо на восток (0 градусов), либо на север (90 градусов). Это можно организовать с помощью следующего выражения:
dir = randint(0, 1) * 90
Вам также будет необходимо ввести выражение from random import* в область ввода, чтобы использовать функцию randint(). Она не включена в шаблон проекта по работе с роботом Rover Coding.
6. Ваш робот Rover поворачивает на заданный угол (dir) и перемещается вперед на 1 единицу.
(Выражения на рисунке прописаны не полностью)
Также добавьте выражение rv.wait_until_done(), чтобы настроить скорость нанесения точек маршрута на экран.
Примечание для учителя: Можно также использовать выражения rv.left() и rv.right(), но с ними работать сложнее. Когда робот Rover поворачивает на заданный угол, он всегда вращается против часовой стрелки (даже если он уже смотрит в нужном направлении, он поворачивается на 360 градусов).
7. Обновите переменные позиции робота Rover rx и ry.
Если робот Rover переместился на восток (dir == 0),
добавьте 1 к rx.
В противном случае
добавьте 1 к ry.
Нанесите координаты текущего положения робота Rover на экран с помощью выражения plt.plot(rx,ry,"o") (не показано в примере).
8. После завершения цикла с оператором while определите, успешно ли достиг робот Rover финишной точки:
if (rx, ry) == (px, py):
Затем прибавьте 1 к переменной общего количества успешных попыток (successes).
Выведите на экран слово "Успешно!" или "Неуспешно" (SUCCESS! или FAIL).
Если робот Rover завершил свой маршрут успешно, цветовой LED индикатор должен загореться ЗЕЛЕНЫМ, в противном случае он должен загореться КРАСНЫМ.
Затем введите следующее (в примере не показано):
- Два выражения для того, чтобы Rover вернулся в исходную точку (0,0) и был развернут в сторону востока (угол 0 градусов)
- Выражение для того, чтобы выключить цветовой LED индикатор
- Выражения, которые заново строят маршрут на экране, начиная с функции plt.cls(), затем снова используйте три выражения настройки Setup
9. После завершения цикла с оператором for (когда все попытки закончились) выведите результаты эксперимента на экран:
- Общее количество удачных попыток
- Процент удачных попыток от общего их числа (переменная successes / переменную общего числа попыток trials *100)
Пример вывода таких результатов при 10 попытках показан на рисунке ниже. Процент является экспериментальной вероятностью успешного завершения попытки.
10. Теоретическая вероятность
Существуют шесть возможных вариантов успешно завершенных маршрутов движения из точки (0, 0) в точку (2, 2).
Неудачных маршрутов 10, когда либо x=3, либо y=3 (они показаны на рисунке в виде единиц и четверок на схеме). Формула теоретической вероятности выглядит так:
Успешные попытки = 6 = 3
Успешные + неудачные 6+10 8
Процент успешных попыток равняется 37.5%.
Насколько приближенно к этому проценту завершился ваш эксперимент? Что бы вы исправили в программе, чтобы результаты получились более точными в экспериментальной вероятности?
Примечание для учителя: Пример кода для программы:
Преобразуйте все выражения rv. в комментарии и выполните 1000 попыток.
# Unit 6 App: random walk
#================================
import ti_rover as rv
from math import *
import ti_plotlib as plt
from ti_system import *
from time import *
from random import *
#================================
trials = int(input("# of trials? "))
successes = 0
px, py = 2, 2
for i in range(trials):
plt.cls()
plt.window(-1,4,-1,4)
plt.grid(1,1,"dashed")
plt.axes("on")
rx, ry = 0, 0
plt.plot(rx,ry,"o")
rv.color_rgb(0,0,0)
while (rx,ry)!=(px,py) and rx<3 and ry<3:
dir=randint(0, 1) * 90
rv.to_angle(dir)
rv.forward(1)
plt.plot(rx,ry,"o")
rv.wait_until_done()
if dir==0:
rx+=1
else:
ry+=1
plt.plot(rx,ry,"o")
# end of while loop
if (rx,ry)==(px,py):
successes+=1
print("SUCCESS!")
rv.color_rgb(0,255,0)
else:
print("FAIL")
rv.color_rgb(255,0,0)
rv.to_xy(0,0)
rv.to_angle(0)
rv.wait_until_done()
# end of for loop
print("Successes:", successes)
print("Percentage: ", successes/trials*100)