Fill This Form To Receive Instant Help

Help in Homework
trustpilot ratings
google ratings


Homework answers / question archive / Use Java to implement a simplified editing tool which allows the users to draw a directed graph with nodes and arcs in the following way: • a node can be inserted, moved and deleted; • an arc can be inserted and deleted, but it cannot be moved

Use Java to implement a simplified editing tool which allows the users to draw a directed graph with nodes and arcs in the following way: • a node can be inserted, moved and deleted; • an arc can be inserted and deleted, but it cannot be moved

Computer Science

Use Java to implement a simplified editing tool which allows the users to draw a directed graph with nodes and arcs in the following way:
• a node can be inserted, moved and deleted;
• an arc can be inserted and deleted, but it cannot be moved.
You should guarantee that
• any arc the users draw must connect two nodes;
• when a node is moved, all its associated arcs should be moved automatically;
• when a node is deleted, all its associated arcs should be deleted automatically.
The users should be allowed to save a graph to a file and open it again to continue to draw.
Apart from the normal selections via menus, lists, buttons etc., the user can also use popup menus for the operations. A popup menu should be sensitive to its context, i.e., the GUI component on which it is triggered.
There should be a button to clear all existing nodes and arcs.
Whenever necessary, the user should be prompted with instructions on how to continue or what is wrong.
Optional: display a shortest path between any two nodes selected by the user, if exists.

pur-new-sol

Purchase A New Answer

Custom new solution created by our subject matter experts

GET A QUOTE

Answer Preview

• a node can be inserted, moved and deleted;
• an arc can be inserted and deleted, but it cannot be moved.

Step-by-step explanation

your explanation

 

 

 

Answer:

Given that:

public class Graph<T> {

   private HashMap<GraphNode<T>, HashSet<GraphNode<T>>> adjacencyMap;
   private int numVertices;
   private int numEdges;
   private final String type = "directed";
   private final boolean weighted = false;

   public Graph() {
       this.adjacencyMap = new HashMap<>();
   }

   /**
   * Adds a vertex to the graph.
   * @param vertex vertex to add.
   * @return true if vertex was added successfully, false if otherwise.
   * @
   */
   public boolean addVertex(GraphNode<T> vertex) {
       if(!this.adjacencyMap.containsKey(vertex)) {
           this.adjacencyMap.put(vertex, new HashSet<>());
           this.numVertices++;
           return true;
       }
       return false;
   }

   /**
   * Removes a specified vertex from the graph.
   * @param vertex vertex to remove.
   * @return true if vertex was removed successfully, false if otherwise.
   * @
   */
   public boolean removeVertex(GraphNode<T> vertex) {
       if(this.adjacencyMap.containsKey(vertex)) {
           this.adjacencyMap.remove(vertex);
           for(Map.Entry<GraphNode<T>, HashSet<GraphNode<T>>> entry : this.adjacencyMap.entrySet()) {
               if(entry.getValue().contains(vertex)) {
                   this.adjacencyMap.get(entry.getKey()).remove(vertex);
               }
           }
           this.numVertices--;
           return true;
       }
       return false;
   }

   /**
   * Adds an edge between two vertices to the graph.
   * @param x source vertex of edge to add.
   * @param y destination vertex of edge to add.
   * @return true if the edge was added successfully, false if otherwise.
   * @
   */
   public boolean addEdge(GraphNode<T> x, GraphNode<T> y) {
       if(this.adjacencyMap.containsKey(x)) {
           if(!this.adjacencyMap.get(x).contains(y)) {
               this.adjacencyMap.get(x).add(y);
               this.numEdges++;
               return true;
           }
       }
       return false;
   }

   /**
   * Removes a specified edge between two vertices from the graph, if it already exists.
   * @param x source vertex of edge to remove.
   * @param y destination vertex of edge to remove.
   * @return true if the edge was removed successfully, false if otherwise.
   * @
   */
   public boolean removeEdge(GraphNode<T> x, GraphNode<T> y) {
       if(this.adjacencyMap.containsKey(x)) {
           if(this.adjacencyMap.get(x).contains(y)) {
               this.adjacencyMap.get(x).remove(y);
               this.numEdges--;
               return true;
           }
       }
       return false;
   }

   /**
   * Determines if two vertices are adjacent (or, if an edge exists between them).
   * @param x source vertex.
   * @param y destination vertex.
   * @return true if both vertices are adjacent, false if otherwise.
   * @
   */
   public boolean isAdjacent(GraphNode<T> x, GraphNode<T> y) {
       HashSet<GraphNode<T>> adjacencySet = this.adjacencyMap.get(x);
       if(adjacencySet != null) {
           if(adjacencySet.contains(y)) {
               return true;
           }
       }
       return false;
   }

   /**
   * Determines if graph contains a given vertex or not.
   * @param vertex vertex to search.
   * @return true if the graph contains the vertex, false if otherwise.
   * @
   */
   public boolean containsVertex(GraphNode<T> vertex) {
       if(this.adjacencyMap.containsKey(vertex)) {
           return true;
       }
       return false;
   }

   /**
   * Returns a HashSet containing all neighbors of a given vertex (or, all vertices with which the vertex shares an edge).
   * @param vertex vertex to search.
   * @return a HashSet containing all neighbors of the vertex.
   * @
   */
   public HashSet<GraphNode<T>> getNeighbors(GraphNode<T> vertex) {
       return this.adjacencyMap.get(vertex);
   }

   /**
   * Determines whether or not a path exists between two nodes, using Depth-First Search.
   * Uses a wrapper method to initialize objects required for search traversal.
   * @param source source node to be used in search.
   * @param destination destination node to be used in search.
   * @return true if a path exists between source and destination nodes, false if otherwise.
   * @
   */
   public boolean depthFirstSearch(GraphNode<T> source, GraphNode<T> destination) {
       if(!this.adjacencyMap.containsKey(source) || !this.adjacencyMap.containsKey(destination)) {
           return false;
       }
       Stack<GraphNode<T>> stack = new Stack<>();
       stack.push(source);
       return depthFirstSearch(stack, destination);
   }
   private boolean depthFirstSearch(Stack<GraphNode<T>> stack, GraphNode<T> destination) {
       HashMap<GraphNode<T>, VisitStatus> visited = new HashMap<>();
       while(!stack.isEmpty()) {
           GraphNode<T> current = stack.pop();
           visited.put(current, VisitStatus.VISITING);
           if(current.equals(destination)) {
               return true;
           }
           for(GraphNode<T> neighbor : this.adjacencyMap.get(current)) {
               if(visited.containsKey(neighbor)) {
                   if(visited.get(neighbor).equals(VisitStatus.UNVISITED)) {
                       stack.push(neighbor);
                   }
               } else {
                   stack.push(neighbor);
               }
           }
           visited.put(current, VisitStatus.VISITED);
       }
       return false;
   }

   /**
   * Determines whether or not a path exists between two nodes, using Breadth-First Search.
   * Uses a wrapper method to initialize objects required for search traversal.
   * @param source source node to be used in search.
   * @param destination destination node to be used in search.
   * @return true if a path exists between source and destination nodes, false if otherwise.
   * @
   */
   public boolean breadthFirstSearch(GraphNode<T> source, GraphNode<T> destination) {
       if(!this.adjacencyMap.containsKey(source) || !this.adjacencyMap.containsKey(destination)) {
           return false;
       }
       LinkedList<GraphNode<T>> queue = new LinkedList<>();
       queue.addLast(source);
       return breadthFirstSearch(queue, destination);
   }
   private boolean breadthFirstSearch(LinkedList<GraphNode<T>> queue, GraphNode<T> destination) {
       HashMap<GraphNode<T>, VisitStatus> visited = new HashMap<>();
       while(!queue.isEmpty()) {
           GraphNode<T> current = queue.removeFirst();
           visited.put(current, VisitStatus.VISITING);
           if(current.equals(destination)) {
               return true;
           }
           for(GraphNode<T> neighbor : this.adjacencyMap.get(current)) {
               if(visited.containsKey(neighbor)) {
                   if(visited.get(neighbor).equals(VisitStatus.UNVISITED)) {
                       queue.addLast(neighbor);
                   }
               } else {
                   queue.addLast(neighbor);
               }
           }
           visited.put(current, VisitStatus.VISITED);
       }
       return false;
   }

   /**
   * Returns the number of vertices within the graph.
   * @return an integer representing number of vertices contained within the graph.
   * @
   */
   public int getNumVertices() {
       return this.numVertices;
   }

   /**
   * Returns the number of edges within the graph.
   * @return an integer representing number of edges contained within the graph.
   * @
   */
   public int getNumEdges() {
       return this.numEdges;
   }