Skip to content

Commit

Permalink
The lca package (#597)
Browse files Browse the repository at this point in the history
* Add interface

* Add interface

* Update old implementations

* Add EulerTourRMQLCAFinder and tests for all implementations

* Fix bug with disconnected graphs.

* Add more tests

* Fix Java related issues

* Add support for multiple roots

* Add Heavy Path Decomposition

* Add forest generator

* Add performance tests

* Small fixes

* docs + opt-heavy-path

* Update docs

* Update heavy-path tests

* Refactor heavy-path decomposition

* Fix checkstyle errors

* Fix checkstyle errors

* Fix checkstyle errors

* Update docs

* Update docs

* Merge branch 'master' of https://github.com/jgrapht/jgrapht into lca

# Conflicts:
#	jgrapht-core/src/main/java/org/jgrapht/GraphTests.java
#	jgrapht-core/src/main/java/org/jgrapht/generate/BarabasiAlbertForestGenerator.java
#	jgrapht-core/src/test/java/org/jgrapht/generate/BarabasiAlbertForestGeneratorTest.java

* Fix imports

* Fix imports

* Update docs + tests

* Fix doc

* Add docs and reorganize lca package

* Refactor lca package

* Fix broken javadoc

* Update documentation of BinaryLifting

* Rename interface to LowestCommonAncestorAlgorithm

* Update method names

* Small fixes + documentation update

* Restore vanished tests
  • Loading branch information
AlexandruValeanu authored and d-michail committed Aug 18, 2018
1 parent 8935a18 commit 048bf34
Show file tree
Hide file tree
Showing 19 changed files with 2,361 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
*/
package org.jgrapht.alg;

import org.jgrapht.*;
import org.jgrapht.Graph;
import org.jgrapht.GraphTests;

import java.util.*;

Expand Down Expand Up @@ -61,8 +62,10 @@
*
* @param <V> the graph vertex type
* @param <E> the graph edge type
*
*
* @deprecated Replaced by {@link org.jgrapht.alg.lca.NaiveLCAFinder}
*/
@Deprecated
public class NaiveLcaFinder<V, E>
{
private Graph<V, E> graph;
Expand Down Expand Up @@ -259,4 +262,4 @@ private V overlappingMember(Set<V> x, Set<V> y)
}
}

// End NaiveLcaFinder.java
// End NaiveLCAFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
*/
package org.jgrapht.alg;

import org.jgrapht.*;
import org.jgrapht.alg.util.*;
import org.jgrapht.Graph;
import org.jgrapht.alg.util.UnionFind;

import java.util.*;

Expand All @@ -29,8 +29,10 @@
* @param <E> the graph edge type
*
* @author Leo Crawford
*
* @deprecated Replaced by {@link org.jgrapht.alg.lca.TarjanLCAFinder}
*/
public class TarjanLowestCommonAncestor<V, E>
@Deprecated public class TarjanLowestCommonAncestor<V, E>
{
private Graph<V, E> g;

Expand Down Expand Up @@ -232,4 +234,4 @@ public Set<LcaRequestResponse<V>> getOrCreate(V key)
}
}

// End TarjanLowestCommonAncestor.java
// End TarjanLCAFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
* into a set of disjoint paths.
*
* <p>
* The techniques was first introduced in <i>Sleator, D. D.; Tarjan, R. E. (1983).
* "A Data Structure for Dynamic Trees". Proceedings of the thirteenth annual ACM symposium on Theory of computing
* - STOC '81 doi:10.1145/800076.802464 </i>
* </p>
*
* <p>
* In a heavy path decomposition, the edges set is partitioned into two sets, a set of heavy edges and a
* set of light ones according to the relative number of nodes in the vertex's subtree.
*
Expand Down Expand Up @@ -80,7 +86,7 @@ public class HeavyPathDecomposition<V, E> implements TreeToPathDecompositionAlgo
/**
* Create an instance with a reference to the tree that we will decompose and to the root of the tree.
*
* Note: The constructor will NOT check if the input tree is a valid tree.
* Note: The constructor will NOT check if the input graph is a valid tree.
*
* @param tree the input tree
* @param root the root of the tree
Expand All @@ -94,7 +100,7 @@ public HeavyPathDecomposition(Graph<V, E> tree, V root) {
* forest (one root per tree).
*
* Note: If two roots appear in the same tree, an error will be thrown.
* Note: The constructor will NOT check if the input forest is a valid forest.
* Note: The constructor will NOT check if the input graph is a valid forest.
*
* @param forest the input forest
* @param roots the set of roots of the graph
Expand Down Expand Up @@ -512,5 +518,16 @@ public int[] getPositionInPathArray(){
public int[] getFirstNodeInPathArray(){
return firstNodeInPath;
}

/**
* Return the internal parent array.
* For each vertex $v \in V$, $parentArray[normalizeVertex(v)] = normalizeVertex(u)$ if $getParent(v) = u$ or
* $-1$ if $getParent(v) = null$.
*
* @return internal parent array
*/
public int[] getParentArray(){
return parent;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* (C) Copyright 2018-2018, by Alexandru Valeanu and Contributors.
*
* JGraphT : a free Java graph-theory library
*
* This program and the accompanying materials are dual-licensed under
* either
*
* (a) the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation, or (at your option) any
* later version.
*
* or (per the licensee's choosing)
*
* (b) the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation.
*/
package org.jgrapht.alg.interfaces;

import org.jgrapht.alg.util.Pair;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* Algorithm to compute a <a href="https://en.wikipedia.org/wiki/Lowest_common_ancestor">lowest common ancestor</a>
* in a tree, forest or DAG.
*
* @param <V> vertex the graph vertex type
*
* @author Alexandru Valeanu
*/
public interface LowestCommonAncestorAlgorithm<V> {

/**
* Return the LCA of a and b
*
* @param a the first element to find LCA for
* @param b the other element to find the LCA for
*
* @return the LCA of a and b, or null if there is no LCA.
*/
V getLCA(V a, V b);

/**
* Return a list of LCAs for a batch of queries
*
* @param queries a list of pairs of vertices
* @return a list L of LCAs where L(i) is the LCA for pair queries(i)
*/
default List<V> getBatchLCA(List<Pair<V, V>> queries){
return queries.stream().map(p -> getLCA(p.getFirst(), p.getSecond())).collect(Collectors.toList());
}

/**
* Return the computed set of LCAs of a and b
*
* @param a the first element to find LCA for
* @param b the other element to find the LCA for
*
* @return the set LCAs of a and b, or empty set if there is no LCA computed.
* @throws UnsupportedOperationException - if the operation is not supported by the implementing class
*/
Set<V> getLCASet(V a, V b);

/**
* Return a list of computed sets of LCAs for a batch of queries
*
* @param queries a list of pairs of vertices
* @return a list L of LCAs where L(i) is the computed set of LCAs for pair queries(i)
*/
default List<Set<V>> getBatchLCASet(List<Pair<V, V>> queries){
return queries.stream().map(p -> getLCASet(p.getFirst(), p.getSecond())).collect(Collectors.toList());
}
}
Loading

0 comments on commit 048bf34

Please sign in to comment.