算法题目打卡:Ques20201024
问题1
描述
你的目标是让机器人走出迷宫。机器人面朝北,开始位置是在迷宫中间,你 可以让机器人转向面朝东、南、西、北。你可以让机器人向前走一段距离,在撞墙之前它会停步。
a. 将问题形式化,状态空间有多大?
形式化如下:
状态:状态由机器人的位置和朝向所确定,当下一个位置只有4个朝向可选,可能的状态数为4,再下一次同样有4个朝向可选,选择朝向与前进的行动是连续的。
初识状态:机器人面朝北。
转移模型:面朝任何一个方向都可向前走,除非即将撞墙。
目标测试:测试当前位置是否走出迷宫。
路径消耗:总的耗散值为机器人移动的距离.
由于机器人在移动过程中,位置朝向并没有限制条件,而机器人的移动也非离散的,因此可能状态呈指数级增长,状态空间为无穷大。
b. 在迷宫中游走,在两条路或更多路交叉的路口可以转弯,重新形式化这个问题,现在状态空间有多大?
状态:状态受机器人的位置所确定,当所处的位置为交叉路口时,才可转弯至下一个状态,状态需要记录下交叉路口的位置以及个数。
初识状态:机器人在迷宫正中间面朝北。
转移模型:走到下一个交叉路口,除非即将撞墙。
目标测试:测试当前位置是否走出迷宫。
路径消耗:总的耗散值为移动距离.
机器人在移动过程中,状态空间受交叉路口个数影响(在其他时刻不改变朝向),当交叉路口为1时,可能状态为4,为2时可能状态为8,当交叉路口为n时状态空间为4n。
c. 从迷宫的任一点出发,我们可以朝四个方向中的任一方向前进直到可以转弯的地方,而且我们只需要这样做,重新对这个问题进行形式化,我们只需要记录机器人的方向吗?
状态:状态由机器人的位置和朝向所确定,当所处的位置为交叉路口时,下一个位置朝向有4个朝向可选,并且,还可转弯至下一个状态,状态需要记录下交叉路口的位置以及个数。
初识状态:机器人在迷宫正中间面朝北。
转移模型:面朝任何一个方向都可向前走,除非即将撞墙。
目标测试:测试当前位置是否走出迷宫。
路径消耗:总的耗散值为移动距离.
不需要记录方向信息,只需要记录交叉路口位置,因为在交叉路口才会有新的状态,与方向信息无关。
d. 在我们最初对问题的最初描述中已经对现实世界进行了抽象,限制了机器人的行动并移除了细节,列出三个我们做的简化。
简化1:机器人的移动速度
简化2:机器人以何种方式作为驱动力
简化3:机器人传感器种类,摄像头或红外测距
问题2
传教士和野人问题,三个传教士和三个野人在河的一岸,有一条能载一个人或者两个人的船。请设法使所有人都渡到河的另一岸,要求在任何地方野人数都不能多于传教士的人数。这个问题在AI中很有名,是因为它是第一个从分析的观点探讨问题形式化的论文主题。
a. 请对该问题进行详细形式化,只描述确保该问题求解所必需的特性。画出完整的状态空间图。
问题解决参考自:https://www.jianshu.com/p/0af3a6bb1e43
一些前提:从左岸到右岸是有往返的,其中传教士和野人均可以开船,状态在转化过程中不能出现循环,即舍弃掉会恢复上一步的状态。问题形式化如下:
状态:用一个三元组(m,c,b)来表示河岸上的状态,其中m、c分别代表某一岸上传教士与野人的数目,b用来表示船是从左岸到对岸还是返程(b=1表示船在这一岸,b=0则表示船不在)。约束条件是:两岸上船上
≤2,为船上的传教士和野人数量。
初识状态:三元组初态为(3,3,1),即左岸野人和传教士都为3。
转移模型:船从左岸开到右岸,b从0-->1,再从1-->0。只要不满足限制条件,则进入下一个状态。
目标测试:是否达到终态(0,0,0)。
路径消耗:走的路径长度.
状态空间图:
b.应用合适的搜索算法求出该问题的最优解。对于这个问题检查重复状态是个好主意吗?
利用深度优先搜索算法求解该问题,代码如下:
#include<iostream>
#include<cstdio>
#include<map>
#include<string>
#include<set>
#include<vector>
using namespace std;
using namespace std;
int N;
set<string>ans;
void print(vector<int>way) {int i = 0;string h;for (i = 1; i < way.size(); i++) {if (way[i] < 100) {h += "0";}h += to_string(way[i]);h += " ";}ans.insert(h);
}
void dfs(int pre, int ni, int nj, int b, set<int>s, vector<int>way) {int now = ni * 100 + nj * 10 + b;// s.insert(pre);if (s.count(now) || (N - ni) < 0 || (N - nj) < 0 || ni < 0 || nj < 0 || (ni < nj && ni != 0) || ((N - ni) < (N - nj) && (N - ni) != 0)) {// 限制条件,若传教士和野人数都小于0,或者剩下的传教士比野人少都直接returnreturn;}if (pre == 0) {// 如果上一轮就截止了,pre == 0 代表已到终点状态print(way);return;}way.push_back(pre);if (b == 1) { // 需前往对岸// 传教士+野人=1dfs(now, ni - 1, nj, 0, s, way);dfs(now, ni, nj - 1, 0, s, way);// 传教士+野人=2dfs(now, ni - 2, nj, 0, s, way);dfs(now, ni, nj - 2, 0, s, way);dfs(now, ni - 1, nj - 1, 0, s, way);}else {// 传教士+野人=1dfs(now, ni + 1, nj, 1, s, way);dfs(now, ni, nj + 1, 1, s, way);// 传教士+野人=2dfs(now, ni + 2, nj, 1, s, way);dfs(now, ni, nj + 2, 1, s, way);dfs(now, ni + 1, nj + 1, 1, s, way);}
}
//Ques20201024
int main() {int b = 1;// 初始化b的值int m, c;int pre = -1;set<int>s;chooseN = 3;N = c = m = 3;vector<int>way;dfs(pre, m, c, b, s, way);for (auto it = ans.begin(); it != ans.end(); it++) {cout << *it << endl;}
}
运行效果
求解得到的最优路径共4条,如上图解空间中所示。
c. 这个问题的状态空间很简单,你认为是什么导致人们求解它很困难?
在求解过程中可能运过去两个人,然后又把同样的两个人运回来了(或者使用别的形式但是依旧是循环,即没有起到作用),所以要去除这种重复,这是问题的难解决的地方。最好方法是使用带有记忆的状态,如果之前遇到过这种状态就直接return,返回上一状态。
算法题目打卡:Ques20201024相关推荐
- 本专栏所有力扣题目的目录链接, 刷算法题目的顺序(由易到难/面试频率)/注意点/技巧, 以及思维导图源文件问题(持续更新中)
这篇文章为本专栏所有力扣题目提供目录链接, 更加方便读者根据题型或面试频率进行阅读, 此外也会介绍我在刷题过程中总结的刷算法题目的顺序/注意点/技巧, 最后说下文中出现的思维导图源文件的问题 和 打卡 ...
- PTA数据结构与算法题目集6-4 6-3 6-8
PTA数据结构与算法题目集(中文) 6-4 链式表的按序号查找 ElementType FindKth( List L, int K ){int index = 0;while(L){++index; ...
- PTA数据结构与算法题目集 6-9 二叉树的遍历
PTA数据结构与算法题目集(中文) 6-9 二叉树的遍历 void InorderTraversal( BinTree BT ){if(BT==NULL)return;if(BT->Left){ ...
- leetcode的回溯算法题目用这个模板解题,一网打尽,so easy!!!
" 这是本人第 46 篇原创博文,每周至少两篇更新,谢谢赏脸阅读文章 这一篇文章来讲解一下如何做leetcode回溯算法题目,这一段时间我把leetcode上面的回溯算法的题目都刷了个遍,发 ...
- 微软面试中简单的算法题目(转)
微软面试中简单的算法题目(转) (说明:这些题就不是什么花样了,考的是你的基础知识怎么样.再聪明而没有实学的人都将会被这些题所淘汰.) 1.链表和数组的区别在哪里? ANSWER 主要在基本概念上的 ...
- 算法题目中经典问题(易错点)
算法题目中经典问题.易错点 (一).二维数组的传参问题 1.方法一:形参为二维数组并给定第二维长度 2.方法二:形参为指向数组的指针并给出数组长度 3.二维数组定义为全局变量 (二).多组测试控制台数 ...
- PTA 数据结构与算法题目集(中文)
一:数据结构与算法题目(中文版) 7-2 一元多项式的乘法与加法运算 (20 分) 7-3 树的同构 (25 分) 7-4 是否同一棵二叉搜索树 (25 分) 7-6 列出连通集 (25 分)(详解) ...
- 数据结构与算法题目集7-32——哥尼斯堡的“七桥问题”
我的数据结构与算法题目集代码仓:https://github.com/617076674/Data-structure-and-algorithm-topic-set 原题链接:https://pin ...
- HihoCoder上网络流算法题目建模总结
经过了几天的学习和做题,我利用刘汝佳书上的网络流算法模板完成了HihoCoder上的几个网络流算法,HihoCoder可能还会继续更新网络流算法,所以我也会接着总结. 这个主要是对网络流算法的建模做分 ...
- java 完美洗牌,(2)数组相关算法题目
数组是最简单的数据结构,占据连续内存并且按顺序存储. 以下是与数组有关的算法题目. (1)查询数组中重复数字 算法思路:(1)利用hash表,没有便放进去,有就返回(Java中HashMap存数字都是 ...
最新文章
- 关于Ubuntu20.04 sudo vi找不到命令解决方法
- ios遍历模块的方式
- arcgis两点之间连线_ArcGIS中实现一种流向地图的方法
- Linux / Ubuntu Desktop / 设置静态 IP 的方法
- 担心被绑架?多云战略为企业解烦忧!
- Why I always see warning message Object is in status Wait using R3AS
- MyEclipse2015 Web项目转Maven项目
- LeetCode 851. 喧闹和富有(拓扑排序)
- 金笛邮件中使用wap邮箱
- HTML中name与id的区别
- ZOC for Mac(终端仿真器)
- 求知若渴,一份15选8的套餐给你
- 最近帮客户优化的一个通讯应用
- 获取到的数组在webview中成了字符串
- STM8L开发环境配置
- java 正则表达式 检测数学公式是否正确_java 正则表达式 检测数学公式是否正
- 电脑PC端如何下载B站视频?
- 微信公众号扫码授权登录思路
- 计算机毕业设计JAVA人民医院体检预约mybatis+源码+调试部署+系统+数据库+lw
- AI 赋能教育,松鼠 AI 智适应学习方案大揭秘