예제 #1
0
  /** Tests Subgraph. */
  public void testSubgraph() {
    UndirectedGraph<String, DefaultEdge> g = init(false);
    UndirectedSubgraph<String, DefaultEdge> sub =
        new UndirectedSubgraph<String, DefaultEdge>(g, null, null);

    assertEquals(g.vertexSet(), sub.vertexSet());
    assertEquals(g.edgeSet(), sub.edgeSet());

    Set<String> vset = new HashSet<String>(g.vertexSet());
    g.removeVertex(v1);
    assertEquals(vset, sub.vertexSet()); // losing track

    g = init(false);
    vset = new HashSet<String>();
    vset.add(v1);
    sub = new UndirectedSubgraph<String, DefaultEdge>(g, vset, null);
    assertEquals(vset, sub.vertexSet());
    assertEquals(0, sub.degreeOf(v1));
    assertEquals(Collections.EMPTY_SET, sub.edgeSet());

    vset.add(v2);
    vset.add(v3);
    sub =
        new UndirectedSubgraph<String, DefaultEdge>(
            g, vset, new HashSet<DefaultEdge>(g.getAllEdges(v1, v2)));
    assertEquals(vset, sub.vertexSet());
    assertEquals(1, sub.edgeSet().size());
  }
예제 #2
0
    /** {@inheritDoc} */
    protected void encounterVertexAgain(V vertex, E edge) {
      super.encounterVertexAgain(vertex, edge);

      int i;

      if (root != null) {
        // For rooted detection, the path must either
        // double back to the root, or to a node of a cycle
        // which has already been detected.
        if (vertex.equals(root)) {
          i = 0;
        } else if ((cycleSet != null) && cycleSet.contains(vertex)) {
          i = 0;
        } else {
          return;
        }
      } else {
        i = path.indexOf(vertex);
      }

      if (i > -1) {
        if (cycleSet == null) {
          // we're doing yes/no cycle detection
          throw new CycleDetectedException();
        } else {
          for (; i < path.size(); ++i) {
            cycleSet.add(path.get(i));
          }
        }
      }
    }
예제 #3
0
  /**
   * @param vertexNumber the number which identifies the vertex v in this order.
   * @return the identifying numbers of all vertices which are connected to v by an edge incoming to
   *     v.
   */
  public int[] getInEdges(int vertexNumber) {
    if (cacheEdges && (incomingEdges[vertexNumber] != null)) {
      return incomingEdges[vertexNumber];
    }

    V v = getVertex(vertexNumber);
    Set<E> edgeSet;

    if (graph instanceof DirectedGraph<?, ?>) {
      edgeSet = ((DirectedGraph<V, E>) graph).incomingEdgesOf(v);
    } else {
      edgeSet = graph.edgesOf(v);
    }

    int[] vertexArray = new int[edgeSet.size()];
    int i = 0;

    for (E edge : edgeSet) {
      V source = graph.getEdgeSource(edge), target = graph.getEdgeTarget(edge);
      vertexArray[i++] = mapVertexToOrder.get(source.equals(v) ? target : source);
    }

    if (cacheEdges) {
      incomingEdges[vertexNumber] = vertexArray;
    }

    return vertexArray;
  }
예제 #4
0
    /** @see Graph#getAllEdges(Object, Object) */
    public Set<E> getAllEdges(V sourceVertex, V targetVertex) {
      Set<E> edges = null;

      if (containsVertex(sourceVertex) && containsVertex(targetVertex)) {
        edges = new ArrayUnenforcedSet<E>();

        Iterator<E> iter = getEdgeContainer(sourceVertex).vertexEdges.iterator();

        while (iter.hasNext()) {
          E e = iter.next();

          boolean equalStraight =
              sourceVertex.equals(getEdgeSource(e)) && targetVertex.equals(getEdgeTarget(e));

          boolean equalInverted =
              sourceVertex.equals(getEdgeTarget(e)) && targetVertex.equals(getEdgeSource(e));

          if (equalStraight || equalInverted) {
            edges.add(e);
          }
        }
      }

      return edges;
    }
  private void init(Graph<V, E> g, Set<V> vertexSet, Set<E> edgeSet) {
    // create a map between vertex value to its order(1st,2nd,etc)
    // "CAT"=1 "DOG"=2 "RHINO"=3

    this.mapVertexToOrder = new HashMap<V, Integer>(vertexSet.size());

    int counter = 0;
    for (V vertex : vertexSet) {
      mapVertexToOrder.put(vertex, new Integer(counter));
      counter++;
    }

    // create a friendlier representation of an edge
    // by order, like 2nd->3rd instead of B->A
    // use the map to convert vertex to order
    // on directed graph, edge A->B must be (A,B)
    // on undirected graph, edge A-B can be (A,B) or (B,A)

    this.labelsEdgesSet = new HashSet<LabelsEdge>(edgeSet.size());
    for (E edge : edgeSet) {
      V sourceVertex = g.getEdgeSource(edge);
      Integer sourceOrder = mapVertexToOrder.get(sourceVertex);
      int sourceLabel = sourceOrder.intValue();
      int targetLabel = (mapVertexToOrder.get(g.getEdgeTarget(edge))).intValue();

      LabelsEdge lablesEdge = new LabelsEdge(sourceLabel, targetLabel);
      this.labelsEdgesSet.add(lablesEdge);

      if (g instanceof UndirectedGraph<?, ?>) {
        LabelsEdge oppositeEdge = new LabelsEdge(targetLabel, sourceLabel);
        this.labelsEdgesSet.add(oppositeEdge);
      }
    }
  }
예제 #6
0
 public Set<String> getIndexedClasses() {
   Set<String> classes = newHashSet();
   Set<JavaClass> vertexSet = graph.vertexSet();
   for (JavaClass each : vertexSet) {
     classes.add(each.getName());
   }
   return classes;
 }
예제 #7
0
 private void markPath(V v, V child, V stem, Set<V> blossom) {
   while (!contracted.get(v).equals(stem)) {
     blossom.add(contracted.get(v));
     blossom.add(contracted.get(match.get(v)));
     path.put(v, child);
     child = match.get(v);
     v = path.get(match.get(v));
   }
 }
예제 #8
0
 public Set<E> getAllEdges(V sourceVertex, V targetVertex) {
   Set<E> res = new HashSet<E>();
   if (g1.containsVertex(sourceVertex) && g1.containsVertex(targetVertex)) {
     res.addAll(g1.getAllEdges(sourceVertex, targetVertex));
   }
   if (g2.containsVertex(sourceVertex) && g2.containsVertex(targetVertex)) {
     res.addAll(g2.getAllEdges(sourceVertex, targetVertex));
   }
   return Collections.unmodifiableSet(res);
 }
예제 #9
0
 public Set<E> edgesOf(V vertex) {
   Set<E> res = new HashSet<E>();
   if (g1.containsVertex(vertex)) {
     res.addAll(g1.edgesOf(vertex));
   }
   if (g2.containsVertex(vertex)) {
     res.addAll(g2.edgesOf(vertex));
   }
   return Collections.unmodifiableSet(res);
 }
 public Set<E> outgoingEdgesOf(V vertex) {
   Set<E> res = new HashSet<E>();
   if (getG1().containsVertex(vertex)) {
     res.addAll(getG1().outgoingEdgesOf(vertex));
   }
   if (getG2().containsVertex(vertex)) {
     res.addAll(getG2().outgoingEdgesOf(vertex));
   }
   return Collections.unmodifiableSet(res);
 }
예제 #11
0
  /** . */
  public void testStronglyConnected3() {
    DirectedGraph<String, DefaultEdge> g =
        new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
    g.addVertex(V1);
    g.addVertex(V2);
    g.addVertex(V3);
    g.addVertex(V4);

    g.addEdge(V1, V2);
    g.addEdge(V2, V3);
    g.addEdge(V3, V1); // strongly connected

    g.addEdge(V1, V4);
    g.addEdge(V2, V4);
    g.addEdge(V3, V4); // weakly connected

    StrongConnectivityInspector<String, DefaultEdge> inspector =
        new StrongConnectivityInspector<String, DefaultEdge>(g);

    // convert from List to Set because we need to ignore order
    // during comparison
    Set<Set<String>> actualSets = new HashSet<Set<String>>(inspector.stronglyConnectedSets());

    // construct the expected answer
    Set<Set<String>> expectedSets = new HashSet<Set<String>>();
    Set<String> set = new HashSet<String>();
    set.add(V1);
    set.add(V2);
    set.add(V3);
    expectedSets.add(set);
    set = new HashSet<String>();
    set.add(V4);
    expectedSets.add(set);

    assertEquals(expectedSets, actualSets);

    actualSets.clear();

    List<DirectedSubgraph<String, DefaultEdge>> subgraphs = inspector.stronglyConnectedSubgraphs();

    for (DirectedSubgraph<String, DefaultEdge> sg : subgraphs) {
      actualSets.add(sg.vertexSet());

      StrongConnectivityInspector<String, DefaultEdge> ci =
          new StrongConnectivityInspector<String, DefaultEdge>(sg);
      assertTrue(ci.isStronglyConnected());
    }

    assertEquals(expectedSets, actualSets);
  }
예제 #12
0
  /** . */
  public void testSubgraphListener() {
    UndirectedGraph<String, DefaultEdge> g = init(true);
    UndirectedSubgraph<String, DefaultEdge> sub =
        new UndirectedSubgraph<String, DefaultEdge>(g, null, null);

    assertEquals(g.vertexSet(), sub.vertexSet());
    assertEquals(g.edgeSet(), sub.edgeSet());

    Set<String> vset = new HashSet<String>(g.vertexSet());
    g.removeVertex(v1);
    vset.remove(v1);
    assertEquals(vset, sub.vertexSet()); // not losing track
    assertEquals(g.edgeSet(), sub.edgeSet());
  }
예제 #13
0
 private void findParents(JavaClass jclass, Set<JavaClass> changedParents) {
   for (JavaClass parent : getParents(jclass)) {
     if (changedParents.add(parent)) {
       findParents(parent, changedParents);
     }
   }
 }
  /*
   * The subroutine of DFS. NOTE: the set is used to distinguish between 1st
   * and 2nd round of DFS. set == null: finished vertices are stored (1st
   * round). set != null: all vertices found will be saved in the set (2nd
   * round)
   */
  private void dfsVisit(
      DirectedGraph<V, E> visitedGraph, VertexData<V> vertexData, Set<V> vertices) {
    Deque<VertexData<V>> stack = new ArrayDeque<VertexData<V>>();
    stack.add(vertexData);

    while (!stack.isEmpty()) {
      VertexData<V> data = stack.removeLast();

      if (!data.isDiscovered()) {
        data.setDiscovered(true);

        if (vertices != null) {
          vertices.add(data.getVertex());
        }

        stack.add(new VertexData1<V>(data, true, true));

        // follow all edges
        for (E edge : visitedGraph.outgoingEdgesOf(data.getVertex())) {
          VertexData<V> targetData = vertexToVertexData.get(visitedGraph.getEdgeTarget(edge));

          if (!targetData.isDiscovered()) {
            // the "recursion"
            stack.add(targetData);
          }
        }
      } else if (data.isFinished()) {
        if (vertices == null) {
          orderedVertices.addFirst(data.getFinishedData());
        }
      }
    }
  }
예제 #15
0
 private V lowestCommonAncestor(V a, V b) {
   Set<V> seen = new HashSet<>();
   for (; ; ) {
     a = contracted.get(a);
     seen.add(a);
     if (!match.containsKey(a)) {
       break;
     }
     a = path.get(match.get(a));
   }
   for (; ; ) {
     b = contracted.get(b);
     if (seen.contains(b)) {
       return b;
     }
     b = path.get(match.get(b));
   }
 }
예제 #16
0
    /** @see Graph#getAllEdges(Object, Object) */
    public Set<E> getAllEdges(V sourceVertex, V targetVertex) {
      Set<E> edges = null;

      if (containsVertex(sourceVertex) && containsVertex(targetVertex)) {
        edges = new ArrayUnenforcedSet<E>();

        DirectedEdgeContainer<V, E> ec = getEdgeContainer(sourceVertex);

        Iterator<E> iter = ec.outgoing.iterator();

        while (iter.hasNext()) {
          E e = iter.next();

          if (getEdgeTarget(e).equals(targetVertex)) {
            edges.add(e);
          }
        }
      }

      return edges;
    }
예제 #17
0
  /**
   * Finds the vertex set for the subgraph of all cycles.
   *
   * @return set of all vertices which participate in at least one cycle in this graph
   */
  public Set<V> findCycles() {
    // ProbeIterator can't be used to handle this case,
    // so use StrongConnectivityInspector instead.
    StrongConnectivityInspector<V, E> inspector = new StrongConnectivityInspector<V, E>(graph);
    List<Set<V>> components = inspector.stronglyConnectedSets();

    // A vertex participates in a cycle if either of the following is
    // true:  (a) it is in a component whose size is greater than 1
    // or (b) it is a self-loop

    Set<V> set = new HashSet<V>();
    for (Set<V> component : components) {
      if (component.size() > 1) {
        // cycle
        set.addAll(component);
      } else {
        V v = component.iterator().next();
        if (graph.containsEdge(v, v)) {
          // self-loop
          set.add(v);
        }
      }
    }

    return set;
  }
예제 #18
0
    /** @see Graph#edgesOf(Object) */
    public Set<E> edgesOf(V vertex) {
      ArrayUnenforcedSet<E> inAndOut = new ArrayUnenforcedSet<E>(getEdgeContainer(vertex).incoming);
      inAndOut.addAll(getEdgeContainer(vertex).outgoing);

      // we have two copies for each self-loop - remove one of them.
      if (allowingLoops) {
        Set<E> loops = getAllEdges(vertex, vertex);

        for (int i = 0; i < inAndOut.size(); ) {
          Object e = inAndOut.get(i);

          if (loops.contains(e)) {
            inAndOut.remove(i);
            loops.remove(e); // so we remove it only once
          } else {
            i++;
          }
        }
      }

      return Collections.unmodifiableSet(inAndOut);
    }
예제 #19
0
  public Set<JavaClass> findClasses(Collection<File> changedFiles) {
    // First update class index
    List<String> changedClassesNames = new ArrayList<String>();
    for (File changedFile : changedFiles) {
      String changedClassname = builder.classFileChanged(changedFile);
      if (changedClassname != null) {
        changedClassesNames.add(changedClassname);
      }
    }

    // Then find dependencies
    Set<JavaClass> changedClasses = newHashSet();
    for (String changedClassesName : changedClassesNames) {
      JavaClass javaClass = builder.getClass(changedClassesName);
      if (javaClass != null) {
        addToIndex(javaClass);
        changedClasses.add(javaClass);
      }
    }
    builder.clear();
    return changedClasses;
  }
예제 #20
0
  /**
   * Updates outgoing vertices of the vertex. For each outgoing vertex, the new paths are obtained
   * by concatenating the specified edge to the calculated paths of the specified vertex. If the
   * weight of a new path is greater than the weight of any path stored so far at the outgoing
   * vertex then the path is not added, otherwise it is added to the list of paths in increasing
   * order of weight. Complexity =
   *
   * <ul>
   *   <li>O(<code>d(v)*k*(m+n)</code>) where <code>d(v)</code> is the outgoing degree of the
   *       specified vertex, <code>k</code> is the maximum number of shortest paths to compute,
   *       <code>m</code> is the number of edges of the graph and <code>n</code> is the number of
   *       vertices of the graph
   * </ul>
   *
   * @param vertex
   * @param improvedVertices
   */
  private void updateOutgoingVertices(V vertex, Set<V> improvedVertices) {
    // try to add new paths for the target vertices of the outgoing edges
    // of the vertex in argument.
    for (Iterator<E> iter = edgesOfIterator(vertex); iter.hasNext(); ) {
      E edge = iter.next();
      V vertexReachedByEdge = Graphs.getOppositeVertex(this.graph, edge, vertex);

      // check if the path does not loop over the start vertex.
      if (!vertexReachedByEdge.equals(this.startVertex)) {
        if (this.seenDataContainer.containsKey(vertexReachedByEdge)) {
          boolean relaxed = tryToAddNewPaths(vertexReachedByEdge, edge);
          if (relaxed) {
            improvedVertices.add(vertexReachedByEdge);
          }
        } else {
          boolean relaxed = tryToAddFirstPaths(vertexReachedByEdge, edge);
          if (relaxed) {
            improvedVertices.add(vertexReachedByEdge);
          }
        }
      }
    }
  }
  /**
   * Compute the unique decomposition of the input graph G (atoms of G). Implementation of algorithm
   * Atoms as described in Berry et al. (2010), DOI:10.3390/a3020197, <a
   * href="http://www.mdpi.com/1999-4893/3/2/197">http://www.mdpi.com/1999-4893/3/2/197</a>
   */
  private void computeAtoms() {
    if (chordalGraph == null) {
      computeMinimalTriangulation();
    }

    separators = new HashSet<>();

    // initialize g' as subgraph of graph (same vertices and edges)
    UndirectedGraph<V, E> gprime = copyAsSimpleGraph(graph);

    // initialize h' as subgraph of chordalGraph (same vertices and edges)
    UndirectedGraph<V, E> hprime = copyAsSimpleGraph(chordalGraph);

    atoms = new HashSet<>();

    Iterator<V> iterator = meo.descendingIterator();
    while (iterator.hasNext()) {
      V v = iterator.next();
      if (generators.contains(v)) {
        Set<V> separator = new HashSet<>(Graphs.neighborListOf(hprime, v));

        if (isClique(graph, separator)) {
          if (separator.size() > 0) {
            if (separators.contains(separator)) {
              fullComponentCount.put(separator, fullComponentCount.get(separator) + 1);
            } else {
              fullComponentCount.put(separator, 2);
              separators.add(separator);
            }
          }
          UndirectedGraph<V, E> tmpGraph = copyAsSimpleGraph(gprime);

          tmpGraph.removeAllVertices(separator);
          ConnectivityInspector<V, E> con = new ConnectivityInspector<>(tmpGraph);
          if (con.isGraphConnected()) {
            throw new RuntimeException("separator did not separate the graph");
          }
          for (Set<V> component : con.connectedSets()) {
            if (component.contains(v)) {
              gprime.removeAllVertices(component);
              component.addAll(separator);
              atoms.add(new HashSet<>(component));
              assert (component.size() > 0);
              break;
            }
          }
        }
      }

      hprime.removeVertex(v);
    }

    if (gprime.vertexSet().size() > 0) {
      atoms.add(new HashSet<>(gprime.vertexSet()));
    }
  }
예제 #22
0
  /**
   * Runs the algorithm on the input graph and returns the match edge set.
   *
   * @return set of Edges
   */
  private Set<E> findMatch() {
    Set<E> result = new ArrayUnenforcedSet<>();
    match = new HashMap<>();
    path = new HashMap<>();
    contracted = new HashMap<>();

    for (V i : graph.vertexSet()) {
      // Any augmenting path should start with _exposed_ vertex
      // (vertex may not escape match-set being added once)
      if (!match.containsKey(i)) {
        // Match is maximal iff graph G contains no more augmenting paths
        V v = findPath(i);
        while (v != null) {
          V pv = path.get(v);
          V ppv = match.get(pv);
          match.put(v, pv);
          match.put(pv, v);
          v = ppv;
        }
      }
    }

    Set<V> seen = new HashSet<>();
    graph
        .vertexSet()
        .stream()
        .filter(v -> !seen.contains(v) && match.containsKey(v))
        .forEach(
            v -> {
              seen.add(v);
              seen.add(match.get(v));
              result.add(graph.getEdge(v, match.get(v)));
            });

    return result;
  }
 public int outDegreeOf(V vertex) {
   Set<E> res = outgoingEdgesOf(vertex);
   return res.size();
 }
예제 #24
0
 /**
  * .
  *
  * @param e
  */
 public void addIncomingEdge(EE e) {
   incoming.add(e);
 }
예제 #25
0
 /**
  * .
  *
  * @param e
  */
 public void removeEdge(EE e) {
   vertexEdges.remove(e);
 }
예제 #26
0
 /**
  * .
  *
  * @return
  */
 public int edgeCount() {
   return vertexEdges.size();
 }
예제 #27
0
 /**
  * .
  *
  * @param e
  */
 public void addEdge(EE e) {
   vertexEdges.add(e);
 }
예제 #28
0
 /**
  * .
  *
  * @param e
  */
 public void addOutgoingEdge(EE e) {
   outgoing.add(e);
 }
예제 #29
0
 /**
  * .
  *
  * @param e
  */
 public void removeOutgoingEdge(EE e) {
   outgoing.remove(e);
 }
예제 #30
0
 /**
  * .
  *
  * @param e
  */
 public void removeIncomingEdge(EE e) {
   incoming.remove(e);
 }