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

作业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+ϵ),(ϵ=1106) n o r m a l i z e ( c h i l d T o t a l V a l u e c h i l d V i s i t T i m e s + ϵ ) , ( ϵ = 1 ∗ 10 − 6 )
uctValue(节点分数) = childValue+2lnparentVisitTimes+1childVisitTimes+ϵ+ξ,ξ c h i l d V a l u e + 2 ln ⁡ p a r e n t V i s i t T i m e s + 1 c h i l d V i s i t T i m e s + ϵ + ξ , ξ 是噪声

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

运行结果

lvl0

lvl1

lvl2

  • 4
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值