使用无向未加权列表图的迷宫实现

时间:2014-12-11 09:10:45

标签: java algorithm graph

我试图使用Undirected未加权列表图来实现Maze。但是我对java有困难。我得到空指针异常。我不知道如何实现这一目标。我已经花了很多时间,我想让这个工作,如果有人能给我指导,我将非常感激。

代码在这里。我没有使用任何已经实现的方法。我自己实现的大部分方法都是:

package maze3;

import java.util.Stack;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Hashtable;
import java.util.Stack;


// Single linked list
class SLLNode<E> {
    protected E element;
    protected SLLNode<E> succ;
    public SLLNode(E elem, SLLNode<E> succ) {
        this.element = elem;
        this.succ = succ;
    }
    @Override
    public String toString() {
        return element.toString();
    }
}

class GraphNode<E> {
    private int index;
    private E info;
    private LinkedList<GraphNode<E>> neighbors;

    public GraphNode(int index, E info) {
        this.index = index;
        this.info = info;
        neighbors = new LinkedList<GraphNode<E>>();
    }
    boolean containsNeighbor(GraphNode<E> o) {
        return neighbors.contains(o);
    }
    void addNeighbor(GraphNode<E> o) {
        neighbors.add(o);
    }
    void removeNeighbor(GraphNode<E> o) {
        if (neighbors.contains(o)) {
            neighbors.remove(o);
        }
    }
    @Override
    public String toString() {
        String ret = "INFO:" + info + " NEIGHBORS:";
        for (int i = 0; i < neighbors.size(); i++) {
            ret += neighbors.get(i).info + " ";
        }
        return ret;

    }
    @Override
    public boolean equals(Object obj) {
        @SuppressWarnings("unchecked")
        GraphNode<E> pom = (GraphNode<E>) obj;
        return (pom.info.equals(this.info));
    }
    public int getIndex() {
        return index;
    }
    public void setIndex(int index) {
        this.index = index;
    }
    public E getInfo() {
        return info;
    }
    public void setInfo(E info) {
        this.info = info;
    }
    public LinkedList<GraphNode<E>> getNeighbors() {
        return neighbors;
    }
    public void setNeighbors(LinkedList<GraphNode<E>> neighbors) {
        this.neighbors = neighbors;
    }
}

interface Queue<E> {
    public boolean isEmpty();
    public int size();
    public E peek();
    public void clear();
    public void enqueue(E x);
    public E dequeue();
}
class LinkedQueue<E> implements Queue<E> {

    SLLNode<E> front, rear;
    int length;

    public LinkedQueue() {
        clear();
    }

    public boolean isEmpty() {
        return (length == 0);
    }

    public int size() {
        // Ja vrakja dolzinata na redicata.
        return length;
    }

    public E peek() {
        if (front == null) {
            throw new NoSuchElementException();
        }
        return front.element;
    }

    public void clear() {
        front = rear = null;
        length = 0;
    }

    public void enqueue(E x) {

        SLLNode<E> latest = new SLLNode<E>(x, null);
        if (rear != null) {
            rear.succ = latest;
            rear = latest;
        } else {
            front = rear = latest;
        }
        length++;
    }

    public E dequeue() {

        if (front != null) {
            E frontmost = front.element;
            front = front.succ;
            if (front == null) {
                rear = null;
            }
            length--;
            return frontmost;
        } else {
            throw new NoSuchElementException();
        }
    }

}

// Graph implementation
class Graph<E> {

    int num_nodes;
    GraphNode<E> adjList[];

    @SuppressWarnings("unchecked")
    public Graph(int num_nodes, E[] list) {
        this.num_nodes = num_nodes;
        adjList = (GraphNode<E>[]) new GraphNode[num_nodes];
        for (int i = 0; i < num_nodes; i++) {
            adjList[i] = new GraphNode<E>(i, list[i]);
        }
    }

    @SuppressWarnings("unchecked")
    public Graph(int num_nodes) {
        this.num_nodes = num_nodes;
        adjList = (GraphNode<E>[]) new GraphNode[num_nodes];
    }

    int adjacent(int x, int y) {
        return (adjList[x].containsNeighbor(adjList[y])) ? 1 : 0;
    }

    void addEdge(int x, int y) {
        //System.out.println(adjList[x].getInfo());
       if (!adjList[x].containsNeighbor(adjList[y])) {
            adjList[x].addNeighbor(adjList[y]);
            adjList[y].addNeighbor(adjList[x]);
        }
    }

    void deleteEdge(int x, int y) {
        adjList[x].removeNeighbor(adjList[y]);
        adjList[y].removeNeighbor(adjList[x]);
    }

    public int getNum_nodes() {
        return num_nodes;
    }

    void dfsSearch(int node) {
        boolean visited[] = new boolean[num_nodes];
        for (int i = 0; i < num_nodes; i++) {
            visited[i] = false;
        }
        dfsRecursive(node, visited);
    }

    void dfsRecursive(int node, boolean visited[]) {
        visited[node] = true;
        System.out.println(node + ": " + adjList[node].getInfo());

        for (int i = 0; i < adjList[node].getNeighbors().size(); i++) {
            GraphNode<E> pom = adjList[node].getNeighbors().get(i);
            if (!visited[pom.getIndex()]) {
                dfsRecursive(pom.getIndex(), visited);
            }
        }
    }

    void dfsNonrecursive(int node) {
        boolean visited[] = new boolean[num_nodes];
        for (int i = 0; i < num_nodes; i++) {
            visited[i] = false;
        }
        visited[node] = true;
        System.out.println(node + ": " + adjList[node].getInfo());
        Stack<Integer> s = new Stack<Integer>();
        s.push(node);

        GraphNode<E> pom;

        while (!s.isEmpty()) {
            pom = adjList[s.peek()];
            GraphNode<E> tmp = null;
            for (int i = 0; i < pom.getNeighbors().size(); i++) {
                tmp = pom.getNeighbors().get(i);
                if (!visited[tmp.getIndex()]) {
                    break;
                }
            }
            if (tmp != null && !visited[tmp.getIndex()]) {
                visited[tmp.getIndex()] = true;
                System.out.println(tmp.getIndex() + ": " + tmp.getInfo());
                s.push(tmp.getIndex());
            } else {
                s.pop();
            }
        }

    }

    void bfs(int node) {
        boolean visited[] = new boolean[num_nodes];
        for (int i = 0; i < num_nodes; i++) {
            visited[i] = false;
        }
        visited[node] = true;
        System.out.println(node + ": " + adjList[node].getInfo());
        Queue<Integer> q = new LinkedQueue<Integer>();
        q.enqueue(node);

        GraphNode<E> pom;

        while (!q.isEmpty()) {
            pom = adjList[q.dequeue()];
            GraphNode<E> tmp = null;
            for (int i = 0; i < pom.getNeighbors().size(); i++) {
                tmp = pom.getNeighbors().get(i);
                if (!visited[tmp.getIndex()]) {
                    visited[tmp.getIndex()] = true;
                    System.out.println(tmp.getIndex() + ": " + tmp.getInfo());
                    q.enqueue(tmp.getIndex());
                }
            }

        }

    }

    @Override
    public String toString() {
        String ret = new String();
        for (int i = 0; i < this.num_nodes; i++) {
            ret += i + ": " + adjList[i] + "\n";
        }
        return ret;
    }

}


// MAIN MAZE CLASS
public class Maze3 {
    /**
     *  Undirected unweighted graph with list
     * The graph nodes are indexes
     * The names of the nodes are translated into numbers with hash table
     * Example 1,1 is translated to 1
     */
    Graph g;
    int start_node; //indeks temeto koe e vlez
    int end_node; //indeks na temeto koe e izlez

    Hashtable<String, Integer> h;

    public Maze3() {
        h = new Hashtable<String, Integer>();
    }

    void generateGraph(int rows, int columns, String[] in) {

        int num_nodes = 0;

        String key;

        // Find start and end position
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < columns; j++) {
                if (in[i].charAt(j) != '#') {
                    key = i + "," + j;
                    h.put(key, num_nodes);
                    if (in[i].charAt(j) == 'S') {
                        start_node = num_nodes;
                    }
                    if (in[i].charAt(j) == 'E') {
                        end_node = num_nodes;
                    }
                    num_nodes++;
                }
            }
        }

        g = new Graph(num_nodes);

        int x;
        int y;
        //Generate the graph
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < columns; j++) {
                if (in[i].charAt(j) != '#') {
                    //check if there is vertex before
                    if (in[i].charAt(j - 1) != '#') {
                        x = h.get(i + "," + j);
                        y = h.get(i + "," + (j - 1));
                        g.addEdge(x, y);
                    }
                    //check if there is vertex after
                    if (in[i].charAt(j + 1) != '#') {
                        x = h.get(i + "," + j);
                        y = h.get(i + "," + (j + 1));
                        g.addEdge(x, y);
                    }
                    //check if there is vertex on top
                    if (in[i - 1].charAt(j) != '#') {
                        x = h.get(i + "," + j);
                        y = h.get((i - 1) + "," + j);
                        g.addEdge(x, y);
                    }
                   //check if there is vertex on bottom
                    if (in[i + 1].charAt(j) != '#') {
                        x = h.get(i + "," + j);
                        y = h.get((i + 1) + "," + j);
                        g.addEdge(x, y);
                    }
                }
            }
        }
    }

    void findPath() {
        boolean visited[] = new boolean[g.getNum_nodes()];
        for (int i = 0; i < g.getNum_nodes(); i++) {
            visited[i] = false;
        }
        visited[start_node] = true;
        Stack<Integer> s = new Stack<Integer>();
        s.push(start_node);

        int pom;
        while (!s.isEmpty() && s.peek() != end_node) {
            pom = s.peek();
            int pom1 = pom;
            for (int i = 0; i < g.getNum_nodes(); i++) {
                if (g.adjacent(pom, i) == 1) {
                    pom1 = i;
                    if (!visited[i]) {
                        break;
                    }
                }
            }
            if (!visited[pom1]) {
                visited[pom1] = true;
                //System.out.println(tmp.getIndex() + ": " + tmp.getInfo());
                s.push(pom1);
            } else {
                s.pop();
            }
        }
        if (s.isEmpty()) {
            System.out.println("Nema reshenie");
        } else {
            Stack<Integer> os = new Stack<Integer>();
            while (!s.isEmpty()) {
                os.push(s.pop());
            }
            while (!os.isEmpty()) {
                System.out.println(os.pop());
            }
        }
    }

    public static void main(String args[]) {
        Maze3 m = new Maze3();
        int rows = 6;
        int columns = 6;
        String[] in = new String[rows];

        //6,6
        in[0] = "######";
        in[1] = "#S# E#";
        in[2] = "# # ##";
        in[3] = "#   ##";
        in[4] = "######";
        in[5] = "######";

        m.generateGraph(rows, columns, in);
        System.out.println("Pateka:");
        m.findPath();
    }

}

函数addEdge()中的错误,也许verexs是null但是如何初始化它们?用什么?

Exception in thread "main" java.lang.NullPointerException
    at maze3.Graph.addEdge(Maze3.java:194)
    at maze3.Maze3.generateGraph(Maze3.java:387)
    at maze3.Maze3.main(Maze3.java:450)
Java Result: 1

0 个答案:

没有答案