IEEE国际标准电脑鼠走迷宫竞赛,简单来说是使用微控制器、传感器和机电运动部件构成的一种智能行走机器人,本文仅对”到达迷宫终点",这一问题进行算法上的思索与解决。
一共三个坑,一个坑填一个数,我们通过开设一个状态数组来标记当前尚未使用的数,每次填入坑中,当一个节点无路可走或走到头是,回溯到最近的一个节点去搜索下一条路
核心操作:
void dfs(int u)
{
if(u == n)//坑满了
{
for(int i = 0; i < n; i ++)
cout << path[i] << " ";
cout << endl;
return;
}
for(int i = 1; i <= n; i ++)
if(!st[i])//找没用过的填坑
{
path[u] = i;//填坑
st[i] = true;
dfs(u + 1);//分支向下走
st[i] = false;//恢复现场
}
}
思路:小鼠从起点出发,一旦撞墙就返回到上一岔路口,尝试不同的转向,尝试过的道路标记一下,不走回头路浪费时间,不断深入迷宫,最终到达终点。
题境:给出一个n*m的01迷宫,0可走,1不可走,从(1, 1)走到(n, m)
核心操作:
void dfs(int x, int y, int cnt)
{
if(x == n && y == m)
{
tt ++;//记录从起点到终点的方案数
if(cnt < ans)//记录最短步数
ans = cnt;
return;
}
int f[5] = {1, 0, -1, 0, 1};//方向数组,四方通行
for(int i = 0; i < 4; i ++)
{
int xx = x + f[i], yy = y + f[i + 1];
if(xx > 0 && yy > 0 && xx <= n && yy <= m && !g[xx][yy] && !st[xx][yy])
{
st[xx][yy] = 1;
dfs(xx, yy, cnt + 1);
st[xx][yy] = 0;//及时回溯,下一条路
}
}
}
思路:小鼠从起点出发,沿着交叉路口的某一分支前进,到下一个路口的时候回去检查,反复循环,达到一层层向外拓展的目的,直到找到终点。(听起来好像更麻烦了,但在实操里时间复杂度还是比暴搜低的)
代码思路:用一个队列来实现(STL大法,数组模拟自己够呛),开一个距离数组,来表示每个点到起点的距离,初始为-1,存入起点,开始上下左右向外拓展,每到一个新位置,距离+1,并存入新位置,注意,当开始探索下一位置时,岔路口的先前存入的坐标要弹出队列,表示不再回头记录。最终当队列为空时,即无路可走,到达终点,此时终点的距离数组的坐标即为所求最短距离。(描述粗糙,见谅)
核心操作:
int bfs()
{
queue q;
q.push({0, 0});
memset(d, -1, sizeof d);//距离数组初始化
d[0][0] = 0;
while(!q.empty())
{
auto t = q.front();
q.pop();//勿忘弹出,再也不见
for(int i = 0; i < 4; i ++)//方向数组同上
{
int x = t.first + f[i], y = t.second + f[i + 1];
if(x < n && y < m && x >= 0 && y >= 0 && g[x][y] == 0 && d[x][y] == -1)
{
d[x][y] = d[t.first][t.second] + 1;//比上一步距离起点+1
q.push({x, y});//这点要压入队列
}
}
}
return d[n - 1][m - 1];//最终答案,终点距离起点的最短距离
}
洪水填充算法:一张图上有多个区域,不同的区域用不同颜色区分,同一个区域的所有点的颜色 (oldColor) 都是相同的。给定图上的一个点,称为种子点,然后从种子点出发,把种子点所属的封闭区域用新颜色 (fillColor) 填充,这就是 “洪水填充”。(了解不深)
实现:用DFS和BFS均可进行实现,上图为通用的四邻域填充法,当然也有八向填充,接受三个参数—起始节点,目标节点以及提取对象要执行的处理。
实际:假设小鼠与终点之间无障碍,小鼠可以直接到达终点,此时在这条"最短路径"上,遇到墙壁便标记起来,并重新规划路线,一直朝终点前进。"祖传代码"会标记出每一点距离终点的距离,碰到墙壁处返回,数字重新标记,此时小鼠沿着递减路线直达终点便是最短路线。任何事不会有完美的,洪水填充算法,不保证第一次便找到最佳路径,但其进一步优化了策略,避免了行走许多重复路线。
算法总归要应用于实际,电脑鼠走迷宫的比赛需要电子信息,程序设计,机械工程,自动控制,传感与测试等多项技术知识。向小鼠走迷宫,我们往往会将目光局限在"最短",可最短不一定最快,转弯速度同样影响平均速度,比起现实,我们需要考虑的还远远不止编译器上的几行代码。
在近期的全国大学生机器人大赛高校对抗赛(机甲大师赛)中,电子科技大学的兔子机器人一跃而起,抢占先机,赢下半决赛冠军,并在之后与广州城市理工学院的决赛中,跳跃式拿下最后总冠军。这是一场创新性的比赛,不拘泥于传统,推陈出新,科技的进步同样如此。
本文参考:(https://zhuanlan.zhihu.com/p/51538950),b站洪水填充,acwing