Added selectRandomSubset() which selects a random subset of elements (with
equal probability) from a collection. git-svn-id: https://samskivert.googlecode.com/svn/trunk@701 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: CollectionUtil.java,v 1.4 2002/03/15 18:05:36 shaper Exp $
|
// $Id: CollectionUtil.java,v 1.5 2002/04/11 04:11:23 mdb Exp $
|
||||||
//
|
//
|
||||||
// samskivert library - useful routines for java programs
|
// samskivert library - useful routines for java programs
|
||||||
// Copyright (C) 2001 Michael Bayne
|
// Copyright (C) 2001 Michael Bayne
|
||||||
@@ -20,9 +20,11 @@
|
|||||||
|
|
||||||
package com.samskivert.util;
|
package com.samskivert.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of collection-related utility functions.
|
* A collection of collection-related utility functions.
|
||||||
@@ -61,6 +63,59 @@ public class CollectionUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list containing a random selection of elements from the
|
||||||
|
* specified collection. The total number of elements selected will be
|
||||||
|
* equal to <code>count</code>, each element in the source collection
|
||||||
|
* will be selected with equal probability and no element will be
|
||||||
|
* included more than once. The elements in the random subset will
|
||||||
|
* always be included in the order they are returned from the source
|
||||||
|
* collection's iterator.
|
||||||
|
*
|
||||||
|
* <p> Algorithm courtesy of William R. Mahoney, published in
|
||||||
|
* <cite>Dr. Dobbs Journal, February 2002</cite>.
|
||||||
|
*
|
||||||
|
* @exception IllegalArgumentException thrown if the size of the
|
||||||
|
* collection is smaller than the number of elements requested for the
|
||||||
|
* random subset.
|
||||||
|
*/
|
||||||
|
public static List selectRandomSubset (Collection col, int count)
|
||||||
|
{
|
||||||
|
int csize = col.size();
|
||||||
|
if (csize < count) {
|
||||||
|
String errmsg = "Cannot select " + count + " elements " +
|
||||||
|
"from a collection of only " + csize + " elements.";
|
||||||
|
throw new IllegalArgumentException(errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList subset = new ArrayList();
|
||||||
|
Iterator iter = col.iterator();
|
||||||
|
int s = 0;
|
||||||
|
|
||||||
|
for (int k = 0; iter.hasNext(); k++) {
|
||||||
|
Object elem = iter.next();
|
||||||
|
|
||||||
|
// the probability that an element is select for inclusion in
|
||||||
|
// our random subset is proportional to the number of elements
|
||||||
|
// remaining to be checked for inclusion divided by the number
|
||||||
|
// of elements remaining to be included
|
||||||
|
float limit = ((float)(count - s)) / ((float)(csize - k));
|
||||||
|
|
||||||
|
// include the record if our random value is below the limit
|
||||||
|
if (Math.random() < limit) {
|
||||||
|
subset.add(elem);
|
||||||
|
|
||||||
|
// stop looking if we've reached our target size
|
||||||
|
if (++s == count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return subset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a collection contains only <code>Integer</code> objects, it can
|
* If a collection contains only <code>Integer</code> objects, it can
|
||||||
* be passed to this function and converted into an int array.
|
* be passed to this function and converted into an int array.
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// $Id: CollectionUtilTest.java,v 1.1 2002/04/11 04:11:23 mdb Exp $
|
||||||
|
|
||||||
|
package com.samskivert.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the {@link CollectionUtil} class.
|
||||||
|
*/
|
||||||
|
public class CollectionUtilTest extends TestCase
|
||||||
|
{
|
||||||
|
public CollectionUtilTest ()
|
||||||
|
{
|
||||||
|
super(CollectionUtil.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runTest ()
|
||||||
|
{
|
||||||
|
ArrayList list = new ArrayList();
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
list.add(new Integer(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
List subset = CollectionUtil.selectRandomSubset(list, 10);
|
||||||
|
// System.out.println(StringUtil.toString(subset));
|
||||||
|
assertTrue("length == 10", subset.size() == 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Test suite ()
|
||||||
|
{
|
||||||
|
return new CollectionUtilTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
CollectionUtilTest test = new CollectionUtilTest();
|
||||||
|
test.runTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user