Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使我的路径查找算法不反向?_Java_Algorithm_Artificial Intelligence_Path Finding - Fatal编程技术网

Java 如何使我的路径查找算法不反向?

Java 如何使我的路径查找算法不反向?,java,algorithm,artificial-intelligence,path-finding,Java,Algorithm,Artificial Intelligence,Path Finding,我的路径查找方法有两个对象,其中包含一个id、名称、x/y坐标和存储在数组列表中的路径。路径数据是它可以直接连接到的每个对象的id。目标是递归调用我的方法,直到它使用最短距离找到目标,当它到达终点时返回true 问题是: 如果到来自的节点的距离比当前节点路径中的其他节点短,则将导致在两个节点之间来回反弹的无限循环。我已经为这个问题挣扎了几个小时,可能是想得太多了。任何意见或建议将不胜感激 算法: while (!pathfound) { current = findPath(curren

我的路径查找方法有两个对象,其中包含一个id、名称、x/y坐标和存储在数组列表中的路径。路径数据是它可以直接连接到的每个对象的id。目标是递归调用我的方法,直到它使用最短距离找到目标,当它到达终点时返回true

问题是: 如果到来自的节点的距离比当前节点路径中的其他节点短,则将导致在两个节点之间来回反弹的无限循环。我已经为这个问题挣扎了几个小时,可能是想得太多了。任何意见或建议将不胜感激

算法:

while (!pathfound) {
    current = findPath(current, end);
}

public static Place findPath(Place curPlace, Place endPlace) {
    ArrayList<Integer> path = curPlace.path;
    int id;
    double lastdist = 999;
    double distance;
    Place bestPlace = null;

    for (int i = 0; i < path.size(); i++) {
        id = curPlace.path.get(i);
        distance = distance(getPlace(id), curPlace)
                + distance(getPlace(id), endPlace);
        if (distance < lastdist) {
            bestPlace = getPlace(id);
        } 

        lastdist = distance;
    }

    if (result.length() == 0) {
        result += bestPlace.name;
    } else {
        result += ", " + bestPlace.name;
    }

    System.out.println("CURCITY: " + bestPlace.id);
    System.out.println(result);
    System.out.println(lastdist);

    if (bestPlace == endPlace) {
        pathfound = true;
    }

    return bestPlace;
}
while(!pathfound){
当前=findPath(当前,结束);
}
公共静态地点查找路径(地点curPlace、地点endPlace){
ArrayList路径=curPlace.path;
int-id;
双lastdist=999;
双倍距离;
Place-bestPlace=null;
对于(int i=0;i

您可以忽略结果,它是为了跟上通过的节点。如果您还想知道其他细节,请询问

如果可以修改
位置
则可以添加布尔“已访问”标志。在运行算法之前,将它们全部重置为false;访问时设置为true,离开时设置为false(不要忘记在退出递归时取消设置它们-如果这样做正确,甚至可以避免在开始之前显式重置标志)。跳过标志为true的节点

更短视的选择是将上次访问的
Place
作为参数传递给函数,并跳过该参数。这不会阻止更大的循环,但可能完全适合您的情况,并且是最简单的实现方法

以上两个都是O(1),开销最小。如果无法修改
Place
,则可以存储访问过的地点的
集(在退出递归时将其从集合中删除),并跳过该集合中已经存在的地点。根据您的性能要求,如果使用
HashSet
,您将需要提供适当的哈希函数


沿着这些路线,以牺牲更多内存为代价,如果您的ID号是唯一的,并且覆盖了一个大小合理的有限范围,则按ID号索引的
布尔[]
是此处设置的恒定时间替代项(它本质上是“已访问”标志选项,标志存储在外部).

使用递归方法进行路径查找算法可能非常棘手,因为您总是需要某种全局信息来评估,两条路径中哪一条更合适。当你沿着一条路走的时候,你永远无法确定它是否正确。即使始终遵循最近的节点,也不一定是正确的路径。这就是所谓的策略,虽然它不是最好的,但可以让它发挥作用,但您必须确保尝试其他路径,因为您无法通过始终坚持最近的节点来实现

如果你想做一个路径查找算法,你需要跟踪所有的节点,这些节点你已经彻底地探索过了,因此永远不需要再次访问。这可以通过将访问的节点列表存储在某种结构中来显式实现,也可以通过选择要访问的新节点的良好策略设计来实现


换句话说,如果您跟踪要访问的节点以及到每个节点的距离(),并且始终确保访问最近的尚未访问的节点,那么您将永远不会再次访问相同的节点,而不必显式地强制执行,例如在中或。

感谢您花时间提供帮助!我可以修改Place,实际上我正在尝试使用一个布尔标志和一个额外的方法来检查是否访问过它。我担心这会引起同样的问题。我一直得到空指针,因为bestPlace被设置在循环中,然后被result使用。可能是我的逻辑不正确,但我不确定如何使用标志来构造代码。@billabrian6我还建议使用访问的
位置的
集合
。@billabrian6您还没有发布完整的递归算法,因此很难给出任何更具体的建议。通常,使用标志方法时,递归函数会首先检查标志,如果标志为false,则将其设置为true,然后在返回之前再次将其设置为false。该标志本质上意味着“堆栈上现在是否有引用此位置的递归函数”。不过,我同意戈文的观点;访问过的地点的
集是健壮而清晰的。@ggovan和Jason C感谢您的输入!在你们两位的建议下,我解决了这个问题。我使用了一个集合,在算法开始时添加了当前位置,然后我循环遍历路径,查看它是否存在于路径中。如果它存在于路径中,我只是将其删除。万分感谢!谢谢你抽出时间来帮助我!