/** @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 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)); } }
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); }
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); }
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); }
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)); } }
/** @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; }
/** @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); }
/** * 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; }
/** * . * * @return */ public int edgeCount() { return vertexEdges.size(); }
/** * . * * @param e */ public void addEdge(EE e) { vertexEdges.add(e); }
/** * . * * @param e */ public void removeOutgoingEdge(EE e) { outgoing.remove(e); }
/** * . * * @param e */ public void removeIncomingEdge(EE e) { incoming.remove(e); }
public Set<V> vertexSet() { Set<V> res = new HashSet<V>(); res.addAll(g1.vertexSet()); res.addAll(g2.vertexSet()); return Collections.unmodifiableSet(res); }
/** * . * * @param e */ public void addIncomingEdge(EE e) { incoming.add(e); }
public int outDegreeOf(V vertex) { Set<E> res = outgoingEdgesOf(vertex); return res.size(); }
public int inDegreeOf(V vertex) { Set<E> res = incomingEdgesOf(vertex); return res.size(); }
/** * . * * @param e */ public void removeEdge(EE e) { vertexEdges.remove(e); }
/** * . * * @param e */ public void addOutgoingEdge(EE e) { outgoing.add(e); }
public Set<E> edgeSet() { Set<E> res = new HashSet<E>(); res.addAll(g1.edgeSet()); res.addAll(g2.edgeSet()); return Collections.unmodifiableSet(res); }
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; }