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

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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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