85 lines
2.5 KiB
JavaScript
85 lines
2.5 KiB
JavaScript
/**
|
|
* Represents a set that randomizes all elements of an entire predicted set,
|
|
* ensuring that repeat sets are less predictable.
|
|
*
|
|
* This algorithm works by first repeating the given set S the necessary number
|
|
* of times in order to produce a new set S' that contains at least one element
|
|
* for the requested sample size. S' is then randomized in its entirety.
|
|
*
|
|
* See also RandomGroupedSet.
|
|
*/
|
|
rectest.set.RandomAllInclusiveSet = Class( 'RandomAllInclusiveSet' )
|
|
.extend( rectest.set.RandomGroupedSet,
|
|
{
|
|
/**
|
|
* Randomizes an entire set large enough to encompass the requested sample
|
|
* size
|
|
*
|
|
* The actual array randomization algorithm is inherited from the parent.
|
|
*
|
|
* @param {Array} set set to randomize
|
|
*
|
|
* @return {Array} randomized set
|
|
*/
|
|
'override protected randomizeSet': function( set )
|
|
{
|
|
var samples = this.getSampleSize();
|
|
|
|
// this algorithm will work only if we know how many samples are desired
|
|
if ( samples < 1 )
|
|
{
|
|
throw Error(
|
|
"RandomAllInclusiveSet can only be used with sets of " +
|
|
"known length; desired sample size is unknown"
|
|
);
|
|
}
|
|
|
|
// nothing we can do with an empty set (avoid the division by 0 and just
|
|
// bail out)
|
|
if ( set.length === 0 )
|
|
{
|
|
return set;
|
|
}
|
|
|
|
// call the super method with the set repeated N times, where N is the
|
|
// minimum number of repeats required to satisfy the requested sample
|
|
// size (may result in a set larger than the sample size, but that is
|
|
// fine)
|
|
return this.__super( this._repeatSet( set,
|
|
Math.ceil( samples / set.length )
|
|
) );
|
|
},
|
|
|
|
|
|
/**
|
|
* Recursively repeats the given set n times
|
|
*
|
|
* @param {Array} set set to repeat
|
|
* @param {number} n number of times to repeat
|
|
* @param {=Array} s2 destination array (defaults to [] on first iteration)
|
|
*
|
|
* @return {Array} s2 after operation is complete
|
|
*/
|
|
'private _repeatSet': function( set, n, s2 )
|
|
{
|
|
s2 = s2 || [];
|
|
n = ( isNaN( n ) ) ? 0 : n; // failsafe
|
|
|
|
var i = set.length;
|
|
|
|
if ( n === 0 )
|
|
{
|
|
return s2;
|
|
}
|
|
|
|
// does not matter that we're doing it in reverse, since the set
|
|
// will be randomized later
|
|
while ( i-- )
|
|
{
|
|
s2.push( set[ i ] );
|
|
}
|
|
|
|
return this._repeatSet( set, --n, s2 );
|
|
}
|
|
} );
|