簡體   English   中英

圖和Dijkstra無限循環?

[英]Graph and Dijkstra infinite loop?

所以我創建了一個Minecraft插件,我需要一個圖形來創建導航系統。 我研究了一下,發現我應該可以使用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);
    }

}

當第一個插件啟用時,我從配置文件加載所有頂點看起來像這樣(這是我正在使用的測試)

配置文件

我在這里添加頂點和邊緣(不確定是否相關,但認為它可能是?):

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;
    }

}

我覺得我發現了錯誤,所以我第一次運行計算路徑和findshortestpath時從來沒有任何循環,所以我終於弄清楚我無法正確地重置東西(應該很明顯我知道) - 我沒有更新之后的頂點。 所以我添加了一個方法來重置思維和以前的屬性,這似乎已經成功了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM