rectest/scripts/set/RandomAllInclusiveSet.js

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 );
}
} );