Skip to content

Commit

Permalink
Delegate to ArraySampler for shuffle
Browse files Browse the repository at this point in the history
  • Loading branch information
aherbert committed Sep 2, 2024
1 parent 61f982c commit 88f7f97
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.commons.rng.sampling;

import java.util.List;
import org.apache.commons.rng.UniformRandomProvider;

/**
Expand Down Expand Up @@ -268,6 +269,34 @@ public static <T> T[] shuffle(UniformRandomProvider rng, T[] array) {
return array;
}

/**
* Shuffles the entries of the given list.
*
* <p>Note: This method is intentionally package-private.
*
* <p>This method exists to allow the shuffle performed by the {@link ListSampler} to
* match the {@link PermutationSampler} and {@link ArraySampler}.
*
* @param <T> Type of the items.
* @param rng Source of randomness.
* @param array Array whose entries will be shuffled (in-place).
*/
static <T> void shuffle(UniformRandomProvider rng, List<T> array) {
int i = array.size();
for (; i > BATCH_2; --i) {
swap(array, i - 1, rng.nextInt(i));
}
// Batches of 2
final int[] productBound = {i * (i - 1)};
for (; i > 1; i -= 2) {
final int[] indices = randomBounded2(i, i - 1, productBound, rng);
final int index1 = indices[0];
final int index2 = indices[1];
swap(array, i - 1, index1);
swap(array, i - 2, index2);
}
}

/**
* Shuffles the entries of the given array in the range {@code [from, to)}.
*
Expand Down Expand Up @@ -629,6 +658,19 @@ private static void swap(Object[] array, int i, int j) {
array[j] = tmp;
}

/**
* Swaps the two specified elements in the list.
*
* @param <T> Type of the list items.
* @param list List.
* @param i First index.
* @param j Second index.
*/
private static <T> void swap(List<T> list, int i, int j) {
final T tmp = list.get(i);
list.set(i, list.get(j));
list.set(j, tmp);
}

/**
* Return two random values in {@code [0, range1)} and {@code [0, range2)}. The
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,11 @@ public static <T> void shuffle(UniformRandomProvider rng,
List<T> list) {
if (list instanceof RandomAccess || list.size() < RANDOM_ACCESS_SIZE_THRESHOLD) {
// Shuffle list in-place
for (int i = list.size(); i > 1; i--) {
swap(list, i - 1, rng.nextInt(i));
}
ArraySampler.shuffle(rng, list);
} else {
// Shuffle as an array
final Object[] array = list.toArray();
for (int i = array.length; i > 1; i--) {
swap(array, i - 1, rng.nextInt(i));
}
ArraySampler.shuffle(rng, array);

// Copy back. Use raw types.
final ListIterator it = list.listIterator();
Expand Down Expand Up @@ -150,31 +146,4 @@ public static <T> void shuffle(UniformRandomProvider rng,
shuffle(rng, list.subList(start, list.size()));
}
}

/**
* Swaps the two specified elements in the list.
*
* @param <T> Type of the list items.
* @param list List.
* @param i First index.
* @param j Second index.
*/
private static <T> void swap(List<T> list, int i, int j) {
final T tmp = list.get(i);
list.set(i, list.get(j));
list.set(j, tmp);
}

/**
* Swaps the two specified elements in the array.
*
* @param array Array.
* @param i First index.
* @param j Second index.
*/
private static void swap(Object[] array, int i, int j) {
final Object tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ private PermutationSampler(UniformRandomProvider rng,

/**
* @return a random permutation.
*
* @see #PermutationSampler(UniformRandomProvider,int,int)
*/
@Override
Expand All @@ -100,14 +99,13 @@ public PermutationSampler withUniformRandomProvider(UniformRandomProvider rng) {
/**
* Shuffles the entries of the given array.
*
* @see #shuffle(UniformRandomProvider,int[],int,boolean)
*
* @param rng Random number generator.
* @param list Array whose entries will be shuffled (in-place).
* @see #shuffle(UniformRandomProvider,int[],int,boolean)
*/
public static void shuffle(UniformRandomProvider rng,
int[] list) {
shuffle(rng, list, list.length - 1, true);
ArraySampler.shuffle(rng, list);
}

/**
Expand All @@ -117,7 +115,7 @@ public static void shuffle(UniformRandomProvider rng,
* The {@code start} and {@code towardHead} parameters select which part
* of the array is randomized and which is left untouched.
*
* <p>Sampling uses {@link UniformRandomProvider#nextInt(int)}.</p>
* <p>Sampling uses {@link UniformRandomProvider#nextInt()}.</p>
*
* @param rng Random number generator.
* @param list Array whose entries will be shuffled (in-place).
Expand All @@ -132,19 +130,10 @@ public static void shuffle(UniformRandomProvider rng,
boolean towardHead) {
if (towardHead) {
// Visit all positions from start to 0.
// Do not visit 0 to avoid a swap with itself.
for (int i = start; i > 0; i--) {
// Swap index with any position down to 0
SubsetSamplerUtils.swap(list, i, rng.nextInt(i + 1));
}
ArraySampler.shuffle(rng, list, 0, start + 1);
} else {
// Visit all positions from the end to start.
// Start is not visited to avoid a swap with itself.
for (int i = list.length - 1; i > start; i--) {
// Swap index with any position down to start.
// Note: i - start + 1 is the number of elements remaining.
SubsetSamplerUtils.swap(list, i, rng.nextInt(i - start + 1) + start);
}
ArraySampler.shuffle(rng, list, start, list.length);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static int[] partialSample(int[] domain,
* @param i the first index
* @param j the second index
*/
static void swap(int[] array, int i, int j) {
private static void swap(int[] array, int i, int j) {
final int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
Expand Down

0 comments on commit 88f7f97

Please sign in to comment.