- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前,仅打印最终顶点,最小距离似乎为无穷大。我似乎找不到问题所在,因为顶点没有添加到“最短路径”ArrayList 中。我还想打印出该路径所采用的所有边缘。非常欢迎任何建议以下是我的完整代码,谢谢!
编辑:我已按照短跑运动员的建议编辑了我的类(class)。
我的 Graph 类的 getNeighbours() 方法中存在错误。有关源的信息被添加为邻居,即使我试图获取它的邻居。
我也不确定如何打印边缘信息以及顶点信息。
非常感谢任何建议!
最短路径查找器
class ShortestPathFinder {
private Graph graph = new Graph();
private Vertex source = new Vertex(0, null);
private Vertex destination = new Vertex(0,null);
private Map<Vertex,Double> minimumWeightToVertices = new HashMap();
private Map<Vertex,Vertex> previousVertex = new HashMap();
private Set<Vertex> visited = new HashSet();
private Map<Vertex,Double> neighbors = new HashMap();
public Optional<Path> findShortestPath(Graph graph, Vertex source, Vertex destination) {
this.graph = graph;
this.source = graph.getVertex(source);
this.destination = graph.getVertex(destination);
Optional<Path> pathFound = Optional.empty();
//start queue at source vertex
source.setDistance(0);
PriorityQueue<Vertex> priorityQueue = new PriorityQueue<>();
priorityQueue.add(source);
source.setVisited(true);
while( !priorityQueue.isEmpty() ){
// Getting the minimum distance vertex from priority queue
Vertex actualVertex = priorityQueue.poll();
//get Neighbors of source vertex
neighbors = graph.getNeighbours(source);
//find Neighbor with lowest weight
for(Entry<Vertex, Double> neighbor : neighbors.entrySet()){
Vertex v = neighbor.getKey();
if(v == destination) {
minimumWeightToVertices.put(v,v.getDistance());
v.setPredecessor(actualVertex);
previousVertex.put(actualVertex,v);
priorityQueue.add(v);
// found, set pathFound = Optional.of(path)
Path path = new Path();
pathFound = Optional.of(path);
}
else if(visited.contains(v) == false)
{
double newDistance = actualVertex.getDistance() + neighbor.getValue();
//when found min add to minmumWeightToVertices
if( newDistance < v.getDistance() ){
priorityQueue.remove(v);
v.setDistance(newDistance);
minimumWeightToVertices.put(v,newDistance);
v.setPredecessor(actualVertex);
previousVertex.put(actualVertex,v);
priorityQueue.add(v);
System.out.println("Added: " + v.getID());
}
}
}
//When visited add to visited so not visited again
actualVertex.setVisited(true);
visited.add(actualVertex);
//continue getting neighbors with lowest index until destination reached
}
return pathFound;
}
public void getPath() {
//print all info using previous Vertex and print out edge info from it
for (Entry<Vertex, Vertex> entry : previousVertex.entrySet()) {
System.out.println("ID: " + entry.getKey().getID() + " Name: " + entry.getKey().getName() +
" to " + "ID: " + entry.getValue().getID() + " Name: " + entry.getValue().getName());
}
}
}
图表
class Graph {
private final Set<Vertex> vertices = new HashSet<Vertex>();
private final Set<Edge> edges = new HashSet<Edge>();
public void addVertex(int id, String name) {
Vertex vertex = new Vertex(id,name);
vertices.add(vertex);
//System.out.println("ID:" + vertex.getID() + "Name:" + vertex.getName());
}
public void addEdge(double weight, Vertex vertex1, Vertex vertex2, String extra) {
Edge edge = new Edge(weight,vertex1,vertex2,extra);
edges.add(edge);
}
public void printVertices() {
for(Vertex vertex : vertices){
System.out.println("ID:" + vertex.getID() + " Name:" + vertex.getName());
}
}
public void printEdges() {
for(Edge edge : edges){
System.out.println("StartVertex:" + edge.getStartVertex() +" EndVertex:" + edge.getTargetVertex()+ "Weight:" + edge.getWeight());
}
}
public Vertex getVertex(Vertex v) {
return v;
}
public Map<Vertex, Double> getNeighbours(Vertex vertex) {
Map<Vertex,Double> neighbors = new HashMap();
Object[] check = edges.toArray();
for(int i = 0; i < edges.size(); i++) {
if(((Edge) check[i]).getStartVertex().getID() == vertex.getID()) {
neighbors.put(((Edge) check[i]).getTargetVertex(),((Edge) check[i]).getWeight());
}
else if(((Edge) check[i]).getTargetVertex().getID() == vertex.getID()) {
neighbors.put(((Edge) check[i]).getStartVertex(),((Edge) check[i]).getWeight());
}
}
return neighbors;
}
}
边缘
public class Edge {
private double weight;
private Vertex startVertex;
private Vertex targetVertex;
private String extra;
public Edge(double weight, Vertex startVertex, Vertex targetVertex, String extra) {
this.weight = weight;
this.startVertex = startVertex;
this.targetVertex = targetVertex;
this.extra = extra;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public Vertex getStartVertex() {
return startVertex;
}
public void setStartVertex (Vertex startVertex) {
this.startVertex = startVertex;
}
public Vertex getTargetVertex() {
return targetVertex;
}
public void setTargetVertex(Vertex targetVertex) {
this.targetVertex = targetVertex;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
}
顶点
public class Vertex implements Comparable<Vertex> {
private int ID;
private String name;
private List<Edge> adjacenciesList;
private boolean visited;
private Vertex predecessor;
private double distance = Double.MAX_VALUE;
public Vertex(int ID, String name) { //(Int ID, String name)?
this.ID = ID;
this.name = name;
this.adjacenciesList = new ArrayList<>();
}
public void addNeighbour(Edge edge) {
this.adjacenciesList.add(edge);
}
public String getName() {
return name;
}
public void setID(int ID) {
this.ID = ID;
}
public int getID() {
return ID;
}
public void setName(String name) {
this.name = name;
}
public List<Edge> getAdjacenciesList() {
return adjacenciesList;
}
public void setAdjacenciesList(List<Edge> adjacenciesList) {
this.adjacenciesList = adjacenciesList;
}
public boolean isVisited() {
return visited;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public Vertex getPredecessor() {
return predecessor;
}
public void setPredecessor(Vertex predecessor) {
this.predecessor = predecessor;
}
public double getDistance() {
return distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
@Override
public String toString() {
return this.name;
}
@Override
public int compareTo(Vertex otherVertex) {
return Double.compare(this.distance, otherVertex.getDistance());
}
}
主要
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
ReadInput graphReader = new ReadInput();
Graph graph = graphReader.readFromStream();
Vertex source = graphReader.calculatesSource();
Vertex destination = graphReader.calcualteDestination();
//graph.printEdges();
//graph.printVertices();
ShortestPathFinder finder = new ShortestPathFinder();
Optional<Path> possiblePath = finder.findShortestPath(graph,source,destination);
if(possiblePath.isPresent() == false) {
System.out.println("No path found");
}
else {
System.out.println("Shortest path:");
finder.getPath();
}
}
}
ReadInputIn
public class ReadInput {
Vertex[] vertex = new Vertex[25252];
final String DELIMITER = ",";
int indexVertex = 0;
//public Vertex[] readVertices() throws NumberFormatException, IOException {
public Graph readFromStream() throws NumberFormatException, IOException {
Graph graph = new Graph();
//25252 number of elements in Place.txt file
//Delimiter used in CSV file
String line = "";
//Create the file reader
BufferedReader fileReader = new BufferedReader(new FileReader("Place.txt"));
String IDString = null;
String name = null;
int ID = 0;
//Read the file line by line
while ((line = fileReader.readLine()) != null)
{
//Get all tokens available in line
String[] tokens = line.split(DELIMITER);
//for(String token : tokens)
//{
IDString = tokens[0];
name = tokens[1];
ID = Integer.parseInt(IDString);
//}
vertex[indexVertex] = new Vertex(ID,name);
graph.addVertex(ID,name);
//System.out.println(indexVertex +":" + vertex[indexVertex].getID());
indexVertex++;
}
fileReader.close();
//return vertex;
//}
//public Edge[] readEdges() throws NumberFormatException, IOException {
Edge[] edge = new Edge[127807];
int indexEdge = 0;
String line2 = "";
BufferedReader fileReader2 = new BufferedReader(new FileReader("Road.txt"));
String valueString = null;
String vertex1IDName = null;
String vertex2IDName = null;
String extra = null;
float value = 0;
int vertex1ID = 0;
int vertex2ID = 0;
//Read the file line by line
while ((line2 = fileReader2.readLine()) != null)
{
//Get all tokens available in line
String[] tokens2 = line2.split(DELIMITER);
//for(String token1 : tokens2)
//{
vertex1IDName = tokens2[0];
vertex2IDName = tokens2[1];
valueString = tokens2[2];
if(tokens2.length - 1 == 3) {
extra = tokens2[tokens2.length - 1];
}
else {
extra = "";
}
vertex1ID = Integer.parseInt(vertex1IDName);
vertex2ID = Integer.parseInt(vertex2IDName);
value = Float.parseFloat(valueString);
//graph.addEdge(value, vertex1ID, vertex2ID, extra);
//}
//System.out.println("value: "+ value + " vertex1ID:"+ vertex1ID +" vertex2ID:"+ vertex2ID+ " extra:" + extra);
//if vertex 1 name or vertex 2 name in vertex.getID()
for(int i = 0; i< indexVertex; i++) {
if(vertex1ID == vertex[i].getID() || vertex2ID == vertex[i].getID()){
for(int j = 0; j< indexVertex; j++) {
if(vertex2ID == vertex[j].getID() || vertex1ID == vertex[j].getID()) {
//vertex[i].addNeighbour(edge[indexEdge] = new Edge(value,vertex[i],vertex[j],extra));
graph.addEdge(value, vertex[i], vertex[j], extra); //newline for constructing graph
//System.out.println("Edge added: "+ vertex1ID +" = " + vertex[i].getID() + " "+ vertex2ID + " = " + vertex[j].getID());
indexEdge++;
}
}
}
}
}
fileReader2.close();
return graph;
//return edge;
}
public Vertex calcualteDestination() {
Scanner scanUserInput = new Scanner(System.in);
System.out.println("Enter the Destination Name:");
String destinationName = scanUserInput.nextLine();
scanUserInput.close();
Vertex Destination = new Vertex(0,null);
for(int i = 0; i<indexVertex; i++) {
if(destinationName.equals(vertex[i].getName())){
Destination.setID(vertex[i].getID());
Destination.setName(vertex[i].getName());
}
}
return Destination;
}
public Vertex calculatesSource() {
Scanner scanUserInput = new Scanner(System.in);
System.out.println("Enter the Source Name:");
String sourceName = scanUserInput.nextLine();
Vertex Source = new Vertex(0, null);
for(int i = 0; i<indexVertex; i++) {
if(sourceName.equals(vertex[i].getName())){
Source.setID(vertex[i].getID());
Source.setName(vertex[i].getName());
}
}
return Source;
}
}
最佳答案
我对您如何考虑重组代码以使其更易于调试有一些建议:
Graph
类,它保存所有顶点和边集,并仅公开用于查询图的方法。您应该能够在输入后独立测试图形是否按预期设置,而无需测试最短路径算法ShortestPath
类中 - 无需在类外部公开该信息。您应该能够独立于代码进行单元测试来读取图表main
方法中的大部分逻辑应该位于单独的类中,例如 GraphReader
- 这些应该是可单元测试的我建议您进行这些更改 - 我相信以这种方式重组代码将使问题更加明显。
<小时/>这是一个可能的设计,可以让您对我所说的内容有一些想法。
class Vertex {
private final int id;
private final String name;
}
class Edge {
private final Vertex vertex1;
private final Vertex vertex2;
private final double weight;
}
class Graph {
private final Set<Vertex> vertices;
private final Set<Edge> edges;
public void addVertex(int id, String name) {...}
public void addEdge(int vertex1, int vertex2, double weight) {...}
public Vertex getVertex(int id) {...}
public Map<Vertex,Double> getNeighbours(Vertex vertex) {...}
}
class GraphReader {
public Graph readFromStream(InputStream input) {...}
}
class Path {
private final List<Vertex> steps;
}
这意味着您可以将构建最短路径时需要保存的临时信息封装到单独的类中:顶点和边不需要保存该信息。
class ShortestPathFinder {
private final Graph graph;
private final Vertex start;
private final Vertex end;
private final Map<Vertex,Double> minimumWeightToVertices;
private final Map<Vertex,Vertex> previousVertex;
private final Set<Vertex> visited;
public ShortestPathFinder(Graph graph, int start, int end) {
this.graph = graph;
this.start = graph.getVertex(start);
this.end = graph.getVertex(end);
...
}
public boolean hasPath() {...}
public Path getPath() {...}
}
public static void main(String[] args) {
GraphReader graphReader = new Graph();
Graph graph = graphReader.readFromStream(System.in);
ShortestPathFinder finder = new ShortestPathFinder(graph, 1, 10);
if (finder.hasPath())
System.out.println("Shortest path " + finder.getPath());
}
关于java - 如何用Java打印Dijkstra算法的完整路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60067608/
谁能告诉我这个 Dijkstra 算法中优先级队列的空间复杂度。请注意,这里可以将一个顶点添加到队列中不止一次。但是,由于访问集,它不会被处理超过一次。这就是为什么我想知道队列的最大大小可以达到的原因
为什么我们不能将 Dijkstra 算法应用于具有负权重的图? 最佳答案 如果每次从 C 到 D 旅行都得到报酬,那么找到从 A 到 B 的最便宜的路径意味着什么? 如果两个节点之间存在负权重,则“最
我正在阅读 工作中的程序员 . 我在 Donald Knuth 的采访中看到了这一段。 Seibel: It seems a lot of the people I’ve talked to had
我一整天都在努力理解 Dijkstra 算法并实现,但没有取得任何重大成果。我有一个城市及其距离的矩阵。我想做的是给定一个起点和一个终点,找到城市之间的最短路径。 示例: __0__ __1
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
一 问题描述 小明为位置1,求他到其他各顶点的距离。 二 实现 package graph.dijkstra; import java.util.Scanner; import java.util.
一 问题背景 在现实生活中,很多问题都可以转化为图来解决问题。例如,计算地图中两点之间的最短距离、网络最小成本布线,以及工程进度控制,等等。这些问题都涉及最小路径的求解。 二 Dijkstra 算法
谁能告诉我这个程序的错误在哪里,这真的很有帮助,我尽力解决了这个问题,这段代码只通过了两个测试用例给定一个无向图和一个起始节点,确定从起始节点到图中所有其他节点的最短路径的长度。如果一个节点不可到达,
除了 Dijkstra 之外,还有其他方法可以计算接近完整图的最短路径吗?我有大约 8,000 个节点和大约 1800 万条边。我已经完成了线程 "a to b on map"并决定使用 Dijkst
我知道 Dijkstra 的算法、Floyd-Warshall 算法和 Bellman-Ford 算法,用于查找图中 2 个顶点之间的最便宜路径。 但是当所有边的成本都相同时,最便宜的路径是边数最少的
我的问题如下:根据不同的消息来源,Dijkstra 算法只不过是 Uniform Cost Search 的一种变体。我们知道 Dijkstra 的算法会找到源和所有目的地(单源)之间的最短路径。但是
所以我的问题是我有一个带有 的有向图 G非负 边长度,我希望找到两个节点 u 和 v 之间的最短路径,以便它们只通过图中的一个标记节点。 如果我们没有涉及标记节点的条件,这个问题可以使用 Dijkst
对于使用最小堆优先级队列的 Dijkstra 实现,我将其设置为查找网络上不存在的站,以便它必须检查所有内容。我的问题是由于整体时间复杂度 O(V + E log V) ,为什么网络查找到一个站点的最
我试图找出是否可以使用 Dijkstra 算法来找到有向无环路径中的最长路径。我知道由于负成本循环,不可能在一般图中找到 Dijkstra 的最长路径。但我认为它应该在 DAG 中工作。通过谷歌我发现
我正在研究 Dijkstra 算法,我真的需要找到所有可能的最短路径,而不仅仅是一条。我正在使用邻接矩阵并应用 Dijkstra 算法,我可以找到最短路径。但是我需要以最低成本找到所有路径,我的意思是
我正在尝试创建 Dijkstra 寻路的实现,除了我要求它创建一条在同一位置开始和结束的路线之外,它似乎工作得很好。 JSFiddle:http://jsfiddle.net/Lt6b4ecr/ 我需
我们可以使用负权重的 Dijkstra 算法吗? 停止! 在您认为“大声笑,您可以在两点之间无休止地跳跃并获得无限便宜的路径”之前,我更多地考虑的是单向路径。 对此的应用程序将是一个带有点的山地地形。
我认为 Dijkstra 算法是确定的,因此,如果您选择相同的起始顶点,您将得到相同的结果(到每个其他顶点的距离相同)。但我不认为它是确定性的(它为每个操作定义了以下操作),因为这意味着它不必首先搜索
我找到了this code使用 Dijkstra 算法来查找加权图中两个节点之间的最短路径。我看到的是代码没有跟踪访问过的节点。但是它对于我尝试过的所有输入都适用。我添加了一行代码来跟踪访问过的节点。
我将 Dijkstra 算法 的 C++ 实现转换为 Java。当我运行 Java 代码时,我没有得到预期的输出 我的 C++ 代码的预期: Minimum distance for source v
我是一名优秀的程序员,十分优秀!