private void checkExcepction(Collection<Vertex> v, Collection<Edge> e) { for (Edge edge : e) { // No edge from or to vertex labeled A if there is no vertex with // label A if (!v.contains(edge.getSource()) || !v.contains(edge.getDestination())) { throw new IllegalArgumentException(); } // Edge weights should not be negative if (edge.getWeight() < 0) { throw new IllegalArgumentException(); } // Collection of edges should not has the same directed edge more // than once // with a different weight for (Edge checkEdges : e) { if (checkEdges.getSource().equals(edge.getSource()) && checkEdges.getDestination().equals(edge.getDestination()) && checkEdges.getWeight() != edge.getWeight()) { throw new IllegalArgumentException(); } } } }
@Override public Vertex<V> opposite(Vertex<V> v, Edge<E, V> e) { Vertex<V> vt; if (e.getSource().equals(v)) vt = (Vertex<V>) e.getDestination(); else if (e.getDestination().equals(v)) vt = (Vertex<V>) e.getSource(); else vt = null; return vt; }
@SuppressWarnings("unchecked") @Override public boolean areAdjacent(Vertex<V> v, Vertex<V> w) { boolean b = false; Edge<E, V> eg = (Edge<E, V>) edges.getHeader(); while (eg != null && !b) { if ((eg.getDestination().equals(v) || eg.getSource().equals(v)) && (eg.getDestination().equals(w) || eg.getSource().equals(w))) b = true; try { eg = (Edge<E, V>) edges.next((Pointer<E>) eg.getPosition()).element(); } catch (Exception exc) { eg = null; } } return b; }
/** * Test whether vertex b is adjacent to vertex a (i.e. a -> b) in a directed graph. Assumes that * we do not have negative cost edges in the graph. * * @param a one vertex * @param b another vertex * @return cost of edge if there is a directed edge from a to b in the graph, return -1 otherwise. * @throws IllegalArgumentException if a or b do not exist. */ @Override public int edgeCost(Vertex a, Vertex b) { if (a == null || b == null || !totalVertices.contains(a) || !totalVertices.contains(b)) { throw new IllegalArgumentException(); } for (Edge edge : adj.get(a)) { if (edge.getDestination().equals(b)) { return edge.getWeight(); } } return -1; }
@SuppressWarnings("unchecked") @Override public void reverseDirection() { Edge<E, V> h = (Edge<E, V>) edges.getHeader(); while (h != null) { Vertex<V> temp = h.getSource(); h.setSource(h.getDestination()); h.setDestination(temp); try { h = (Edge<E, V>) edges.next((Pointer<E>) h.getPosition()).element(); } catch (Exception exc) { h = null; } } }
@SuppressWarnings("unchecked") public String printEdges(String type) { String s = ""; Edge<E, V> eg = (Edge<E, V>) edges.getHeader(); while (eg != null) { if (eg.getType().equals(type)) s += eg.getSource().getInfo() + " -> " + eg.getDestination().getInfo() + "\n"; try { eg = (Edge<E, V>) edges.next((Pointer<E>) eg.getPosition()).element(); } catch (Exception exc) { eg = null; } } return s; }
/** * Return a collection of vertices adjacent to a given vertex v. i.e., the set of all vertices w * where edges v -> w exist in the graph. Return an empty collection if there are no adjacent * vertices. * * @param v one of the vertices in the graph * @return an iterable collection of vertices adjacent to v in the graph * @throws IllegalArgumentException if v does not exist. */ @Override public Collection<Vertex> adjacentVertices(Vertex v) { if (v == null || !totalVertices.contains(v)) { throw new IllegalArgumentException(); } List<Vertex> destiVertex = new ArrayList<Vertex>(); // Returns the edge to which the specified key is mapped, or null if // this map contains no mapping for the key.Then add the edge to the // ArrayList for (Edge e : adj.get(v)) { destiVertex.add(e.getDestination()); } return destiVertex; }
@SuppressWarnings("unchecked") @Override public Iterator<Vertex<V>> adjacentVertices(Vertex<V> v) { List<Vertex<V>> coll = new ArrayList<Vertex<V>>(); Edge<E, V> head_edg = (Edge<E, V>) edges.getHeader(); while (head_edg != null) { if (head_edg.getSource().equals(v)) coll.add((Vertex<V>) head_edg.getDestination()); try { head_edg = (Edge<E, V>) edges.next((Pointer<E>) head_edg.getPosition()).element(); } catch (Exception exc) { head_edg = null; } } return coll.iterator(); }
/** * Returns the shortest path from a to b in the graph, or null if there is no such path. Assumes * all edge weights are nonnegative. Uses Dijkstra's algorithm. * * @param a the starting vertex * @param b the destination vertex * @return a Path where the vertices indicate the path from a to b in order and contains a (first) * and b (last) and the cost is the cost of the path. Returns null if b is not reachable from * a. * @throws IllegalArgumentException if a or b does not exist. */ public Path shortestPath(Vertex a, Vertex b) { List<Vertex> vertexList = new ArrayList<Vertex>(); VertexComparator vcp = new VertexComparator(); PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>(10, vcp); // queue for unknow vertex // If the start and end vertex are equal // return a path containing one vertex and a cost of 0. if (a.equals(b)) { vertexList.add(a); return new Path(vertexList, 0); } // if the start and end vertex are not equal: // if there is no path starting from a, return null if (!adj.containsKey(a)) { return null; } // for (Vertex v : this.vertices() ) { // System.out.println(v.known); // } // initialize before searching path for (Vertex v : adj.keySet()) { // variables in adj.keySet() are actually pointers pointing to different memory with those in // this.vertices() // what we need is actually to change those in memory pointed by this.vertices() // have no idea why this.vertices.get() method did not work // thus I have to implement as below Vertex vn = v; // actually this is a bad initialization for (Vertex vi : this.vertices()) { if (vi.equals(v)) { vn = vi; } } vn.known = false; // set all vertex distance to infinity vn.distance = Integer.MAX_VALUE; // vn.distance = 99999; vertexQueue.add(vn); } // System.exit(1); // Set source vertex distance to 0 for (Vertex vn : this.vertices()) { if (vn.equals(a)) { vertexQueue.remove(vn); vn.distance = 0; vn.previous = vn; // update vn in vertexQueue vertexQueue.add(vn); } } // a.distance = 0; // a.previous = a; // vertexQueue.remove(a); // vertexList.add(a); Vertex end = b; for (Vertex vn : this.vertices()) { if (vn.equals(b)) { end = vn; } } // for (Vertex v : this.vertices() ) { // System.out.println(v.distance); // } System.out.println("start searching..."); // while ( (!vertexQueue.isEmpty()) && (end.known == false) ) { //while there are still unknow // vertex and vertex b is unknown while ((!vertexQueue .isEmpty())) { // while there are still unknow vertex and vertex b is unknown // System.out.println("elements in vertexQueue at beginning:"); // for (Vertex v : vertexQueue ) { // System.out.println(v.getLabel()); // System.out.println("distance: " + v.distance); // } Vertex nt = vertexQueue.poll(); // unknown node with smallest distance // System.out.println("marked " + nt + " as known."); // System.out.println("its current distance: " + nt.distance); nt.known = true; for (Edge e : adj.get(nt)) { // search for vertex with the same name as e.getDestination() in this.vertices() Vertex en = e.getDestination(); for (Vertex vn : this.vertices()) { if (vn.equals(e.getDestination())) { en = vn; } } if (!en.known) { if ((nt.distance + e.getWeight()) < en.distance) { // update en in vertexQueue vertexQueue.remove(en); en.distance = nt.distance + e.getWeight(); en.previous = nt; vertexQueue.add(en); } } } } System.out.println("finished computing shortest path."); // for (Vertex v : this.vertices() ) { // System.out.println(v.distance); // } // traverse to get path from a to b Vertex tmp = end; while (!tmp.equals(a)) { vertexList.add(0, tmp); // may need a heap here? tmp = tmp.previous; } vertexList.add(0, a); return new Path(vertexList, end.distance); // TODO: after searching for all possible path, return null if there is no path from a to b }