Coverage Report - edu.uci.ics.jung.graph.DirectedSparseMultigraph
 
Classes in this File Line Coverage Branch Coverage Complexity
DirectedSparseMultigraph
82%
83/101
62%
35/56
2.667
DirectedSparseMultigraph$1
100%
2/2
N/A
2.667
 
 1  
 /*
 2  
  * Created on Oct 17, 2005
 3  
  *
 4  
  * Copyright (c) 2005, the JUNG Project and the Regents of the University 
 5  
  * of California
 6  
  * All rights reserved.
 7  
  *
 8  
  * This software is open-source under the BSD license; see either
 9  
  * "license.txt" or
 10  
  * http://jung.sourceforge.net/license.txt for a description.
 11  
  */
 12  
 package edu.uci.ics.jung.graph;
 13  
 
 14  
 import java.util.Collection;
 15  
 import java.util.Collections;
 16  
 import java.util.HashMap;
 17  
 import java.util.HashSet;
 18  
 import java.util.Map;
 19  
 import java.util.Set;
 20  
 
 21  
 import org.apache.commons.collections15.Factory;
 22  
 
 23  
 import edu.uci.ics.jung.graph.util.EdgeType;
 24  
 import edu.uci.ics.jung.graph.util.Pair;
 25  
 
 26  
 
 27  
 /**
 28  
  * An implementation of <code>DirectedGraph</code>, suitable for sparse graphs,
 29  
  * that permits parallel edges.
 30  
  */
 31  
 @SuppressWarnings("serial")
 32  
 public class DirectedSparseMultigraph<V,E> 
 33  
     extends AbstractTypedGraph<V,E>
 34  
     implements DirectedGraph<V,E>, MultiGraph<V,E> {
 35  
 
 36  
     /**
 37  
      * Returns a {@code Factory} that creates an instance of this graph type.
 38  
      * @param <V> the vertex type for the graph factory
 39  
      * @param <E> the edge type for the graph factory
 40  
      */
 41  
         public static <V,E> Factory<DirectedGraph<V,E>> getFactory() {
 42  18
                 return new Factory<DirectedGraph<V,E>> () {
 43  38
                         public DirectedGraph<V,E> create() {
 44  20
                                 return new DirectedSparseMultigraph<V,E>();
 45  
                         }
 46  
                 };
 47  
         }
 48  
 
 49  
         protected Map<V, Pair<Set<E>>> vertices; // Map of vertices to Pair of adjacency sets {incoming, outgoing}
 50  
     protected Map<E, Pair<V>> edges;            // Map of edges to incident vertex pairs
 51  
 
 52  
     /**
 53  
      * Creates a new instance.
 54  
      */
 55  
     public DirectedSparseMultigraph() {
 56  62
             super(EdgeType.DIRECTED);
 57  62
         vertices = new HashMap<V, Pair<Set<E>>>();
 58  62
         edges = new HashMap<E, Pair<V>>();
 59  62
     }
 60  
     
 61  
     public Collection<E> getEdges() {
 62  2
         return Collections.unmodifiableCollection(edges.keySet());
 63  
     }
 64  
 
 65  
     public Collection<V> getVertices() {
 66  118
         return Collections.unmodifiableCollection(vertices.keySet());
 67  
     }
 68  
 
 69  
     public boolean containsVertex(V vertex) {
 70  846
             return vertices.keySet().contains(vertex);
 71  
     }
 72  
     
 73  
     public boolean containsEdge(E edge) {
 74  344
             return edges.keySet().contains(edge);
 75  
     }
 76  
 
 77  
     protected Collection<E> getIncoming_internal(V vertex)
 78  
     {
 79  310
         return vertices.get(vertex).getFirst();
 80  
     }
 81  
     
 82  
     protected Collection<E> getOutgoing_internal(V vertex)
 83  
     {
 84  346
         return vertices.get(vertex).getSecond();
 85  
     }
 86  
     
 87  
     public boolean addVertex(V vertex) {
 88  222
             if(vertex == null) {
 89  2
                     throw new IllegalArgumentException("vertex may not be null");
 90  
             }
 91  220
         if (!containsVertex(vertex)) {
 92  218
             vertices.put(vertex, new Pair<Set<E>>(new HashSet<E>(), new HashSet<E>()));
 93  218
             return true;
 94  
         } else {
 95  2
             return false;
 96  
         }
 97  
     }
 98  
 
 99  
     public boolean removeVertex(V vertex) {
 100  22
         if (!containsVertex(vertex))
 101  0
             return false;
 102  
         
 103  
         // copy to avoid concurrent modification in removeEdge
 104  22
         Set<E> incident = new HashSet<E>(getIncoming_internal(vertex));
 105  22
         incident.addAll(getOutgoing_internal(vertex));
 106  
         
 107  22
         for (E edge : incident)
 108  30
             removeEdge(edge);
 109  
         
 110  22
         vertices.remove(vertex);
 111  
         
 112  22
         return true;
 113  
     }
 114  
     
 115  
     public boolean removeEdge(E edge) {
 116  32
         if (!containsEdge(edge))
 117  0
             return false;
 118  
         
 119  32
         Pair<V> endpoints = this.getEndpoints(edge);
 120  32
         V source = endpoints.getFirst();
 121  32
         V dest = endpoints.getSecond();
 122  
         
 123  
         // remove edge from incident vertices' adjacency sets
 124  32
         getOutgoing_internal(source).remove(edge);
 125  32
         getIncoming_internal(dest).remove(edge);
 126  
         
 127  32
         edges.remove(edge);
 128  32
         return true;
 129  
     }
 130  
 
 131  
     
 132  
     public Collection<E> getInEdges(V vertex) {
 133  4
         if (!containsVertex(vertex))
 134  0
             return null;
 135  
 
 136  4
         return Collections.unmodifiableCollection(getIncoming_internal(vertex));
 137  
     }
 138  
 
 139  
     public Collection<E> getOutEdges(V vertex) {
 140  12
         if (!containsVertex(vertex))
 141  0
             return null;
 142  
         
 143  12
         return Collections.unmodifiableCollection(getOutgoing_internal(vertex));
 144  
     }
 145  
 
 146  
     public Collection<V> getPredecessors(V vertex) {
 147  8
         if (!containsVertex(vertex))
 148  0
             return null;
 149  
 
 150  8
         Set<V> preds = new HashSet<V>();
 151  8
         for (E edge : getIncoming_internal(vertex))
 152  12
             preds.add(this.getSource(edge));
 153  
         
 154  8
         return Collections.unmodifiableCollection(preds);
 155  
     }
 156  
 
 157  
     public Collection<V> getSuccessors(V vertex) {
 158  34
         if (!containsVertex(vertex))
 159  0
             return null;
 160  
         
 161  34
         Set<V> succs = new HashSet<V>();
 162  34
         for (E edge : getOutgoing_internal(vertex))
 163  28
             succs.add(this.getDest(edge));
 164  
         
 165  34
         return Collections.unmodifiableCollection(succs);
 166  
     }
 167  
 
 168  
     public Collection<V> getNeighbors(V vertex) {
 169  2
         if (!containsVertex(vertex))
 170  0
             return null;
 171  
         
 172  2
         Collection<V> neighbors = new HashSet<V>();
 173  2
         for (E edge : getIncoming_internal(vertex))
 174  4
             neighbors.add(this.getSource(edge));
 175  2
         for (E edge : getOutgoing_internal(vertex))
 176  4
             neighbors.add(this.getDest(edge));
 177  2
         return Collections.unmodifiableCollection(neighbors);
 178  
     }
 179  
 
 180  
     public Collection<E> getIncidentEdges(V vertex) {
 181  2
         if (!containsVertex(vertex))
 182  0
             return null;
 183  
         
 184  2
         Collection<E> incident = new HashSet<E>();
 185  2
         incident.addAll(getIncoming_internal(vertex));
 186  2
         incident.addAll(getOutgoing_internal(vertex));
 187  2
         return incident;
 188  
     }
 189  
 
 190  
     @Override
 191  
     public E findEdge(V v1, V v2) {
 192  2
         if (!containsVertex(v1) || !containsVertex(v2))
 193  0
             return null;
 194  2
         for (E edge : getOutgoing_internal(v1))
 195  4
             if (this.getDest(edge).equals(v2))
 196  2
                 return edge;
 197  
         
 198  0
         return null;
 199  
     }
 200  
     
 201  
         @Override
 202  
   public boolean addEdge(E edge, Pair<? extends V> endpoints, EdgeType edgeType) 
 203  
         {
 204  254
                 this.validateEdgeType(edgeType);
 205  252
         Pair<V> new_endpoints = getValidatedEndpoints(edge, endpoints);
 206  248
         if (new_endpoints == null)
 207  8
             return false;
 208  
         
 209  240
         edges.put(edge, new_endpoints);
 210  
         
 211  240
         V source = new_endpoints.getFirst();
 212  240
         V dest = new_endpoints.getSecond();
 213  
 
 214  240
         if (!containsVertex(source))
 215  42
             this.addVertex(source);
 216  
         
 217  240
         if (!containsVertex(dest))
 218  160
             this.addVertex(dest);
 219  
         
 220  240
         getIncoming_internal(dest).add(edge);
 221  240
         getOutgoing_internal(source).add(edge);
 222  
 
 223  240
         return true;
 224  
         }
 225  
 
 226  
     
 227  
     public V getSource(E edge) {
 228  16
         if (!containsEdge(edge))
 229  0
             return null;
 230  16
         return this.getEndpoints(edge).getFirst();
 231  
     }
 232  
 
 233  
     public V getDest(E edge) {
 234  36
         if (!containsEdge(edge))
 235  0
             return null;
 236  36
         return this.getEndpoints(edge).getSecond();
 237  
     }
 238  
 
 239  
     public boolean isSource(V vertex, E edge) {
 240  0
         if (!containsEdge(edge) || !containsVertex(vertex))
 241  0
             return false;
 242  0
         return vertex.equals(this.getEndpoints(edge).getFirst());
 243  
     }
 244  
 
 245  
     public boolean isDest(V vertex, E edge) {
 246  0
         if (!containsEdge(edge) || !containsVertex(vertex))
 247  0
             return false;
 248  0
         return vertex.equals(this.getEndpoints(edge).getSecond());
 249  
     }
 250  
 
 251  
     public Pair<V> getEndpoints(E edge) {
 252  110
         return edges.get(edge);
 253  
     }
 254  
 
 255  
         public int getEdgeCount() {
 256  26
                 return edges.size();
 257  
         }
 258  
 
 259  
         public int getVertexCount() {
 260  34
                 return vertices.size();
 261  
         }
 262  
 }