我正在尝试用Dijkstra算法写一个表格,两个顶点之间的权重是从文件中取出的一组坐标之间的距离。它添加顶点很好但是当它添加到边缘时我在主方法中得到一个空指针。
Exception in thread "main" java.lang.NullPointerException
at matrix.matrix(matrix.java:61)
at matrix.main(matrix.java:102)
指向标记(**)部分的代码。它可能非常简单,我很想念,所以任何帮助都会非常感激!感谢。
import java.util.*;
import java.io.*;
class matrix
{
//public static double[][] distanceMatrix;
public static int[] nameOfCities;
public static double[] Latitude;
public static double[] Longitude;
public static Graph theGraph = new Graph();
public static void matrix()
{
int size=0;
try {
File f = new File("Cities2.txt");//the file where the coordinates of cities are kept
Scanner sc = new Scanner(f);
Scanner scan = new Scanner(f);
int i=0;
while(scan.hasNextLine())
{
String readLine = scan.nextLine();
size++;
}
System.out.println("The number of cities is "+size);
double[] Latitude = new double[size];
double[] Longitude = new double[size];
nameOfCities = new int[size];
//double[][] distanceMatrix = new double[size][size];
while(sc.hasNextLine())
{
String line = sc.nextLine();
String[] details = line.split(" ");//until there's a space(" ") in the file
int name = Integer.parseInt(details[0]);//number in the file corresponds to the name of the town
nameOfCities[i]=name;//add this to the array called nameOfCities
double latitude = Double.parseDouble(details[1]);//corresponds to latitude value
Latitude[i]=latitude;//add this to latitude array
double longitude = Double.parseDouble(details[2]);//corresponds to longitude array
Longitude[i]=longitude;//add this to longitude array
theGraph.addVertex(i+1);
theGraph.displayVertex(i);
System.out.println(" Vertex added");
i++;
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
**for(int i=0; i<Latitude.length; i++)**
{
for(int j=i; j<Longitude.length; j++)
{
double distance = getDistance(Latitude[i],Longitude[i],Latitude[j],Longitude[j]);//gets distance between two points
distance = (double)Math.round(distance*100000.0)/100000.0;
//distanceMatrix[i][j] = distance;//inserts it into the matrix
theGraph.addEdge(i,j,distance);
System.out.print("Edge added.");
}
}
System.out.print("Distance matrix and graph filled.");//matrix is filled
}
public static double getDistance(double lat1, double lon1, double lat2, double lon2)
{
//gets the distance using haversine function
double R = 6371;
double dLat = Math.toRadians((lat2-lat1));
double dLon = Math.toRadians((lon2-lon1));
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = R * c;
return d;
}
public static void main(String[] args)
{
System.out.println("Filling Graph...");
**matrix();**
System.out.print("Shortest paths: ");
theGraph.path(); //shortest paths
System.out.println();
} // end main()
}
这是我的图表类
class Graph
{
private final int MAX_VERTS = 80;
private final int INFINITY = 1000000;
private Vertex vertexList[]; // list of vertices
private double adjMat[][]; // adjacency matrix
private int nVerts; // current number of vertices
private int nTree; //number of verts in tree
private DistPar sPath[]; //array for shortest-path data
private int currentVert;
private PriorityQ thePQ;
private double startToCurrent; //distance to currentVert
// -------------------------------------------------------------
public Graph() // constructor
{
vertexList = new Vertex[MAX_VERTS];
// adjacency matrix
adjMat = new double[MAX_VERTS][MAX_VERTS];
nVerts = 0;
nTree=0;
for(int j=0; j<MAX_VERTS; j++) // set adjacency
for(int k=0; k<MAX_VERTS; k++) // matrix to 0
adjMat[j][k] = INFINITY;
thePQ = new PriorityQ();
sPath = new DistPar[MAX_VERTS]; // shortest paths
} // end constructor
// -------------------------------------------------------------
public void addVertex(int lab)
{
vertexList[nVerts++] = new Vertex(lab);
}
// -------------------------------------------------------------
public void addEdge(int start, int end, double weight)
{
adjMat[start][end] = weight;
adjMat[end][start] = weight;
}
// -------------------------------------------------------------
public void displayVertex(int v)
{
System.out.print(vertexList[v].label);
}
// -------------------------------------------------------------
public void mstw() // minimum spanning tree
{
currentVert = 0; // start at 0
while(nTree < nVerts-1) // while not all verts in tree
{ // put currentVert in tree
vertexList[currentVert].isInTree = true;
nTree++;
// insert edges adjacent to currentVert into PQ
for(int j=0; j<nVerts; j++) // for each vertex,
{
if(j==currentVert) // skip if it’s us
continue;
if(vertexList[j].isInTree) // skip if in the tree
continue;
double distance = adjMat[currentVert][j];
if( distance == INFINITY) // skip if no edge
continue;
putInPQ(j, distance); // put it in PQ (maybe)
}
if(thePQ.size()==0) // no vertices in PQ?
{
System.out.println(" GRAPH NOT CONNECTED");
return;
}
// remove edge with minimum distance, from PQ
Edge theEdge = thePQ.removeMin();
int sourceVert = theEdge.srcVert;
currentVert = theEdge.destVert;
// display edge from source to current
System.out.print( vertexList[sourceVert].label );
System.out.print( vertexList[currentVert].label );
System.out.print(" ");
} // end while(not all verts in tree)
// mst is complete
for(int j=0; j<nVerts; j++) // unmark vertices
vertexList[j].isInTree = false;
} // end mstw
// -------------------------------------------------------------
public void putInPQ(int newVert, double newDist)
{
// is there another edge with the same destination vertex?
int queueIndex = thePQ.find(newVert);
if(queueIndex != -1) // got edge’s index
{
Edge tempEdge = thePQ.peekN(queueIndex); // get edge
double oldDist = tempEdge.distance;
if(oldDist > newDist) // if new edge shorter,
{
thePQ.removeN(queueIndex); // remove old edge
Edge theEdge = new Edge(currentVert, newVert, newDist);
thePQ.insert(theEdge); // insert new edge
}
// else no action; just leave the old vertex there
} // end if
else // no edge with same destination vertex
{ // so insert new one
Edge theEdge = new Edge(currentVert, newVert, newDist);
thePQ.insert(theEdge);
}
} // end putInPQ()
// -------------------------------------------------------------
public void path() // find all shortest paths
{
int startTree = 0; // start at vertex 0
vertexList[startTree].isInTree = true;
nTree = 1; // put it in tree
// transfer row of distances from adjMat to sPath
for(int j=0; j<nVerts; j++)
{
double tempDist = adjMat[startTree][j];
sPath[j] = new DistPar(startTree, tempDist);
}
// until all vertices are in the tree
while(nTree < nVerts)
{
int indexMin = getMin(); // get minimum from sPath
double minDist = sPath[indexMin].distance;
if(minDist == INFINITY) // if all infinite
{ // or in tree,
System.out.println("There are unreachable vertices");
break; // sPath is complete
}
else
{ // reset currentVert
currentVert = indexMin; // to closest vert
startToCurrent = sPath[indexMin].distance;
// minimum distance from startTree is
// to currentVert, and is startToCurrent
}
// put current vertex in tree
vertexList[currentVert].isInTree = true;
nTree++;
adjust_sPath(); // update sPath[] array
} // end while(nTree<nVerts)
displayPaths(); // display sPath[] contents
nTree = 0; // clear tree
for(int j=0; j<nVerts; j++)
vertexList[j].isInTree = false;
} // end path()
public int getMin() // get entry from sPath
{ // with minimum distance
double minDist = INFINITY; // assume large minimum
int indexMin = 0;
for(int j=1; j<nVerts; j++) // for each vertex,
{ // if it’s in tree and
if( !vertexList[j].isInTree && // smaller than old one
sPath[j].distance < minDist )
{
minDist = sPath[j].distance;
indexMin = j; // update minimum
}
} // end for
return indexMin; // return index of minimum
} // end getMin()
public void adjust_sPath()
{
// adjust values in shortest-path array sPath
int column = 1; // skip starting vertex
while(column < nVerts) // go across columns
{
// if this column’s vertex already in tree, skip it
if( vertexList[column].isInTree )
{
column++;
continue;
}
// calculate distance for one sPath entry
// get edge from currentVert to column
double currentToFringe = adjMat[currentVert][column];
// add distance from start
double startToFringe = startToCurrent + currentToFringe;
// get distance of current sPath entry
double sPathDist = sPath[column].distance;
// compare distance from start with sPath entry
if(startToFringe < sPathDist) // if shorter,
{ // update sPath
sPath[column].parentVert = currentVert;
sPath[column].distance = startToFringe;
}
column++;
} // end while(column < nVerts)
} // end adjust_sPath()
public void displayPaths()
{
for(int j=0; j<nVerts; j++) // display contents of sPath[]
{
System.out.print(vertexList[j].label + "="); // B=
if(sPath[j].distance == INFINITY)
System.out.print("inf"); // inf
else
System.out.print(sPath[j].distance); // 50
int parent = vertexList[ sPath[j].parentVert ].label;
System.out.print("(" + parent + ") "); // (A)
}
System.out.println("");
}
} // end class Graph
所有其他类只涉及构造函数,并且有一个优先级队列类以尝试以不同的方式实现算法,但我仍然得到相同的空指针。欢迎所有建议,即使我必须彻底改变我的代码! :)
答案 0 :(得分:1)
您shadowing变量Latitude
(和Longitude
)
double[] Latitude = new double[size];
应该是
Latitude = new double[size];
注意:Java命名约定表明变量以小写字母开头,例如latitude
和longitude