当我将边缘添加到图形(树)时,我得到一个空指针

时间:2014-02-28 16:58:25

标签: java graph tree

我有一个创建Kruskal算法的任务,在网上有一个很好的教程很好,但是我很难尝试用指定的权重将边添加到我的所有节点。这就是我正在做的事情,希望你们能帮助我。

主要功能

 public static void main(String[] args) {
    int maximumVertices = 50;
    Random ran = new Random();


    Graph g = new Graph(maximumVertices);
    for(int i=0; i<maximumVertices-1; i++){
        int weight = ran.nextInt(50);
        int connectedNode = ran.nextInt(10); //the idea here is to create random connections between nodes
        g.addVertex(i);
        g.addBidirectionalEdge(i, connectedNode, weight);
        g.addBidirectionalEdge(i+1, connectedNode, weight);
        System.out.println(Arrays.toString((g.getAdjacentVertexNumbers(i))));

    }
Kruskal k = new Kruskal(g);
    List<Edge> mst = k.getMSTEdges();

    System.out.println ("Minimum Spanning Tree Edges are:");
    ListIterator<Edge> it = mst.listIterator();
    while(it.hasNext()){
        Edge e = (Edge)it.next();
        System.out.println ("v" + e.getFrom().getVertexNo() + " --- v" + e.getTo().getVertexNo());
        }

Kruskal班

  public class Kruskal {
private Graph graph;
private int[] sets; //represent set for vertices

public Kruskal(Graph g) {
    this.graph = g;
    this.sets = new int[g.getTotalNumberOfVertices()];
}

private void makeSet(Vertex v){
    this.sets[v.getVertexNo()] = v.getVertexNo(); //simply set the set name to each vertex no
}

private int findSet(Vertex v){
    return this.sets[v.getVertexNo()]; //gets the set name/number of a vertex
}

private void union(Vertex u, Vertex v){
    int findWhat, replaceWith;

    if(u.getVertexNo() < v.getVertexNo()){
        findWhat = this.sets[v.getVertexNo()];
        replaceWith = this.sets[u.getVertexNo()];
    }
    else{
        findWhat = this.sets[u.getVertexNo()];
        replaceWith = this.sets[v.getVertexNo()];
    }

    //make both sets same
    for(int i=0; i<this.sets.length; i++){
        if(this.sets[i] == findWhat){
            this.sets[i] = replaceWith;
        }
    }

}

private void sortEdges(Edge[] edges){
    for(int i=0; i<edges.length-1; i++){
        for(int j=i+1; j<edges.length; j++){
            if(edges[i].getWeight() > edges[j].getWeight()){
                Edge tmp = edges[i];
                edges[i] = edges[j];
                edges[j] = tmp;
            }
        }
    }
}

//runs the main kruskal algorithm
public List<Edge> getMSTEdges(){
    //holds the MST edges
    List<Edge> mstEdges = new ArrayList<Edge>();

    Vertex[] vertices = this.graph.getVertices();
    for(int i=0; i<vertices.length; i++){
        this.makeSet(vertices[i]);
    }

    //get all bi-directional edges
    Edge[] edges = this.graph.getAllBidirectionalEdges();
    //sort the edges w.r.t their weights in non-decreasing order
    this.sortEdges(edges);

    for(int i=0; i<edges.length; i++){
        //for each each, in sorted order
        Edge e = edges[i];          
        if(this.findSet(e.getFrom()) != this.findSet(e.getTo())){
            //if the vertices it connects are not in the same set
            //this edge is an MST edge
            mstEdges.add(e);
            //now, both vertices should have same set
            this.union(e.getFrom(), e.getTo());
        }
    }

    return mstEdges;
}
}

图表类

public class Graph {
private final int DEFAULT_EDGE_COST = 1;
private Vertex[] vertices = null; //list of all vertices in the graph
private int totalVertices = 0; //keeps count of vertices
private int[][] adjMatrix = null; //keeps the edges of the graph using adjacency matrix
private int[] adjacentVertCount = null; //keeps count of adjacent vertices for each vertex

public Graph(int maxVertices) {
    this.vertices = new Vertex[maxVertices]; //initialize vertices array
    this.adjMatrix = new int[maxVertices][maxVertices]; //initialize adjacency matrix
    this.adjacentVertCount = new int[maxVertices]; //initialize adjacent vertices count
    for(int i=0; i<maxVertices; i++){
        this.adjacentVertCount[i] = 0; //set adjacent vertex count to 0 initially
        for(int j=0; j<maxVertices; j++){
            this.adjMatrix[i][j] = -1; //set adjacency list to -1 initially
        }
    }
}



 public Graph(){
    //default Max amount of vertices: 100 [0-99]
    this(100);
}

//add a new vertex with vertexNo and data
public void addVertex(int vertexNo, Object data){
    this.vertices[vertexNo] = new Vertex(vertexNo, data);
    this.totalVertices++;
}

//add a new vertex with vertexNo only
public void addVertex(int vertexNo){
    this.addVertex(vertexNo, null);
}

//add a uni-directional edge with cost
public void addEdge(int fromVertexNo, int toVertexNo, int cost){
    this.adjMatrix[fromVertexNo][toVertexNo] = cost;
    this.adjacentVertCount[fromVertexNo]++;
} 

//add a bi-directional edge with cost
public void addBidirectionalEdge(int vertex1, int vertex2, int cost){
    this.addEdge(vertex1, vertex2, cost);
    this.addEdge(vertex2, vertex1, cost);
}

//add a bi-directional edge with cost
public void addBidirectionalEdge(Vertex v1, Vertex v2, int cost){
    this.addBidirectionalEdge(v1.getVertexNo(), v2.getVertexNo(), cost);
}


//get the total vertices count in the graph
public int getTotalNumberOfVertices(){
    return this.totalVertices;
}



//get adjacent vertex numbers for a given vertexNo
public int[] getAdjacentVertexNumbers(int vertexNo){
    int[] ret = new int[this.adjacentVertCount[vertexNo]];
    int index = 0;

    for(int i=0; i<this.adjMatrix[vertexNo].length; i++){
        if(this.adjMatrix[vertexNo][i] >= 0){
            ret[index++] = i;
        }
    }

    return ret;
}

//get adjacent vertex numbers for a given vertex
public int[] getAdjacentVertexNumbers(Vertex vert){
    return this.getAdjacentVertexNumbers(vert.getVertexNo());
}

//get adjacent vertices for a given vertexNo
public Vertex[] getAdjacentVertices(int vertexNo){
    Vertex[] ret = new Vertex[this.adjacentVertCount[vertexNo]];
    int index = 0;

    for(int i=0; i<this.adjMatrix[vertexNo].length; i++){
        if(this.adjMatrix[vertexNo][i] >= 0){
            ret[index++] = this.vertices[i];
        }
    }

    return ret;
}

//get adjacent vertices for a given vertex
public Vertex[] getAdjacentVertices(Vertex vert){
    return this.getAdjacentVertices(vert.getVertexNo());
}

//gets the edge/path cost from adjacency list for two given vertexNo
public int getEdgeCost(int fromVertNo, int toVertNo){
    return this.adjMatrix[fromVertNo][toVertNo];
}

//gets the edge/path cost from adjacency list for two given vertices
public int getEdgeCost(Vertex fromVert, Vertex toVert){
    return this.getEdgeCost(fromVert.getVertexNo(), toVert.getVertexNo());
}

//gets all vertices
public Vertex[] getVertices(){
    return this.vertices;
}

//returns all the edges of the graph
//needed for edge traversing algorithms
public Edge[] getAllEdges(){
    int totalEdges = 0;
    for(int i=0; i<this.adjacentVertCount.length; i++){
        totalEdges += this.adjacentVertCount[i];
    }

    Edge[] edges = new Edge[totalEdges];
    int index = 0;
    for(int i=0; i<this.vertices.length; i++){
        for(int j=0; j<this.vertices.length; j++){
            if(this.adjMatrix[i][j] >= 0){
                edges[index++] = new Edge(this.vertices[i], this.vertices[j], this.adjMatrix[i][j]);
            }
        }
    }

    return edges;
}

public Edge[] getAllBidirectionalEdges(){
    int totalEdges = 0;
    for(int i=0; i<this.adjacentVertCount.length; i++){
        totalEdges += this.adjacentVertCount[i];
    }
    totalEdges /= 2;

    Edge[] edges = new Edge[totalEdges];
    int index = 0;
    for(int i=0; i<this.vertices.length; i++){
        for(int j=i+1; j<this.vertices.length; j++){
            if(this.adjMatrix[i][j] >= 0){
                edges[index++] = new Edge(this.vertices[i], this.vertices[j], this.adjMatrix[i][j]);
            }
        }
    }

    return edges;
}

}

错误:

Exception in thread "main" java.lang.NullPointerException
at Kruskal.makeSet(Kruskal.java:15)
at Kruskal.getMSTEdges(Kruskal.java:62)
at Main.main(Main.java:51)

我很好地打印出边缘,但是当我实现k.getMSTEdges()时,如果给我空指针而不喜欢它。 然而,当我对它进行硬编码时,例如g.addBidrectionalEdge(0,2,8)等等,它的工作原理让我知道它的主要内容,我不是正确的。再次感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

这似乎是你的问题:

for(int i=0; i<maximumVertices-1; i++)

将其更改为

for(int i=0; i<maximumVertices; i++)

这是您创建图表的位置。

否则,您只创建49个顶点,然后当您尝试访问第50个顶点时,会有NULL数据。或者至少,我假设Vertex将一些数据初始化为NULL