您的位置:首页 > 大数据 > 人工智能

【人工智能】作业1: Bait游戏 实验报告

2018-03-25 17:32 495 查看

作业1: Bait游戏 实验报告

151220129 计科 吴政亿

任务一 深度优先搜索

变量简介

变量类型变量名变量含义
ArrayListcloseList存储已经走过的历史路径
booleanisCalculated是否得到了能走到终点的答案
ArrayListdepthFirstAction存储dfs中的每一步动作
intnowStep当前步骤在depthFirstAction的下标

函数简介

返回类型函数名传入参数函数功能
booleanisInCloseListStateObservation obs检测是否在历史状态中
booleangetDepthFirstStateObservation stateObs, ElapsedCpuTimer elapsedTimer计算从stateObs出发的深度优先路径,如果找到则返回true
Types.ACTIONSactStateObservation stateObs, ElapsedCpuTimer elapsedTimer根据局面stateObs调用getDepthFirst并返回当轮动作
voiddebugPrintTypes.ACTIONS act输出act动作信息
voiddebugPrintAllActionArrayList actions输入actions中所有动作信息

核心代码

boolean getDepthFirst(StateObservation stateObs, ElapsedCpuTimer elapsedTimer){
if(stateObs in closeList)
return false;
else
closeList.add(stateObs);
stCopy = stateObs.copy();
for(all actions in stateObs){
try this action in stCopy;
depthFirstAction.add(action);
if(win)
return true; // all actions are in 'depthFirstAction'
else if(stateObs in closeList || Game over){
stCopy = stateObs.copy(); // reset stCopy
depthFirstAction.delete(action);
continue;
}
else{ // a new state
if(getDepthFirst(stCopy,elapsedTimer))
return true;
else {
stCopy = stateObs.copy(); // reset stCopy
depthFirstAction.delete(action);
continue;
}
}
}
return false;
}


任务二 深度受限的深度优先搜索

变量简介

变量类型变量名变量含义
ArrayListcloseList存储已经走过的历史路径
ArrayListstateDepth历史路径里对应的每一个的深度
ArrayListlimitDepthFirstAction存储limitdfs中的每一步动作
doublebestCost精灵与目标在state中最优状态的距离
Vector2dgoalpos门的位置
Vector2dkeypos钥匙的位置

函数简介

返回类型函数名传入参数函数功能
voidinitAgentnull初始化Agent
booleanisInCloseListStateObservation obs检测是否在历史状态中
voidlimitDepthFirstStateObservation stateObs, ElapsedCpuTimer elapsedTimer, int depth计算从stateObs出发的受限层数为depth的深度优先路径
Types.ACTIONSactStateObservation stateObs, ElapsedCpuTimer elapsedTimer根据局面stateObs调用limitDepthFirst并返回当轮动作
voiddebugPrintTypes.ACTIONS act输出act动作信息
voiddebugPrintAllActionArrayList actions输入actions中所有动作信息
doublegetDistanceVector2d vec1, Vector2d vec2返回vec1与vec2的曼哈顿距离
booleanavatarGetKeyStateObservation stateObs判断精灵是否得到钥匙
doubleheuristicStateObservation stateObs启发式函数,返回局面评分
voiddebugPosVector2d vec, String head输出vec的位置信息

核心代码

protected void limitDepthFirst(StateObservation stateObs, ElapsedCpuTimer elapsedTimer, int depth){
if(Reach the end of limitDepthFirst){
nowStateScore = heuristic(stateObs);
if(nowStateScore better than bestCost)
bestAction = now actions;
return;
}
else if(stateObs is not game start){
if(stateObs in closeList && depth same)
return;
else{
closeList.add(stateObs);
stateDepth.add(depth);
}
}
else{ // at the beginning of limitdfs, init all
closeList.clear();
stateDepth.clear();
}

for(all actions in stateObs){
try this action in stCopy;
limitDepthFirstAction.add(action);
if(Game win) {
nowStateScore = heuristic(stateObs);
if(nowStateScore better than bestCost)
bestAction = now actions;
stCopy = stateObs.copy(); // reset stCopy
limitDepthFirstAction.delete(action);
continue;
}
else{
limitDepthFirst(stCopy,elapsedTimer,depth);
stCopy = stateObs.copy(); // reset stCopy
limitDepthFirstAction.delete(action);
continue;
}
}
}


任务三 A*搜索

根据自己自行测试,可以在有限时间内完成第二关与第三关的搜索并成功通关。

变量简介

变量类型变量名变量含义
ArrayListcloseList存储已经走过的历史路径
PriorityQueueopenList存储尚未走的已探索到的步骤
booleangetAnswer是否得到了能走到终点的答案
ArrayListaStarAction存储aStar中的每一步动作
Vector2dgoalpos门的位置
Vector2dkeypos钥匙的位置

函数简介

返回类型函数名传入参数函数功能
voidinitAgentnull初始化Agent
booleanisInCloseListStateObservation obs检测是否在历史状态中
booleanisInOpenListStateObservation obs检测是否在尚未走的已搜索到的区域中
voidaStarStateObservation stateObs, ElapsedCpuTimer elapsedTimer, int depth计算从stateObs出发的受时间限制的aStar路径
Types.ACTIONSactStateObservation stateObs, ElapsedCpuTimer elapsedTimer根据局面stateObs调用aStar并返回当轮动作
doublegetDistanceVector2d vec1, Vector2d vec2返回vec1与vec2的曼哈顿距离
booleanavatarGetKeyStateObservation stateObs判断精灵是否得到钥匙
doubleheuristicStateObservation stateObs启发式函数,返回局面评分

核心代码

protected void aStar(StateObservation stateObs, ElapsedCpuTimer elapsedTimer) {
initAgent();
openList.add(startNode); // 将初始状态加入openList
while(!openList.isEmpty())
{
Node tmp = openList.poll(); // 取得分最高的节点tmp
aStarAction = tmp.actions; // 将aStarAction初始化为tmp从起点到当前位置的所有动作
closeList.add(tmp.stateObs.copy()); // 将tmp的状态加入closeList中标记已走过

for(all actions in stateObs){
stCopy = tmp.stateObs.copy();
try this action in stCopy;
aStarAction.add(act);
if(Game win) {
getAnswer = true;
return ; // 最终的序列步骤在aStarAction中
}
else if(Game over || stateObs in closeList) { // 如果游戏结束或发现曾走过,则回溯
aStarAction.delete(action);
continue;
}
else if(stateObs in openList){ // 如果发现当前局面在openList待尝试
if(new actions better than old){ // 如果当前走法优于之间走法
refresh openList; // 则更新动作
}
aStarAction.delete(action); // 回溯
}
else{ // 这是一个新的动作
openList.add(new Node(stCopy,heuristic(stCopy),aStarAction)); // 加入新的动作
aStarAction.delete(action); // 回溯
}
}
}
}


任务四 蒙特卡洛树搜索

算法框架

while(时间限制内){
treePolicy选择一个当前可达状态selected;
对子状态执行rollOut,得到得分;
从selected开始执行backUp;
}
通过mostVisitedAction返回次数最大的动作并作为结果;


函数简介

函数名传入参数函数功能
rollOutnull不断随机向下搜索,当游戏结束或达到递归层数后对状态评分。更新Agent得分bound后返回得分。
backUpSingleTreeNode node, double result传入一个节点与他的得分,对这个节点与他的所有祖先节点,访问次数+1,总分+=得分。
treePolicynull如果当前节点有子节点未访问,则返回其中一个,否则调用uct从所有子节点中选择一个。
uctnull根据子节点总分,访问次数,Agent的得分bound计算节点分数,然后选择得分最高的返回。

核心代码

uct算法作为关键,他的子节点计算方式如下:

childValue(平均估值) = normalize(childTotalValuechildVisitTimes+ϵ),(ϵ=1∗10−6)normalize(childTotalValuechildVisitTimes+ϵ),(ϵ=1∗10−6)

uctValue(节点分数) = childValue+2lnparentVisitTimes+1childVisitTimes+ϵ−−−−−−−−−−−−−−−√+ξ,ξchildValue+2ln⁡parentVisitTimes+1childVisitTimes+ϵ+ξ,ξ是噪声

简而言之,访问次数少的,平均分高的子节点节点分数更高,更容易被roolOut选中。由于在act中我们返回的是访问次数最多的子节点作为状态,所以可以看出uct对于可能成功的子节点更友好。

运行结果





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息