java - 图和 Dijkstra 无限循环?

标签 java graph

所以我创建了一个我的世界插件,我需要一个图表来创建一个导航系统。我研究了一下,发现我应该可以使用 Dijkstra,但我遇到了问题。在搜索最短路径时,我有时会遇到无限循环(并非总是如此,它通常在前 2-3 次运行时有效,但之后进入循环)。

当玩家想要到达目的地时,我会搜索最近的顶点并使用以该顶点作为参数的 computePaths。当我然后运行 ​​getShortestPathTo 时,它有时会陷入无限循环并且我用完了内存(这很有意义,因为我将相同的顶点添加到列表中)。你能看出它为什么会卡住吗?据我所知,Dijkstra 应该能够处理从 A 节点到 B 节点以及从 B 节点到 A 节点,对吗?

下面是我的代码:

public class Dijkstra {
    public static void computePaths(Vertex source) {
    source.minDistance = 0.;
    PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
    vertexQueue.add(source);

    while (!vertexQueue.isEmpty()) {
        Vertex u = vertexQueue.poll();

        // Visit each edge exiting u
        for (Edge e : u.adjacencies) {
            Vertex v = e.target;
            double weight = e.weight;
            double distanceThroughU = u.minDistance + weight;
            if (distanceThroughU < v.minDistance) {
                vertexQueue.remove(v);
                v.minDistance = distanceThroughU;
                v.previous = u;
                vertexQueue.add(v);
            }
        }
    }
}

public static List<Vertex> getShortestPathTo(Vertex target) {
    List<Vertex> path = new ArrayList<Vertex>();
    for (Vertex vertex = target; vertex != null; vertex = vertex.previous) {
        path.add(vertex);
    }
    Collections.reverse(path);
    return path;
}
}

和顶点类:

public class Vertex implements Comparable<Vertex>
{
    public final String name;
    public Edge[] adjacencies;
    public double minDistance = Double.POSITIVE_INFINITY;
    public Vertex previous;
    public Location location;
    public Vertex(String argName) { name = argName; }
    public Vertex(String argName,Location l) { name = argName; location = l;}
    public String toString() { return name; }
    public int compareTo(Vertex other)
    {
        return Double.compare(minDistance, other.minDistance);
    }

}

当第一次启用插件时,我从一个看起来像这样的配置文件加载所有顶点(这是我正在使用的测试文件)

Config file

我在这里添加顶点和边(不确定是否相关但认为可能相关?):

public void loadAllVertex() {
    ConfigurationSection section = nodeConfig.config.getConfigurationSection("nodes");
    for (String key: section.getKeys(false)) {
        String locationString = nodeConfig.getString("nodes." + key + ".location");
        if (locationString == null)
            return;
        String[] locationSplit = locationString.split(",");
        if (locationSplit.length <=1) {
            log.log(Level.SEVERE, "Location is not specified correctly in nodes.yml");
            return;
        }
        Location l = new Location(Bukkit.getWorlds().get(0),Integer.parseInt(locationSplit[0]),Integer.parseInt(locationSplit[1]),Integer.parseInt(locationSplit[2]));
        Vertex tmpVertex = new Vertex(key, l);
        allNodes.add(tmpVertex);

    }

    for (Vertex v : allNodes) {
        String path = "nodes." + v.name + ".connectedTo";
        List<String> connectedTo = nodeConfig.getStringList(path,true);
        List<Edge> edges = new ArrayList<>();

        for (String sideNodeName : connectedTo) {
            Vertex vertexCon = GraphUtils.getVertexByName(allNodes, sideNodeName);
            if (vertexCon == null) {
                log.warning("The '" + sideNodeName + "' node is not defined");
                return;
            }
            //A.adjacencies = new Edge[]{ new Edge(M, 8) };
            edges.add(new Edge(vertexCon,vertexCon.location.distance(v.location)));
        }
        Edge[] arrayEdges = new Edge[edges.size()];
        arrayEdges = edges.toArray(arrayEdges);
        v.adjacencies = arrayEdges;
    }

}

最佳答案

我想我发现了错误,所以我第一次运行计算路径和查找最短路径时从未遇到过任何循环,所以我最终发现我无法正确重置事物(我知道应该很明显)-我没有之后更新顶点。所以我添加了一个方法来重置 mindistance 和以前的属性,这似乎已经成功了。

关于java - 图和 Dijkstra 无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45413720/

相关文章:

java - Orika vs JMapper - 它是如何工作的以及速度差异 - 为什么?

java - Spring Security 自定义身份验证提供程序 403 响应

java - JacksonDB 相当于 db.collection.find({}, {"fieldName":1})?

algorithm - 计算图中的唯一对(不允许重复顶点)

algorithm - 涉及任意两个节点的三角形数

java - 当 DB 有这样的约束时,为什么要使用 JPA/Hibernate 约束注释

java - Kafka Consumer 无法为 JsonDeserializer 消费 905 字节的消息

algorithm - 中国 postman 问题的变体

graph - 在 Neo4J 中找到具有重复方向关系模式的 N 个级别的路径

c# - 径向 TreeMap 布局 : fix beizer curves