Пример #1
0
  public void union(AbstractBaseGraph<V, E> g2) {
    if (!(this instanceof DirectedGraph<?, ?> && g2 instanceof DirectedGraph<?, ?>)) {
      return;
    }
    Set<V> vertexSet = g2.vertexSet();
    for (V vertex : vertexSet) {
      if (!containsVertex(vertex)) addVertex(vertex);
    }

    for (V vertex : vertexSet) {
      Set<E> edgeSet = g2.specifics.outgoingEdgesOf(vertex);
      for (E edge : edgeSet) {
        V sourceVertex = getEdgeSource(edge);
        V targetVertex = getEdgeTarget(edge);
        if (!allowingMultipleEdges && containsEdge(sourceVertex, targetVertex)) {
          continue;
        }

        if (!allowingLoops && sourceVertex.equals(targetVertex)) {
          continue;
        }

        if (containsEdge(edge)) {
          continue;
        } else {
          IntrusiveEdge intrusiveEdge = createIntrusiveEdge(edge, sourceVertex, targetVertex);

          edgeMap.put(edge, intrusiveEdge);
          specifics.addEdgeToTouchingVertices(edge);
        }
      }
    }
  }
Пример #2
0
  /** @see Graph#addEdge(Object, Object, Object) */
  public boolean addEdge(V sourceVertex, V targetVertex, E e) {
    if (e == null) {
      throw new NullPointerException();
    } else if (containsEdge(e)) {
      return false;
    }

    assertVertexExist(sourceVertex);
    assertVertexExist(targetVertex);

    if (!allowingMultipleEdges && containsEdge(sourceVertex, targetVertex)) {
      return false;
    }

    if (!allowingLoops && sourceVertex.equals(targetVertex)) {
      throw new IllegalArgumentException(LOOPS_NOT_ALLOWED);
    }

    IntrusiveEdge intrusiveEdge = createIntrusiveEdge(e, sourceVertex, targetVertex);

    edgeMap.put(e, intrusiveEdge);
    specifics.addEdgeToTouchingVertices(e);

    return true;
  }
Пример #3
0
  /** @see Graph#edgeSet() */
  public Set<E> edgeSet() {
    if (unmodifiableEdgeSet == null) {
      unmodifiableEdgeSet = Collections.unmodifiableSet(edgeMap.keySet());
    }

    return unmodifiableEdgeSet;
  }
Пример #4
0
  /** @see Graph#addEdge(Object, Object) */
  public E addEdge(V sourceVertex, V targetVertex) {
    assertVertexExist(sourceVertex);
    assertVertexExist(targetVertex);

    if (!allowingMultipleEdges && containsEdge(sourceVertex, targetVertex)) {
      return null;
    }

    if (!allowingLoops && sourceVertex.equals(targetVertex)) {
      throw new IllegalArgumentException(LOOPS_NOT_ALLOWED);
    }

    E e = edgeFactory.createEdge(sourceVertex, targetVertex);

    if (containsEdge(e)) { // this restriction should stay!

      return null;
    } else {
      IntrusiveEdge intrusiveEdge = createIntrusiveEdge(e, sourceVertex, targetVertex);

      edgeMap.put(e, intrusiveEdge);
      specifics.addEdgeToTouchingVertices(e);

      return e;
    }
  }
Пример #5
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));
   }
 }
Пример #6
0
  /** @see Graph#removeEdge(Object) */
  public boolean removeEdge(E e) {
    if (containsEdge(e)) {
      specifics.removeEdgeFromTouchingVertices(e);
      edgeMap.remove(e);

      return true;
    } else {
      return false;
    }
  }
Пример #7
0
  /** @see Graph#removeEdge(Object, Object) */
  public E removeEdge(V sourceVertex, V targetVertex) {
    E e = getEdge(sourceVertex, targetVertex);

    if (e != null) {
      specifics.removeEdgeFromTouchingVertices(e);
      edgeMap.remove(e);
    }

    return e;
  }
Пример #8
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));
   }
 }
Пример #9
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;
  }
Пример #10
0
 /** @see Graph#containsEdge(Object) */
 public boolean containsEdge(E e) {
   return edgeMap.containsKey(e);
 }
Пример #11
0
 private IntrusiveEdge getIntrusiveEdge(E e) {
   if (e instanceof IntrusiveEdge) {
     return (IntrusiveEdge) e;
   }
   return edgeMap.get(e);
 }
Пример #12
0
  private V findPath(V root) {
    Set<V> used = new HashSet<>();
    Queue<V> q = new ArrayDeque<>();

    // Expand graph back from its contracted state
    path.clear();
    contracted.clear();

    graph.vertexSet().forEach(vertex -> contracted.put(vertex, vertex));

    used.add(root);
    q.add(root);

    while (!q.isEmpty()) {
      V v = q.remove();

      for (E e : graph.edgesOf(v)) {
        V to = graph.getEdgeSource(e);

        if (to.equals(v)) {
          to = graph.getEdgeTarget(e);
        }

        if ((contracted.get(v).equals(contracted.get(to))) || to.equals(match.get(v))) {
          continue;
        }

        // Check whether we've hit a 'blossom'
        if ((to.equals(root)) || ((match.containsKey(to)) && (path.containsKey(match.get(to))))) {
          V stem = lowestCommonAncestor(v, to);

          Set<V> blossom = new HashSet<>();

          markPath(v, to, stem, blossom);
          markPath(to, v, stem, blossom);

          graph
              .vertexSet()
              .stream()
              .filter(i -> contracted.containsKey(i) && blossom.contains(contracted.get(i)))
              .forEach(
                  i -> {
                    contracted.put(i, stem);
                    if (!used.contains(i)) {
                      used.add(i);
                      q.add(i);
                    }
                  });

          // Check whether we've had hit a loop (of even length (!) presumably)
        } else if (!path.containsKey(to)) {
          path.put(to, v);

          if (!match.containsKey(to)) {
            return to;
          }

          to = match.get(to);

          used.add(to);
          q.add(to);
        }
      }
    }
    return null;
  }