Java迷宫求解与强化学习

Java迷宫求解与强化学习,java,maze,Java,Maze,我正在编写代码,以自动模拟忒修斯和美诺陶尔的动作,如本逻辑游戏所示 对于每个迷宫,我向其提供迷宫的位置,以及哪些位置可用,例如从位置0开始,接下来的状态为1,2或保持在0。我运行了一个QLearning实例,它计算了忒修斯在没有牛头怪的情况下逃离迷宫的最佳路径。然后介绍了牛头人。忒修斯第一次朝出口走去,不可避免地被抓住了,这导致了对最佳路径的重新称重。在游戏中使用迷宫3作为测试,这种方法导致特修斯在中线上下移动,因为这是唯一没有杀死它的动作 根据过去几天里的一个建议,我调整了我的代码,把状态考虑

我正在编写代码,以自动模拟忒修斯和美诺陶尔的动作,如本逻辑游戏所示

对于每个迷宫,我向其提供迷宫的位置,以及哪些位置可用,例如从位置0开始,接下来的状态为1,2或保持在0。我运行了一个QLearning实例,它计算了忒修斯在没有牛头怪的情况下逃离迷宫的最佳路径。然后介绍了牛头人。忒修斯第一次朝出口走去,不可避免地被抓住了,这导致了对最佳路径的重新称重。在游戏中使用迷宫3作为测试,这种方法导致特修斯在中线上下移动,因为这是唯一没有杀死它的动作

根据过去几天里的一个建议,我调整了我的代码,把状态考虑为SeeSUS和MioToor在给定时间的位置。当特修斯将采取行动时,该州将被添加到“受访州”列表中。通过将建议的行动产生的州与受访州列表进行比较,我能够确保特修斯不会采取会导致先前状态的行动

问题是,在某些情况下,我需要能够重新访问。例如,以迷宫3为例,牛头怪每移动一次忒修斯,就移动2次。 忒修斯移动4->5,增加状态(t5,m1)。米诺移动1->5。特修斯被抓住,复位。4->5是一个糟糕的动作,因此忒修斯移动4->3,米诺在轮到他时接住。现在(t5,m1)和(t3 m1)都在访问列表中

发生的情况是,从初始状态开始的所有可能状态都被添加到dont visit列表中,这意味着我的代码不确定地循环,无法提供解决方案

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);
}       
公共作废移动()
{
int随机性=10;
State tempState=新状态();
布尔值=真;
int keepCurrent=当前位置;
int keepMinotaur=位置;
previousPosition=当前位置;
做
{
牛头人位置=keepMinotaur;
currentPosition=keepCurrent;
拒绝移动=错误;
如果(states.size()>10)
{
状态。清除();
}
if(this.policy(currentPosition)=this.policy(currentPosition)
{
随机性=100;
}

如果(Math.random()*100这里的问题是“从不访问您以前所处的状态”方法和“强化学习”方法之间的差异。当我推荐“从不访问您以前所处的状态”时在这种方法中,我假设你在使用回溯:一旦特修斯被抓住,你会将堆栈展开到他做出非强迫选择的最后一个位置,然后尝试另一种选择(也就是说,我假设你在使用简单的深度优先搜索状态空间)在这种方法中,从来没有任何理由访问您以前访问过的州

对于你的“强化学习”方法,每次特修斯被抓住时,你都要完全重置迷宫,你需要改变这一点。我想你可以将“从不访问你以前所处的状态”规则改为双管齐下的规则:

  • 千万不要访问迷宫运行期间所处的状态。(这是为了防止无限循环。)
  • 在特修斯被抓到的迷宫中,你所处的状态(这是“学习”部分:如果之前的选择效果不佳,那么应该少做选择)

这里的问题是“从不访问您以前所处的状态”方法和“强化学习”方法之间的差异。当我建议“从不访问您以前所处的状态”时在这种方法中,我假设你在使用回溯:一旦特修斯被抓住,你会将堆栈展开到他做出非强迫选择的最后一个位置,然后尝试另一种选择(也就是说,我假设你在使用简单的深度优先搜索状态空间)在这种方法中,从来没有任何理由访问您以前访问过的州

对于你的“强化学习”方法,每次特修斯被抓住时,你都要完全重置迷宫,你需要改变这一点。我想你可以将“从不访问你以前所处的状态”规则改为双管齐下的规则:

  • 千万不要访问迷宫运行期间所处的状态。(这是为了防止无限循环。)
  • 在特修斯被抓到的迷宫中,你所处的状态(这是“学习”部分:如果之前的选择效果不佳,那么应该少做选择)

为了获得价值,最佳解决此问题的最简单方法是使用,这是一种针对确定性双人游戏(如井字游戏、跳棋、国际象棋)的搜索算法。以下是如何针对您的案例实施此算法的摘要:

  • 创建一个表示游戏当前状态的类,该类 应包括:忒修斯的位置、弥诺陶尔的位置和 轮到谁了。假设你称这个类为
    游戏状态

  • 创建一个启发式函数,将
    游戏状态
    的一个实例作为paraemter,并返回一个double,计算如下:

    • 设Dt为忒修斯离开出口的(平方数)

    • 让Dm为弥诺陶尔与忒修斯之间的曼哈顿距离(方格数)

    • 如果是特修斯的话,让T为1,如果是牛头怪的话,让T为-1

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

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

    • 如果Dt为零,则返回无穷大*T

  • 上面的启发式函数返回Wikipedia在算法伪代码中为给定的
    游戏状态
    (节点)引用为“节点启发式值”的值

    你没有