如何防止我的路径查找算法倒退?

我的路径查找方法接收两个包含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;}

你可以忽略result,它是用来跟踪经过的节点的。如果你需要了解其他细节,请问我。


回答:

如果可以修改Place,你可以添加一个布尔类型的“已访问”标志。在运行算法之前将所有标志重置为false;访问时设置为true,离开时设置为false(别忘了在递归退出时取消设置它们 – 如果你正确地这样做,你甚至可以避免在开始前显式重置标志)。跳过标志为true的节点。

一个更短视的选项是将最后访问的Place作为参数传递给函数,并跳过那个节点。这不会防止更大的循环,但可能完全适合你的情况,并且是最简单的实现方式。

以上两种方法都是O(1)且开销最小。如果你不能修改Place,你可以存储一个已访问地点的Set(在递归退出时从集合中移除它们),并跳过已经在该集合中的地点。根据你的性能要求,如果你使用HashSet,你将需要想出一个合适的哈希函数。

沿着这个思路,如果你的ID号是唯一的并且覆盖一个合理大小的有限范围,以ID号为索引的boolean[]在这里是集合的一个常数时间的替代方案(它本质上是“已访问”标志选项,但标志存储在外部)。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注