Java 非标准迷宫中的最优路径搜索技术

Java 非标准迷宫中的最优路径搜索技术,java,optimization,path-finding,maze,Java,Optimization,Path Finding,Maze,所以,我的问题是,我目前正在研究一种在开放世界中使用各种大小瓷砖的路径查找技术。对象需要在无限世界(它动态生成)中找到到达目的地的最佳路径,其中填充了各种大小的瓷砖(它们不位于设置的网格上-它们可以有任何位置和大小-并且两者都不必是整数)。(对象可以通过和ArrayList访问所有分幅的数据)。现在,一些因素使这个问题变得更加困难: 对象本身有一个大小,不能在平铺中移动。因此,存在的路径可能太窄,对象无法通过 目标目的地本身可以是移动对象 有可能同时有几十个这样的对象——因此,算法必须在系统上

所以,我的问题是,我目前正在研究一种在开放世界中使用各种大小瓷砖的路径查找技术。对象需要在无限世界(它动态生成)中找到到达目的地的最佳路径,其中填充了各种大小的瓷砖(它们不位于设置的网格上-它们可以有任何位置和大小-并且两者都不必是整数)。(对象可以通过和ArrayList访问所有分幅的数据)。现在,一些因素使这个问题变得更加困难:

  • 对象本身有一个大小,不能在平铺中移动。因此,存在的路径可能太窄,对象无法通过
  • 目标目的地本身可以是移动对象
  • 有可能同时有几十个这样的对象——因此,算法必须在系统上保持清晰,或者在程序的几个单独的记号中计算路径
我尝试实现迷宫解决技术的解决方案,但主要问题是在大多数迷宫中,瓷砖只能有非常特定的坐标(如整数),并且总是相同的大小

我还尝试将场景渲染为一个巨大的传统迷宫,其中的瓷砖实际上是瓷砖的像素(因此,如果我有一个20x40瓷砖,它将变成一个由1x1瓷砖组成的20x40块),但遇到了性能问题,仍然没有解决问题,因为路径可能会变窄,以便对象能够通过

编辑:

非常抱歉,我之前的措辞很糟糕,当我试图在没有完全理解问题的情况下匆忙找到解决方案时,就会发生这种情况。所以我现在使用的算法是让NPC的敌人在障碍物周围找到他们的路径。以下是一个场景示例:

带箭头的黑色圆圈是玩家,黑色灌木状斑点是NPC的敌人。这是我目前用于敌人AI的算法:

void move() { //part of the Enemy class, this function is called once each tick for every enemy
  PVector velocity = new PVector(speed*game.dt, 0); //speed is a pre-set float denoting the enemy's speed, game.dt is deltatim
  velocity.rotate(atan2(game.player.location.y-location.y, game.player.location.x-location.x)); //game.player.location is a PVector of the player's position, location is a PVector of this enemy's position

  boolean init_collision = getTileCollision(); //getTileCollision is a boolean of whether this enemy is colliding with any tile
  location.add(velocity);
  boolean collision = getTileCollision();
  if (!init_collision && collision) { //if the enemy happens to spawn inside a tile, let is move out of it before checking for collision
    location.sub(velocity);

    if (desired_heading != -1) { //desired heading is the angle, in radians, of which 90-degree angle the enemy wants to move in, by default set to -1 (see my descrition of this algorithm below)
      velocity = new PVector(speed*game.dt, 0);
      velocity.rotate(desired_heading);
      location.add(velocity);
      if (getTileCollision()) {
        location.sub(velocity);
        velocity = new PVector(speed*game.dt, 0);
        velocity.rotate(current_heading); //current heading the an angle, in radians, of which 90-degree angle the enemy is currently moving in. set to -1 by default but can not equal -1 if desired_heading is not -1
        location.add(velocity);
        if (getTileCollision()) {
          location.sub(velocity);
          desired_heading = -1;
          current_heading = -1;
        }
      } else {
        desired_heading = -1;
        current_heading = -1;
      }
    } else {
      float original_heading = velocity.heading();
      desired_heading = radians(round(degrees(velocity.heading())/90.0)*90.0); //round to the nearest 90 degrees
      velocity = new PVector(speed*game.dt, 0);
      velocity.rotate(desired_heading);
      location.add(velocity);
      if (getTileCollision()) {
        location.sub(velocity);
      }
      float turn = radians(90);
      while (true) { //if it cant move, try rotating 90 degrees and moving
        velocity.rotate(turn);
        location.add(velocity);
        if (!getTileCollision() && abs(round(degrees(current_heading)) - round(degrees(velocity.heading()))) != 180) {
          current_heading = velocity.heading();
          break;
        } else {
          location.sub(velocity);
        }
      }
    }
  } else {
    desired_heading = -1;
    current_heading = -1;
  }
}
因此,我的可怕代码希望实现的是,敌人首先试图直接向玩家移动。如果遇到障碍物,它会将角度调到最近的90度,将所需的_航向设置为该角度,然后尝试通过。如果不能,它将再旋转90度,以此类推,始终记住原始圆角

这在远程操作中不起作用,首先,旋转90度有50%的机会进入完全错误的方向,所以我尝试添加

if (abs(original_heading - velocity.heading()+turn) < abs(original_heading - velocity.heading()-turn)) {
    turn = radians(-90);
}
if(abs(原航向-速度.航向()+转弯)
就在
while(true)
之前,但这完全破坏了算法(有时敌人会陷入深思熟虑,不再移动)

我做错了什么?我应该尝试另一种算法,还是这个算法有潜力


我希望这是一个更好的问题……

也许你可以朝着目的地走,如果你的物体撞到了什么东西,让它绕过障碍物(总是朝着同一个方向,也许先挑一个最好的,记住最初的目的地是什么)。所以你需要一个碰撞检测和一些算法。绕过障碍物。但由于世界是生成的,您的最佳路径始终是“局部路径”,因此不可能将其作为副本关闭,因为您不清楚自己的要求/范围太广,因为您基本上只是提供了一份详细的需求清单和关于您尝试过的内容的非常模糊的细节。@RC。我试着做类似的事情,但问题是首先要选择绕过障碍的方向。另外,另一个障碍可能会阻碍你绕过第一个障碍。。。尽管我必须说,这个解决方案比那些尝试过的要好得多。非常感谢。我觉得你的问题很有趣,但你真的应该添加一些细节,可能是一个迷宫截图,可能是一些代码,可能两者都有。你知道吗?这是为了图表,但我不认为它很难适应你的迷宫。它的复杂性几乎与大小成线性关系,所以我不认为对瓷砖进行像素化会造成问题。我希望现在情况会好得多,它很快就会重新开放。你是在寻找一条(接近)最优路径还是一些定向漫游就足够了(我想你的算法很容易陷入畜栏)?++我猜,您在
getTileCollision()
上花费的时间最多,这很可能是可以优化的(预计算、四叉树或其他)。