【发布时间】:2018-03-08 04:16:44
【问题描述】:
我想使用Dijkstra shortest path algorithm的Vogella Dijkstra算法生成最短路径并画出路径。
Android Studio 没有给出任何语法错误,但是当我启动我的应用程序时,它显示“不幸的是,DijkstraAlgorithmTest 已停止”
我会将所有代码以及 Logcat 发布在下面:
MainActivity.java
package com.example.lyeji.dijkstraalgorithmtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Vertex> nodes;
private List<Edge> edges;
private static String tempPath ="";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nodes = new ArrayList<Vertex>();
edges = new ArrayList<Edge>();
for (int i = 0; i < 11; i++) {
Vertex location = new Vertex("Node_" + i, "" + i);
nodes.add(location);
}
addLane("Edge_0", 0, 1, 85);
addLane("Edge_1", 0, 2, 217);
addLane("Edge_2", 0, 4, 173);
addLane("Edge_3", 2, 6, 186);
addLane("Edge_4", 2, 7, 103);
addLane("Edge_5", 3, 7, 183);
addLane("Edge_6", 5, 8, 250);
addLane("Edge_7", 8, 9, 84);
addLane("Edge_8", 7, 9, 167);
addLane("Edge_9", 4, 9, 502);
addLane("Edge_10", 9, 10, 40);
addLane("Edge_11", 1, 10, 600);
// Lets check from location Loc_1 to Loc_10
Graph graph = new Graph(nodes, edges);
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(graph);
dijkstra.execute(nodes.get(0));
LinkedList<Vertex> path = dijkstra.getPath(nodes.get(10));
//assertNotNull(path);
//assertTrue(path.size() > 0);
String temp = "";
for (Vertex vertex : path)
{
temp += vertex + " ";
}
if (temp !=null && temp.length()>0 && temp.charAt(temp.length()-1) == 'x')
{
temp = temp.substring(0,temp.length()-1);
}
temp = removeLastChar(temp);
tempPath = temp;
}
private void addLane(String laneId, int sourceLocNo, int destLocNo,
int duration) {
Edge lane = new Edge(laneId,nodes.get(sourceLocNo), nodes.get(destLocNo), duration );
edges.add(lane);
}
private static String removeLastChar(String str)
{
return str.substring(0, str.length()-1);
}
public static String getPath()
{
return tempPath;
}
}
Navigation.java
package com.example.lyeji.dijkstraalgorithmtest;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* Created by lyeji on 08-Mar-18.
*/
public class Navigation extends View {
Paint paint;
static Path path , path2;
static String temp = MainActivity.getPath();
int [] pathTaken;
float[] xcoor = {260,260,115,260,40,260,230,440,440,630,730,730,730,730,490};
float[] ycoor = {1035,860,860,715,715,585,400,585,345,585,585,685,940,1035,1035};
public Navigation (Context context){
super(context);
initialrun();
init();
}
public Navigation (Context context, AttributeSet attrs){
super(context,attrs);
initialrun();
init();
}
public void initialrun(){
String items = "";
String[] tempPath ;
items = temp.replaceAll(" ", ",");
tempPath = items.split(",");
pathTaken = new int[tempPath.length];
for (int i = 0; i < tempPath.length; i++) {
pathTaken[i] = Integer.parseInt(tempPath[i]);
}
for (int i = 0; i < tempPath.length; i++) {
tempPath[i] = null;
}
}
public Navigation (Context context, AttributeSet attrs,int defStyle){
super(context,attrs,defStyle);
initialrun();
init();
}
private void init(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
path = new Path();
path2 = new Path();
path.moveTo(xcoor[pathTaken[0]],ycoor[pathTaken[0]]);
for(int i=1;i<pathTaken.length;i++){
float a = xcoor[pathTaken[i]];
float b = ycoor[pathTaken[i]];
path.lineTo(a,b);
}
}
}
DijkstraAlgorithm.java
package com.example.lyeji.dijkstraalgorithmtest;
/**
* Created by lyeji on 04-Mar-18.
*/
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<Vertex> nodes;
private final List<Edge> edges;
private Set<Vertex> settledNodes;
private Set<Vertex> unSettledNodes;
private Map<Vertex, Vertex> predecessors;
private Map<Vertex, Integer> distance;
public DijkstraAlgorithm(Graph graph) {
// create a copy of the array so that we can operate on this array
this.nodes = new ArrayList<Vertex>(graph.getVertexes());
this.edges = new ArrayList<Edge>(graph.getEdges());
}
public void execute(Vertex source) {
settledNodes = new HashSet<Vertex>();
unSettledNodes = new HashSet<Vertex>();
distance = new HashMap<Vertex, Integer>();
predecessors = new HashMap<Vertex, Vertex>();
distance.put(source, 0);
unSettledNodes.add(source);
while (unSettledNodes.size() > 0) {
Vertex node = getMinimum(unSettledNodes);
settledNodes.add(node);
unSettledNodes.remove(node);
findMinimalDistances(node);
}
}
private void findMinimalDistances(Vertex node) {
List<Vertex> adjacentNodes = getNeighbors(node);
for (Vertex 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(Vertex node, Vertex target) {
for (Edge edge : edges) {
if (edge.getSource().equals(node)
&& edge.getDestination().equals(target)) {
return edge.getWeight();
}
}
throw new RuntimeException("Should not happen");
}
private List<Vertex> getNeighbors(Vertex node) {
List<Vertex> neighbors = new ArrayList<Vertex>();
for (Edge edge : edges) {
if (edge.getSource().equals(node)
&& !isSettled(edge.getDestination())) {
neighbors.add(edge.getDestination());
}
}
return neighbors;
}
private Vertex getMinimum(Set<Vertex> vertexes) {
Vertex minimum = null;
for (Vertex vertex : vertexes) {
if (minimum == null) {
minimum = vertex;
} else {
if (getShortestDistance(vertex) < getShortestDistance(minimum)) {
minimum = vertex;
}
}
}
return minimum;
}
private boolean isSettled(Vertex vertex) {
return settledNodes.contains(vertex);
}
private int getShortestDistance(Vertex 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<Vertex> getPath(Vertex target) {
LinkedList<Vertex> path = new LinkedList<Vertex>();
Vertex 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;
}
}
顶点、边、图代码同Dijkstra Shortest Path Algorithm
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:orientation="vertical"
tools:context="com.example.lyeji.dijkstraalgorithmtest.MainActivity">
<com.example.lyeji.dijkstraalgorithmtest.Navigation
android:layout_width="1100px"
android:layout_height="1250px" />
</RelativeLayout>
LogCat
03-08 11:42:43.225 13819-13819/com.example.lyeji.dijkstraalgorithmtest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.lyeji.dijkstraalgorithmtest, PID: 13819
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.lyeji.dijkstraalgorithmtest/com.example.lyeji.dijkstraalgorithmtest.MainActivity}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class com.example.lyeji.dijkstraalgorithmtest.Navigation
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2611)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2677)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1515)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:6100)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:859)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
Caused by: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class com.example.lyeji.dijkstraalgorithmtest.Navigation
at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
at com.example.lyeji.dijkstraalgorithmtest.MainActivity.onCreate(MainActivity.java:19)
at android.app.Activity.performCreate(Activity.java:6280)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1131)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2564)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2677)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1515)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:6100)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:859)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
Caused by: android.view.InflateException: Binary XML file line #0: Error inflating class com.example.lyeji.dijkstraalgorithmtest.Navigation
at android.view.LayoutInflater.createView(LayoutInflater.java:645)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
at com.example.lyeji.dijkstraalgorithmtest.MainActivity.onCreate(MainActivity.java:19)
at android.app.Activity.performCreate(Activity.java:6280)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1131)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2564)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2677)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1515)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:6100)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:859)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at android.view.LayoutInflater.createView(LayoutInflater.java:619)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
at com.example.lyeji.dijkstraalgorithmtest.MainActivity.onCreate(MainActivity.java:19)
at android.app.Activity.performCreate(Activity.java:6280)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1131)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2564)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2677)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1515)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:6100)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:859)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
Caused by: java.lang.NumberFormatException: Invalid int: ""
at java.lang.Integer.invalidInt(Integer.java:138)
at java.lang.Integer.parseInt(Integer.java:358)
at java.lang.Integer.parseInt(Integer.java:334)
at com.example.lyeji.dijkstraalgorithmtest.Navigation.initialrun(Navigation.java:51)
at com.example.lyeji.dijkstraalgorithmtest.Navigation.<init>(Navigation.java:37)
at java.lang.reflect.Constructor.newInstance(Native Method)
at android.view.LayoutInflater.createView(LayoutInflater.java:619)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
at com.example.lyeji.dijkstraalgorithmtest.MainActivity.onCreate(MainActivity.java:19)
at android.app.Activity.performCreate(Activity.java:6280)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1131)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2564)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2677)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1515)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:6100)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:859)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
我认为主要问题来自 Navigation.java:51
pathTaken[i] = Integer.parseInt(tempPath[i]);
我认为问题在于它没有将任何 int 存储到 pathTaken[i] 中,但我不知道为什么会发生此错误。
我已经面临这个问题好几个小时了。我希望有人可以帮助我找出问题所在。提前致谢!
【问题讨论】:
-
与问题分享您的 xml 布局文件
-
我打赌这是你的数据。使用调试器单步执行您的代码(或者只需使用
System.out.println将您的顶点吐出到控制台),这样您就可以在添加顶点时看到实际值。其中一个是空白的,只有你用来填充顶点的空间。当您执行replace()时,您会连续得到两个逗号,从而产生一个空字符串作为您的令牌之一。这就是你的程序令人窒息的地方。 -
Navigation.java 第 51 行是哪一行?在这一行中,您尝试将空字符串转换为 int。
-
@Henry 第 51 行是
pathTaken[i] = Integer.parseInt(tempPath[i]);根据 LogCat 中的错误,这正是您所期望的。 -
@NileshRathod 我已经更新了 XML 文件