Java迷宫解决和强化学习

时间:2012-03-25 17:08:27

标签: java maze

我正在编写代码来自动模拟这个逻辑游戏中显示的Theseus和Minoutaur的动作; http://www.logicmazes.com/theseus.html

对于每个迷宫,我为它提供了迷宫的位置,以及哪些位置可用,例如从位置0开始,下一个状态是1,2或保持为0.我运行QLearning实例,计算这些的最佳路径避开迷宫假设没有迷你世界。然后介绍牛头怪。忒修斯首次走向出口并不可避免地被抓住,导致重新加入最佳路径。在游戏中使用迷宫3作为测试,这种方法导致这些在中间线上无限地上下移动,因为这是唯一没有被杀死的动作。

根据在过去几天收到的建议,我调整了我的代码,以考虑状态既是thesesus的位置,也是在给定时间的牛头人。当这些状态移动时,状态将被添加到“访问状态”列表中。通过将建议移动的状态与访问状态列表进行比较,我能够确保这些状态不会导致以前的州。

问题是我需要能够在某些情况下重新访问。例如,使用迷宫3作为示例,并且minotaur移动2x用于每个移动。 忒修斯4 - > 5,状态添加(t5,m1)。 mino move 1-> 5。忒修斯抓住了,重置。 4-> 5是一个不好的动作,所以这些动作移动4-> 3,mino捕获轮到他。现在(t5,m1)和(t3 m1)都在访问列表中

所发生的事情是从初始状态的所有可能状态都被添加到不访问列表中,这意味着我的代码无限循环并且无法提供解决方案。

public void move()
{
    int randomness =10;
    State tempState = new State();
    boolean rejectMove = true;
    int keepCurrent = currentPosition;
    int keepMinotaur = minotaurPosition;

    previousPosition = currentPosition;
    do
    {
        minotaurPosition = keepMinotaur;
        currentPosition = keepCurrent;
        rejectMove = false;

        if (states.size() > 10)
        {
            states.clear();
        }


        if(this.policy(currentPosition) == this.minotaurPosition )
        {
            randomness = 100;
        }

        if(Math.random()*100 <= randomness)
        {
            System.out.println("Random move");
            int[] actionsFromState = actions[currentPosition];
            int max = actionsFromState.length;
            Random r = new Random();
            int s =  r.nextInt(max);    

            previousPosition = currentPosition;
            currentPosition = actions[currentPosition][s];
        }
        else
        {
            previousPosition = currentPosition;
            currentPosition = policy(currentPosition);
        }

        tempState.setAttributes(minotaurPosition, currentPosition);
        randomness = 10;    

        for(int i=0; i<states.size(); i++)
        {
            if(states.get(i).getMinotaurPosition() == tempState.getMinotaurPosition()  &&  states.get(i).theseusPosition == tempState.getTheseusPosition())
            {

                rejectMove = true;

                changeReward(100);

            }
        }

    }
    while(rejectMove == true);

    states.add(tempState);
}       

以上是忒的移动方法;显示它偶尔暗示随机移动

2 个答案:

答案 0 :(得分:2)

这里的问题是“从未访问过你曾经进入的状态”方法和“强化学习”方法之间存在差异。当我建议“永远不会访问你以前曾经进入过的状态”的方法时,我假设你正在使用回溯:一旦Theseus被抓住,你就会将筹码放到他做出非强制选择的最后一个地方,然后尝试不同的选项。 (也就是说,我假设你正在使用一个简单的深度优先搜索状态空间。)在这种方法中,从来没有任何理由访问你之前访问过的状态。

对于你的“强化学习”方法,每当Theseus被抓住你完全重置迷宫时,你需要改变它。我想你可以改变“永远不会访问你曾经进入过的状态”规则,这是一个双管齐下的规则:

  • 从不访问您在迷宫运行期间所处的状态。 (这是为了防止无限循环。)
  • 不赞成访问您在捉住Theseus的迷宫运行期间所处的状态。 (这是“学习”的一部分:如果选择以前效果不佳,则应该不经常做出选择。)

答案 1 :(得分:2)

对于什么是值得的,解决这个问题的最简单方法最佳是使用ALPHA-BETA,这是一种确定性双人游戏的搜索算法(如tic-tac-toe) ,西洋跳棋,国际象棋)。以下是如何根据您的情况实施它的摘要:

  1. 创建一个表示游戏当前状态的类 应该包括:Thesesus的位置,Minoutaur的位置和 轮到它了。假设您将此课程称为GameState

  2. 创建一个启发式函数,该函数将GameState的实例作为paraemter,并返回一个计算如下的double:

    • 设Dt为忒修斯从出口处的Manhattan distance(方格数)。

    • 让Dm为Minotaur来自Theseus的曼哈顿距离(方格数)。

    • 如果是忒修斯,则T为1,如果是牛头怪,则为-1。

    • 如果Dm不为零且Dt不为零,则返回Dm +(Dt / 2)* T

    • 如果Dm为零,则返回-Infinity * T

    • 如果Dt为零,则返回Infinity * T

  3. 上面的启发式函数返回维基百科称为算法伪代码中给定GameState(节点)的“节点的启发式值”的值。

    现在,您已拥有使用Java编写代码的所有元素。