0

I am making a project like google map in which I have to construct a graph in which vertices are intersections and edges are roads . In my code I was able to add intersections and roads but I`m not able to return a path through breadth first search . And this is my code ,

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;
}

strong text This is the code with comments could anyone figure what is wrong with my implementation

  • First incorrect point about the code is "if(curr==gp)" in getNeighbors() method. You are comparing pointers instead of comparing the contents – mangusta Aug 02 '20 at 15:13
  • firstly I used equals() but still the same – Hesham Adel Aug 02 '20 at 15:16
  • I changed it now and still the same – Hesham Adel Aug 02 '20 at 15:18
  • Second incorrect point is the way how you populate the hashset and hashmaps. You are using custom objects as keys. Each object has its own hashcode (unless you override the hashCode() method of GeographicPoint class) which means that even if the object contents are the same, they are going to have different hashcodes and will thus occupy different hash buckets – mangusta Aug 02 '20 at 15:18
  • "equals" is not going to work either - you did not override it. java doesn't know how to compare two GeographicPoint objects if you don't override equals() method – mangusta Aug 02 '20 at 15:21
  • I don`t undrstand the second comment – Hesham Adel Aug 02 '20 at 15:22
  • but in the provided code they used "=" sign – Hesham Adel Aug 02 '20 at 15:23
  • For more help post [mre] and include test data. – c0der Aug 03 '20 at 03:50

0 Answers0