【问题标题】:Dijkstra Algorithm how to make it work directedDijkstra算法如何使其工作定向
【发布时间】:2020-12-26 14:18:16
【问题描述】:

我正在使用下面的方法来实现寻找最短路径的算法。

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DijkstraAlgorithm {

        private final List<Node> nodes;
        private final List<Edge> edges;
        private Set<Node> settledNodes;
        private Set<Node> unSettledNodes;
        private Map<Node, Node> predecessors;
        private Map<Node, Integer> distance;

        public DijkstraAlgorithm(Graph graph) {
            // create a copy of the array so that we can operate on this array
            this.nodes = new ArrayList<Node>(graph.getNodelIst());
            this.edges = new ArrayList<Edge>(graph.getEdgeList());
        }

        public void execute(Node source) {
            settledNodes = new HashSet<Node>();
            unSettledNodes = new HashSet<Node>();
            distance = new HashMap<Node, Integer>();
            predecessors = new HashMap<Node, Node>();
            distance.put(source, 0);
            unSettledNodes.add(source);
            while (unSettledNodes.size() > 0) {
                Node node = getMinimum(unSettledNodes);
                settledNodes.add(node);
                unSettledNodes.remove(node);
                findMinimalDistances(node);
            }
        }

        private void findMinimalDistances(Node node) {
            List<Node> adjacentNodes = getNeighbors(node);
            for (Node target : adjacentNodes) {
                if (getShortestDistance(target) > getShortestDistance(node)
                        + getDistance(node, target)) {
                    distance.put(target, getShortestDistance(node)
                            + getDistance(node, target));
                    predecessors.put(target, node);
                    unSettledNodes.add(target);
                }
            }

        }

        private int getDistance(Node node, Node target) {
            for (Edge edge : edges) {
                if (edge.getSourceNode().equals(node)
                        && edge.getEndNode().equals(target)) {
                    return edge.getWeight();
                }
            }
            throw new RuntimeException("Should not happen");
        }

        private List<Node> getNeighbors(Node node) {
            List<Node> neighbors = new ArrayList<Node>();
            for (Edge edge : edges) {
                if (edge.getSourceNode().equals(node)
                        && !isSettled(edge.getEndNode())) {
                    neighbors.add(edge.getEndNode());
                }
            }
            return neighbors;
        }

        private Node getMinimum(Set<Node> vertexes) {
            Node minimum = null;
            for (Node vertex : vertexes) {
                if (minimum == null) {
                    minimum = vertex;
                } else {
                    if (getShortestDistance(vertex) < getShortestDistance(minimum)) {
                        minimum = vertex;
                    }
                }
            }
            return minimum;
        }

        private boolean isSettled(Node vertex) {
            return settledNodes.contains(vertex);
        }

        private int getShortestDistance(Node destination) {
            Integer d = distance.get(destination);
            if (d == null) {
                return Integer.MAX_VALUE;
            } else {
                return d;
            }
        }

    /*
     * This method returns the path from the source to the selected target and
     * NULL if no path exists
     */
    public LinkedList<Node> getPath(Node target) {
        LinkedList<Node> path = new LinkedList<Node>();
        Node step = target;
        // check if a path exists
        if (predecessors.get(step) == null) {
            return null;
        }
        path.add(step);
        while (predecessors.get(step) != null) {
            step = predecessors.get(step);
            path.add(step);
        }
        // Put it into the correct order
        Collections.reverse(path);
        return path;
    }


    }

这很好用,但是我现在希望向我的边缘添加一个方向并运行相同的定向方法,以返回一个定向的 PathList。例如,我将为双向传递 11,为 --> 传递 01,为

有人可以帮忙吗?

【问题讨论】:

  • 你能解释一下你所说的导演是什么意思吗?
  • @AliHassan 对不起,我的意思是我需要在边缘添加一个方向属性,所以它们可以是双向的,也可以是一个方向。即,如果我们进行路径规划,并且一个边缘可能是自动扶梯,那么它只能用于一个方向。谢谢。
  • 您能展示一下您是如何打造自己的优势的吗?你的算法似乎已经有了一个边有源节点和结束节点的概念。
  • @RogerLindsjö 我的边有一个属性,即 Nodeids: [sourceID, DestinationID] 所以我们确实知道方向,然后我如何让算法遵守这些规则?例如我有一个边缘自动扶梯node1--node2。当我有一个双向边缘时,方向由方向表示:11。所以我们是否认为我需要复制双向边缘,所以我有节点 3--node4 和 node4--node3,并且两者都在我的边数组列表中.在定向的那些我离开它们并在需要时在运行时交换源和目标,然后我将它们放入算法的数组列表中?

标签: java android graph-theory dijkstra


【解决方案1】:

我认为最简单的方法是保持定向边缘不变,如果连接是双向的,则创建两条边缘。

释义 NodeAID,NodeBID,01给edges.add(new Edge(NodeAID, NodeBID))

NodeAID,NodeBID,10 给出edges.add(new Edge(NodeBID, NodeAID))

和NodeAID,NodeBID,11给出

edges.add(new Edge(NodeAID, NodeBID));    
edges.add(new Edge(NodeBID, NodeAID));

您可以创建一个同时处理单向和双向的 Edge 接口,但我认为这会使边缘在不同方向上开始有不同的信仰变得更加复杂。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 2020-08-09
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    相关资源
    最近更新 更多