Проблема с BFS в графе java. Ничего не возвращает - PullRequest
0 голосов
/ 02 августа 2020

Я делаю проект вроде карты Google, в котором мне нужно построить граф, в котором вершины - это пересечения, а края - дороги. В моем коде я мог добавить перекрестки и дороги, но я не могу вернуть путь через поиск в ширину. И это мой код,

public class MapGraph {
//TODO: Add your member variables here in WEEK 3
HashSet<GeographicPoint> intersections ; 
HashMap<GeographicPoint,LinkedList<GeographicPoint>> roads ; 
HashMap<HashMap<GeographicPoint,GeographicPoint>,ArrayList<String>> roadInfo ; 

/** 
 * Create a new empty MapGraph 
 */
public MapGraph()
{
    // TODO: Implement in this constructor in WEEK 3
    intersections = new HashSet<GeographicPoint>() ; 
    roads = new HashMap<GeographicPoint,LinkedList<GeographicPoint>>() ; 
    roadInfo = new HashMap<HashMap<GeographicPoint,GeographicPoint>,ArrayList<String>>() ; 
}

/**
 * Get the number of vertices (road intersections) in the graph
 * @return The number of vertices in the graph.
 */
public int getNumVertices()
{
    //TODO: Implement this method in WEEK 3
    return intersections.size();
}

/**
 * Return the intersections, which are the vertices in this graph.
 * @return The vertices in this graph as GeographicPoints
 */
public Set<GeographicPoint> getVertices()
{
    //TODO: Implement this method in WEEK 3
    return intersections;
}

/**
 * Get the number of road segments in the graph
 * @return The number of edges in the graph.
 */
public int getNumEdges()
{
    //TODO: Implement this method in WEEK 3
    int num = 0 ; 
    for(GeographicPoint gp : roads.keySet()) {
        num+=roads.get(gp).size() ; 
    }
    return num;
}



/** Add a node corresponding to an intersection at a Geographic Point
 * If the location is already in the graph or null, this method does 
 * not change the graph.
 * @param location  The location of the intersection
 * @return true if a node was added, false if it was not (the node
 * was already in the graph, or the parameter is null).
 */
public boolean addVertex(GeographicPoint location)
{
    // TODO: Implement this method in WEEK 3
    if(!intersections.contains(location) && !(location == null)) {
        intersections.add(location) ; 
        return true ; 
    }
    return false;
}

/**
 * Adds a directed edge to the graph from pt1 to pt2.  
 * Precondition: Both GeographicPoints have already been added to the graph
 * @param from The starting point of the edge
 * @param to The ending point of the edge
 * @param roadName The name of the road
 * @param roadType The type of the road
 * @param length The length of the road, in km
 * @throws IllegalArgumentException If the points have not already been
 *   added as nodes to the graph, if any of the arguments is null,
 *   or if the length is less than 0.
 */
public void addEdge(GeographicPoint from, GeographicPoint to, String roadName,
        String roadType, double length) throws IllegalArgumentException {

    //TODO: Implement this method in WEEK 3
        if(roads.containsKey(from)) {
            roads.get(from).add(to) ;
        } else {
        List curr1 = new LinkedList<GeographicPoint>() ; 
        curr1.add(to);
        roads.put(from, (LinkedList<GeographicPoint>) curr1) ; 
        HashMap<GeographicPoint,GeographicPoint> curr = new HashMap<GeographicPoint,GeographicPoint>() ; 
        curr.put(from, to) ; 
        List<String> info = new  ArrayList<String>() ; 
        info.add(roadName);info.add(roadType);info.add(Double.toString(length));
        roadInfo.put(curr , (ArrayList<String>) info) ; 
    
        }
}


/** Find the path from start to goal using breadth first search
 * 
 * @param start The starting location
 * @param goal The goal location
 * @return The list of intersections that form the shortest (unweighted)
 *   path from start to goal (including both start and goal).
 */
public List<GeographicPoint> bfs(GeographicPoint start, GeographicPoint goal) {
    // Dummy variable for calling the search algorithms
    Consumer<GeographicPoint> temp = (x) -> {};
    return bfs(start, goal, temp);
}

/** Find the path from start to goal using breadth first search
 * 
 * @param start The starting location
 * @param goal The goal location
 * @param nodeSearched A hook for visualization.  See assignment instructions for how to use it.
 * @return The list of intersections that form the shortest (unweighted)
 *   path from start to goal (including both start and goal).
 *   
 */
private List<GeographicPoint> getNeighbors(GeographicPoint curr){
    List<GeographicPoint> answer = new ArrayList<GeographicPoint> () ; 
    for(GeographicPoint gp : roads.keySet()) {
        if(curr==gp) {
            answer = roads.get(gp) ; 
        }
    }
    System.out.println(answer);
    return answer ; 
}
public List<GeographicPoint> bfs(GeographicPoint start, 
                                 GeographicPoint goal, Consumer<GeographicPoint> nodeSearched)
{
    // TODO: Implement this method in WEEK 3
    
    // Hook for visualization.  See writeup.
    //nodeSearched.accept(next.getLocation());

    if (start == null || goal == null) {
        System.out.println("Start or goal node is null!  No path exists.");
        return new LinkedList<GeographicPoint>();
    }

    HashSet<GeographicPoint> visited = new HashSet<GeographicPoint>();
    Queue<GeographicPoint> toExplore = new LinkedList<GeographicPoint>();
    HashMap<GeographicPoint, GeographicPoint> parentMap = new HashMap<GeographicPoint, GeographicPoint>();
    toExplore.add(start);
    boolean found = false;
    while (!toExplore.isEmpty()) {
        GeographicPoint curr = toExplore.remove();
        if (curr == goal) {
            found = true;
            break;
        }
        List<GeographicPoint> neighbors = getNeighbors(curr);
        ListIterator<GeographicPoint> it = neighbors.listIterator(neighbors.size());
        while (it.hasPrevious()) {
            GeographicPoint next = it.previous();
            nodeSearched.accept(next);
            if (!visited.contains(next)) {
                visited.add(next);
                parentMap.put(next, curr);
                toExplore.add(next);
            }
        }
    }

    if (!found) {
        System.out.println("No path exists");
        return new ArrayList<GeographicPoint>();
    }
    // reconstruct the path
    LinkedList<GeographicPoint> path = new LinkedList<GeographicPoint>();
    GeographicPoint curr = goal;
    while (curr != start) {
        path.addFirst(curr);
        curr = parentMap.get(curr);
    }
    path.addFirst(start);
    return path;
}

строгий текст Это код с комментариями, кто-нибудь может понять, что не так с моей реализацией

...