救援机器人路径规划系统

作者头像 青和
2023-01-03 12:20:39
1.2k 阅读
文章封面

🧭 第一部分:

任务背景:救援机器人路径规划系统

你正在编写一个**灾区救援机器人(RescueBot)**的控制程序。机器人在一片二维地形网格中执行搜救、标记和信息采集任务。每个网格单元可能是可通行的空地、被碎石阻挡的障碍、或被标记为危险区。

网格定义

整个灾区地图 disaster_map 是一个二维列表(list of lists)。

元素值 True 代表该格已探测安全;

元素值 False 代表该格尚未探测或存在碎石。

机器人的位置以 (row, col) 表示,方向 face 取值为 'N', 'E', 'S', 'W'。

坐标原点 (0, 0) 在地图左上角,行号向下、列号向右递增。

指令集

机器人会接收一系列行动指令(每个为字符串):

指令名

功能描述

rotate-left

向左旋转 90°。

rotate-right

向右旋转 90°。

move

向当前朝向前进一格。若前方越界或有障碍,则不移动,并自动右转一次(回避机制)。

scan

探测前方格子是否安全(不移动),将结果保存到机器人状态中。

mark

在当前位置放置一个标记,表示已找到目标或危险区域。

rescue

若当前位置为 False(危险区),执行救援并将其设为 True(安全区)。

backtrack

向后退一步(朝向不变),若越界则不移动并右转一次。

charge

若当前位置是充电点,则将能量恢复到最大值。

standby

什么也不做(通常在电量为 0 时执行)。

能量与限制

每执行一次 move、rescue 或 backtrack,消耗 1 单位电量。

当能量为 0 时,只能执行 standby 直到执行 charge。

若机器人移动到 charging_stations 集合中的任意位置,电量立即充满(最大值由初始输入 energy_max 决定)。

程序输入

disaster_map:二维列表。

初始状态 robot = [row, col, face]

指令列表 commands

最大能量值 energy_max

充电站集合 charging_stations

障碍集合 rocks

程序输出

最终机器人位置与朝向 (row, col, face)

剩余能量 energy

救援成功次数(False→True 的次数)

遇到障碍或越界而右转的次数

放置的标记坐标列表

所有执行后的移动轨迹(含起点)

⚙️ 第二部分:参考答案(核心实现示例)

def rescue_action(robot, commands, disaster_map, energy_max, charging_stations, rocks):

# 方向映射

dirs = ['N', 'E', 'S', 'W']

dr = [-1, 0, 1, 0]

dc = [0, 1, 0, -1]

# 初始状态

row, col, face = robot

energy = energy_max

rescued = 0

marks = set()

turns = 0

path = [(row, col, face)]

scan_result = None

# 获取方向索引

def idx(f): return dirs.index(f)

for cmd in commands:

f = idx(face)

if cmd == 'rotate-left':

face = dirs[(f - 1) % 4]

elif cmd == 'rotate-right':

face = dirs[(f + 1) % 4]

elif cmd == 'move':

nr, nc = row + dr[f], col + dc[f]

if 0 <= nr < len(disaster_map) and 0 <= nc < len(disaster_map[0]) and (nr, nc) not in rocks:

row, col = nr, nc

energy -= 1

else:

face = dirs[(f + 1) % 4]

turns += 1

elif cmd == 'scan':

nr, nc = row + dr[f], col + dc[f]

if 0 <= nr < len(disaster_map) and 0 <= nc < len(disaster_map[0]):

scan_result = disaster_map[nr][nc]

else:

scan_result = None

elif cmd == 'mark':

marks.add((row, col))

elif cmd == 'rescue':

if not disaster_map[row][col]:

disaster_map[row][col] = True

rescued += 1

energy -= 1

elif cmd == 'backtrack':

br, bc = row - dr[f], col - dc[f]

if 0 <= br < len(disaster_map) and 0 <= bc < len(disaster_map[0]) and (br, bc) not in rocks:

row, col = br, bc

energy -= 1

else:

face = dirs[(f + 1) % 4]

turns += 1

elif cmd == 'charge':

if (row, col) in charging_stations:

energy = energy_max

elif cmd == 'standby':

pass

# 若能量耗尽则停机等待

if energy < 0:

energy = 0

path.append((row, col, face))

return {

"final": (row, col, face),

"rescued": rescued,

"marks": sorted(list(marks)),

"turns": turns,

"energy_left": energy,

"path": path,

"scan_result": scan_result

}

# 示例输入

disaster_map = [

[True, False, True],

[False, True, False],

[True, True, False]

]

robot = [1, 1, 'N']

commands = [

'scan', 'rotate-left', 'move',

'rescue', 'mark', 'rotate-right',

'move', 'rescue', 'backtrack',

'rotate-right', 'move', 'charge'

]

rocks = {(0, 0)}

charging_stations = {(2, 2)}

energy_max = 5

print(rescue_action(robot, commands, disaster_map, energy_max, charging_stations, rocks))

🔍 第三部分:题目解析

一、核心思路

本题要求你模拟一个机器人在二维地图上的动作。

能量系统(energy)

标记与扫描

障碍与自动右转机制

可充电逻辑

因此整个算法的核心是:

每个指令执行一次 → 根据动作类型修改位置、朝向、能量、标记或地图状态 → 更新统计信息。

二、关键实现要点

方向映射
用 dirs = ['N','E','S','W'] 结合 dr/dc 进行统一管理,左转即索引-1,右转索引+1。

越界或障碍处理
与原扫地机一样,“无法前进 → 自动右转一次”。

能量系统
每次移动或救援消耗 1 单位能量;当能量为 0 时,只能执行 standby。

充电机制
若当前坐标在 charging_stations 中,执行 charge 将能量恢复到 energy_max。

扩展功能

scan:不移动,只检测前方一格。

mark:记录坐标(不修改地图)。

backtrack:后退一格(若无效则右转)。

统计变量

rescued:救援成功次数(False→True)。

turns:因越界或障碍而触发右转的次数。

marks:标记坐标集合。

energy_left:剩余能量。

path:每次动作后的状态轨迹。

评论区