diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/PermutationGroup.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/PermutationGroup.java index 733cd204eb..6c4769a411 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/PermutationGroup.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/PermutationGroup.java @@ -22,7 +22,9 @@ package org.biojava.nbio.structure.symmetry.core; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * @@ -47,24 +49,36 @@ public int getOrder() { /** + * Starts with an incomplete set of group generators in `permutations` and + * expands it to include all possible combinations. + * * Ways to complete group: * - combinations of permutations pi x pj * - combinations with itself p^k * */ public void completeGroup() { - int n = permutations.size(); - for (int i = 0; i < permutations.size(); i++) { - for (int j = i; j < permutations.size(); j++) { - List p = combine(permutations.get(i), permutations.get(j)); - addPermutation(p); -// System.out.println("complete group: adding " + p); - } - } - // repeat iteratively until no new permutation are created - if (permutations.size() > n) { - completeGroup(); - } + // Copy initial set to allow permutations to grow + List> gens = new ArrayList>(permutations); + // Keep HashSet version of permutations for fast lookup. + Set> known = new HashSet>(permutations); + //breadth-first search through the map of all members + List> currentLevel = new ArrayList>(permutations); + while( currentLevel.size() > 0) { + List> nextLevel = new ArrayList>(); + for( List p : currentLevel) { + for(List gen : gens) { + List y = combine(p,gen); + if(!known.contains(y)) { + nextLevel.add(y); + //bypass addPermutation(y) for performance + permutations.add(y); + known.add(y); + } + } + } + currentLevel = nextLevel; + } } public String toString() {