1573 Robot Motion (简单题)

本文介绍了一道关于机器人路径模拟的编程题目。该题目要求通过分析预设的指令网格,判断机器人是否能成功退出网格或者陷入循环,并给出了具体的实现代码。

Description

1573 Robot Motion - jolt2 - 正在成长的菜鸟


A robot has been programmed to follow the instructions in its path. Instructions for the next direction the robot is to move are laid down in a grid. The possible instructions are 
N north (up the page) 
S south (down the page) 
E east (to the right on the page) 
W west (to the left on the page) 
For example, suppose the robot starts on the north (top) side of Grid 1 and starts south (down). The path the robot follows is shown. The robot goes through 10 instructions in the grid before leaving the grid. 
Compare what happens in Grid 2: the robot goes through 3 instructions only once, and then starts a loop through 8 instructions, and never exits. 

Sample Input

3 6 5
NEESWE
WWWESS
SNWWWW
4 5 1
SESWE
EESNW
NWEEN
EWSEN
0 0 0

Sample Output

10 step(s) to exit
3 step(s) before a loop of 8 step(s)
这是一道模拟题,只要按照题目的意思一步一步的实现,就能成功。

exit的条件是大于行、列,或者小于0,loop的条件是第一次出现走过的位置。

#include<stdio.h>
#include<string.h>
int main()
{
	char map[11][11],m[11][11];//map代表grid,m记录走过的地方(m可以不要,直接对map进行操作,但要记录位置比较麻烦)
	int row,col,f,i,flag,rr,cc;
	while(1)
	{		
		flag = 0;
		scanf("%d%d%d",&row, &col, &f);
		int r = 0,c = f - 1;
		if(0 == row && 0 == col)
			break;
		for(i = 0; i < row; i++)
			scanf("%s",map[i]);
		memset(m,0,sizeof(m));	
		i = 1;
		while(flag == 0)
		{	
			//rr、cc来记录对一个指令的行和列,flag标记是exit了还是循环了
			rr = r;
			cc = c;
			switch(map[r][c])
			{
			case 'E':				
				if( c + 1 >= col)
					flag = 1;
				else
				{
					m[r][c] = i++;
					if(m[r][++c] > 0)
						flag = 2;
				}
				break;
			case 'N':
				if( r - 1 < 0 )
					flag = 1;
				else
				{
					m[r][c] = i++;
					if(m[--r][c] > 0)
						flag = 2;
				}
				break;
			case 'W':
				if( c - 1 < 0)
					flag = 1;
				else
				{
					m[r][c] = i++;
					if(m[r][--c] > 0)
						flag = 2;
				}break;
			case 'S':
				if( r + 1 >= row)
					flag = 1;
				else
				{
					m[r][c] = i++;
					if(m[++r][c] > 0)
						flag = 2;
				}break;
			}
		}
		if(1 == flag)
			printf("%d step(s) to exit\n",i);
		else
			printf("%d step(s) before a loop of %d step(s)\n",m[r][c] - 1,m[rr][cc] - m[r][c] + 1 );

	}
	return 0;
}


import pandas as pd import math import numpy as np import matplotlib.pyplot as plt show_animation = True """读取流速""" # file_path = r"C:\Users\LEGION\Desktop\A\vx_data_processed.xlsx" # file_path1=r"C:\Users\LEGION\Desktop\A\vy_data_processed.xlsx" file_path = r"C:\Users\LEGION\Desktop\A\processed_vx_data.xlsx" file_path1=r"C:\Users\LEGION\Desktop\A\processed_vy_data.xlsx" # 读取 Excel 数据 df = pd.read_excel(file_path, header=None) df1 = pd.read_excel(file_path1, header=None) # 第一列和第一行是坐标值,数据部分从第二行第二列开始 data = df.values # 转换为数组 data1 = df1.values """读取概率""" # file_path3 = r"C:\Users\LEGION\Desktop\A\probability_grid A.xlsx" # file_path4=r"C:\Users\LEGION\Desktop\A\probability_grid B.xlsx" file_path3 = r"C:\Users\LEGION\Desktop\A\processed__probability_gridA.xlsx" file_path4 = r"C:\Users\LEGION\Desktop\A\processed__probability_gridB.xlsx" df3 = pd.read_excel(file_path3, header=None) df4 = pd.read_excel(file_path4, header=None) # 第一列和第一行是坐标值,数据部分从第二行第二列开始 data3 = df3.values # 转换为数组 data4 = df4.values class AStarPlanner: def __init__(self, ox, oy, resolution, rr): """ Initialize grid map for a star planning ox: x position list of Obstacles [m] oy: y position list of Obstacles [m] resolution: grid resolution [m],地图的像素 rr: robot radius[m] """ self.resolution = resolution self.rr = rr self.min_x, self.min_y = 0, 0 self.max_x, self.max_y = 0, 0 self.obstacle_map = None self.x_width, self.y_width = 0, 0 self.motion = self.get_motion_model() self.calc_obstacle_map(ox, oy) class Node: """定义搜索区域节点类,每个Node都包含坐标x和y, 移动代价cost和父节点索引。 """ def __init__(self, x, y, cost, parent_index): self.x = x # index of grid self.y = y # index of grid self.cost = cost self.parent_index = parent_index def __str__(self): return str(self.x) + "," + str(self.y) + "," + str( self.cost) + "," + str(self.parent_index) def planning(self, sx, sy, gx, gy, data1 , data2, data3 , data4): """ A star path search 输入起始点和目标点的坐标(sx,sy)(gx,gy), 最终输出的结果是路径包含的点的坐标集合rx和ry。 input: s_x: start x position [m] s_y: start y position [m] gx: goal x position [m] gy: goal y position [m] output: rx: x position list of the final path ry: y position list of the final path """ start_node = self.Node(self.calc_xy_index(sx, self.min_x), self.calc_xy_index(sy, self.min_y), 0.0, -1) goal_node = self.Node(self.calc_xy_index(gx, self.min_x), self.calc_xy_index(gy, self.min_y), 0.0, -1) open_set, closed_set = dict(), dict() open_set[self.calc_grid_index(start_node)] = start_node while 1: if len(open_set) == 0: print("Open set is empty..") break c_id = min( open_set, key=lambda o: open_set[o].cost + self.calc_heuristic(data,data1,goal_node, open_set[o])) current = open_set[c_id] # show graph if show_animation: # pragma: no cover plt.plot(self.calc_grid_position(current.x, self.min_x), self.calc_grid_position(current.y, self.min_y), "xc") # for stopping simulation with the esc key. plt.gcf().canvas.mpl_connect('key_release_event', lambda event: [exit(0) if event.key == 'escape' else None]) if len(closed_set.keys()) % 10 == 0: plt.pause(0.001) # 通过追踪当前位置current.x和current.y来动态展示路径寻找 if current.x == goal_node.x and current.y == goal_node.y: print("Find goal") goal_node.parent_index = current.parent_index goal_node.cost = current.cost break # Remove the item from the open set del open_set[c_id] # Add it to the closed set closed_set[c_id] = current # expand_grid search grid based on motion model for i, _ in enumerate(self.motion): """计算能耗代价""" n1x = current.x n1y = current.y n2x = current.x + self.motion[i][0] n2y = current.y + self.motion[i][1] if n2x < 0 or n2x >= len(data1) or n2y < 0 or n2y >= len(data1[0]): continue vx1 = data1[n2x][n2y]*1.94 vy1 = data2[n2x][n2y]*1.94 vx2 = 0 # 空值 vy2 = 0 # 空值 dis = 0 # 空值 if n2y>n1y and n2x>n1x: vx2 = 4/np.sqrt(2) vy2 = 4/np.sqrt(2) dis = 1.25/2 if n2y>n1y and n2x<n1x: vx2 = -4/np.sqrt(2) vy2 = 4/np.sqrt(2) dis = 1.25/2 if n2y<n1y and n2x<n1x: vx2 = -4/np.sqrt(2) vy2 = -4/np.sqrt(2) dis = 1.25/2 if n2y<n1y and n2x>n1x: vx2 = 4/np.sqrt(2) vy2 = -4/np.sqrt(2) dis = 1.25/2 if n2y>n1y and n2x==n1x: vx2=0 vy2=4 dis = 0.92/2 if n2y<n1y and n2x == n1x: vx2 = 0 vy2 = -4 dis = 0.92/2 if n2y==n1y and n2x >n1x: vx2 = 4 vy2 = 0 dis = 0.84/2 if n2y==n1y and n2x <n1x: vx2 = -4 vy2 = 0 dis = 0.84/2 vt = math.sqrt((vx1-vx2)**2+(vy1-vy2)**2) if vt <= 1: en = dis * 0.06 if vt > 1 and vt<=2: en = dis * 0.08 if vt > 2 and vt<=3: en = dis * 0.11 if vt > 3 and vt <= 4: en = dis * 0.15 if vt > 4 and vt <= 5: en = dis * 0.2 w = 0 q = 0 """计算概率代价""" p1=data3[n2x][n2y] p2=data4[n2x][n2y] P=(p1+p2) node = self.Node(current.x + self.motion[i][0], current.y + self.motion[i][1], current.cost + self.motion[i][2]+en * w+P*q, c_id) n_id = self.calc_grid_index(node) # If the node is not safe, do nothing if not self.verify_node(node): continue if n_id in closed_set: continue if n_id not in open_set: open_set[n_id] = node # discovered a new node else: if open_set[n_id].cost > node.cost: # This path is the best until now. record it open_set[n_id] = node rx, ry = self.calc_final_path(goal_node, closed_set) return rx, ry def calc_final_path(self, goal_node, closed_set): # generate final course rx, ry = [self.calc_grid_position(goal_node.x, self.min_x)], [ self.calc_grid_position(goal_node.y, self.min_y)] parent_index = goal_node.parent_index while parent_index != -1: n = closed_set[parent_index] rx.append(self.calc_grid_position(n.x, self.min_x)) ry.append(self.calc_grid_position(n.y, self.min_y)) parent_index = n.parent_index return rx, ry @staticmethod def calc_heuristic(data1,data2,n1, n2): """计算启发函数 Args: n1 (_type_): _description_ n2 (_type_): _description_ Returns: _type_: _description_ """ """定义海水流速造成的能耗损失代价""" """定义目标被发现的概率代价""" w = 1.0 # weight of heuristic d = w * math.hypot(n1.x - n2.x, n1.y - n2.y) return d def calc_grid_position(self, index, min_position): """ calc grid position :param index: :param min_position: :return: """ pos = index * self.resolution + min_position return pos def calc_xy_index(self, position, min_pos): return round((position - min_pos) / self.resolution) def calc_grid_index(self, node): return (node.y - self.min_y) * self.x_width + (node.x - self.min_x) def verify_node(self, node): px = self.calc_grid_position(node.x, self.min_x) py = self.calc_grid_position(node.y, self.min_y) if node.x < 0 or node.x >= self.x_width or node.y < 0 or node.y >= self.y_width: return False # 如果超出范围,返回 False # 检查节点是否碰到障碍物 if self.obstacle_map[node.x][node.y]: return False # 如果该位置是障碍物,返回 False if px < self.min_x: return False elif py < self.min_y: return False elif px >= self.max_x: return False elif py >= self.max_y: return False # collision check if self.obstacle_map[node.x][node.y]: return False return True def calc_obstacle_map(self, ox, oy): self.min_x = round(min(ox)) self.min_y = round(min(oy)) self.max_x = round(max(ox)) self.max_y = round(max(oy)) print("min_x:", self.min_x) print("min_y:", self.min_y) print("max_x:", self.max_x) print("max_y:", self.max_y) self.x_width = round((self.max_x - self.min_x) / self.resolution) self.y_width = round((self.max_y - self.min_y) / self.resolution) print("x_width:", self.x_width) print("y_width:", self.y_width) # obstacle map generation self.obstacle_map = [[False for _ in range(self.y_width)] for _ in range(self.x_width)] for ix in range(self.x_width): x = self.calc_grid_position(ix, self.min_x) for iy in range(self.y_width): y = self.calc_grid_position(iy, self.min_y) for iox, ioy in zip(ox, oy): d = math.hypot(iox - x, ioy - y) if d <= self.rr: self.obstacle_map[ix][iy] = True break @staticmethod def get_motion_model(): # dx, dy, cost motion = [[1, 0, 841/925], [0, 1, 1], [-1, 0, 841/925], [0, -1, 1], [-1, -1, np.sqrt(841**2+925**2)/925], [-1, 1, np.sqrt(841**2+925**2)/925], [1, -1, np.sqrt(841**2+925**2)/925], [1, 1, np.sqrt(841**2+925**2)/925]] # motion = [[0, 1, 841 / 925], # [1, 0, 1], # [0, -1, 841 / 925], # [-1, 0, 1], # [-1, -1, 1250 / 925], # [1, -1, 1250 / 925], # [-1, 1, 1250 / 925], # [1, 1, 1250 / 925]] return motion def main(): print(__file__ + " start!!") # # start and goal position sx = 165 # [m] sy = 37 # [m]145 29 gx =26 # [m] gy = 74 # [m]31,101 # sx = 470 # [m] # sy = 88 # [m]145 29 # gx = 84 # [m] # gy =242 # [m]31,101 grid_size = 2.0 # [m] robot_radius = 1.0 # [m] ox, oy = [], [] # obstacle_x = [] # obstacle_y = [] rows, cols = data.shape for i in range(1, rows): for j in range(1, cols): if data[i][j] == 0: # 检查是否为空 oy.append(i) # y坐标 ox.append(j) # x坐标 if show_animation: # pragma: no cover plt.plot(ox, oy, ".k") plt.plot(sx, sy, "og") plt.plot(gx, gy, "xb") plt.grid(True) plt.axis("equal") a_star = AStarPlanner(ox, oy, grid_size, robot_radius) rx, ry = a_star.planning(sx, sy, gx, gy,data,data1,data3,data4) if show_animation: # pragma: no cover plt.plot(rx, ry, "-r") plt.pause(0.001) plt.show() if __name__ == '__main__': main() 分析一下这段代码,告诉哪些地方设置的不合理或者有问
最新发布
06-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值