Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d4298dc
Showing
5 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="src" path="src"/> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> | ||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> | ||
<classpathentry kind="output" path="bin"/> | ||
</classpath> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>Permutation</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
</natures> | ||
</projectDescription> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#Fri Sep 16 18:24:57 IDT 2011 | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 | ||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||
org.eclipse.jdt.core.compiler.compliance=1.6 | ||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | ||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | ||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | ||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||
org.eclipse.jdt.core.compiler.source=1.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package permutations; | ||
|
||
import java.util.Collections; | ||
import java.util.Iterator; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
|
||
public class PermutationGenerator<T> implements Iterator<List<T>>, Iterable<List<T>> { | ||
|
||
private final List<T> permutationObjects; | ||
private final int permutationSize; | ||
private int currentPermutationIndex = -1; //TODO: think about numbering | ||
private final int lastPermutationIndex; | ||
private final List<T> permutation; | ||
|
||
public PermutationGenerator(final List<T> list) { | ||
this.permutationObjects = list; | ||
this.permutationSize = list.size(); | ||
this.lastPermutationIndex = factorial(permutationSize); | ||
permutation = new LinkedList<T>(); | ||
permutation.addAll(list); | ||
} | ||
|
||
public List<T> getPermutation(final int index) { | ||
final PermutationGenerator<T> pg = new PermutationGenerator<T>(permutationObjects); | ||
List<T> permutationByIndex = null; | ||
for (int i=0; i<index; ++i) { | ||
permutationByIndex = pg.next(); | ||
} | ||
return permutationByIndex; | ||
} | ||
|
||
//TODO: replace with fast implementation | ||
public int factorial(final int n) { | ||
return (n == 1) ? 1 : factorial(n-1) * n; | ||
} | ||
|
||
@Override | ||
public boolean hasNext() { | ||
if (currentPermutationIndex < lastPermutationIndex) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public List<T> next() { | ||
currentPermutationIndex++; | ||
if (currentPermutationIndex == 0) { | ||
return permutation; | ||
} | ||
|
||
//Find the largest index k such that a[k] < a[k + 1]. | ||
final int k = findMaxK(); | ||
if (k == -1) { | ||
throw new RuntimeException("Called next when there are no more permutations"); | ||
} | ||
|
||
//Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l. | ||
final int l = findMaxL(k); | ||
|
||
//Swap a[k] with a[l]. | ||
swap(k,l); | ||
|
||
//Reverse the sequence from a[k + 1] up to and including the final element a[n]. | ||
reverseFrom(k+1); | ||
|
||
return permutation; | ||
} | ||
|
||
private List<T> permutationByIndex(int index) | ||
{ | ||
final List<T> permutation = new LinkedList<T>(); | ||
int r = 1, m; | ||
for(int i = 0; i < permutationSize; i++) { | ||
permutation.set(i, permutationObjects.get(i)); | ||
} | ||
|
||
while (r < permutationSize) | ||
{ | ||
m = index%(r+1); | ||
index = index/(r+1); | ||
final T temp = permutation.get(r); | ||
permutation.set(r, permutation.get(m)); | ||
permutation.set(m, temp); | ||
r++; | ||
} | ||
return permutation; | ||
} | ||
|
||
private void reverseFrom(final int i) { | ||
Collections.reverse(permutation.subList(i, permutationSize)); | ||
} | ||
|
||
private void swap(final int k, final int l) { | ||
final T tK = permutation.get(k); | ||
final T tL = permutation.get(l); | ||
permutation.set(l, tK); | ||
permutation.set(k, tL); | ||
} | ||
|
||
//Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l. | ||
private int findMaxL(final int k) { | ||
int l = k+1; | ||
final T tK = permutation.get(k); | ||
for (int i=k+1; i<permutationSize; ++i) { | ||
final T tL= permutation.get(i); | ||
if (permutationObjects.indexOf(tK) < permutationObjects.indexOf(tL)) { | ||
l = i; | ||
} | ||
} | ||
return l; | ||
} | ||
|
||
private int findMaxK() { | ||
int k = -1; | ||
for (int i=0; i<permutationSize-1; ++i) { | ||
final T tK = permutation.get(i); | ||
final T tKNext= permutation.get(i+1); | ||
if (permutationObjects.indexOf(tK) < permutationObjects.indexOf(tKNext)) { | ||
k = i; | ||
} | ||
} | ||
return k; | ||
} | ||
|
||
@Override | ||
public void remove() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
@Override | ||
public Iterator<List<T>> iterator() { | ||
return this; | ||
} | ||
|
||
public List<T> get(final int index) { | ||
return permutationByIndex(index); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* | ||
*/ | ||
package tests; | ||
|
||
import static org.junit.Assert.fail; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import permutations.PermutationGenerator; | ||
|
||
/** | ||
* @author Rachum | ||
* | ||
*/ | ||
public class PermutationGeneratorTest { | ||
|
||
private PermutationGenerator<String> pg; | ||
/** | ||
* @throws java.lang.Exception | ||
*/ | ||
@Before | ||
public void setUp() throws Exception { | ||
pg = new PermutationGenerator<String>(Arrays.asList("a", "b", "c")); | ||
} | ||
|
||
/** | ||
* Test method for {@link permutations.PermutationGenerator#next()}. | ||
*/ | ||
@Test | ||
public void testNext() { | ||
for (final List<String> permutation : pg) { | ||
System.out.println(permutation); | ||
} | ||
System.out.println(pg.get(3)); | ||
fail("Not yet implemented"); // TODO | ||
} | ||
|
||
} |