175 lines
5.6 KiB
JavaScript
175 lines
5.6 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
exports.createPickRandom = void 0;
|
||
|
|
||
|
var _array = require("../../utils/array.js");
|
||
|
|
||
|
var _factory = require("../../utils/factory.js");
|
||
|
|
||
|
var _is = require("../../utils/is.js");
|
||
|
|
||
|
var _seededRNG = require("./util/seededRNG.js");
|
||
|
|
||
|
var name = 'pickRandom';
|
||
|
var dependencies = ['typed', 'config', '?on'];
|
||
|
var createPickRandom = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
|
||
|
var typed = _ref.typed,
|
||
|
config = _ref.config,
|
||
|
on = _ref.on;
|
||
|
// seeded pseudo random number generator
|
||
|
var rng = (0, _seededRNG.createRng)(config.randomSeed);
|
||
|
|
||
|
if (on) {
|
||
|
on('config', function (curr, prev) {
|
||
|
if (curr.randomSeed !== prev.randomSeed) {
|
||
|
rng = (0, _seededRNG.createRng)(curr.randomSeed);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
/**
|
||
|
* Random pick one or more values from a one dimensional array.
|
||
|
* Array elements are picked using a random function with uniform or weighted distribution.
|
||
|
*
|
||
|
* Syntax:
|
||
|
*
|
||
|
* math.pickRandom(array)
|
||
|
* math.pickRandom(array, number)
|
||
|
* math.pickRandom(array, weights)
|
||
|
* math.pickRandom(array, number, weights)
|
||
|
* math.pickRandom(array, weights, number)
|
||
|
* math.pickRandom(array, { weights, number, elementWise })
|
||
|
*
|
||
|
* Examples:
|
||
|
*
|
||
|
* math.pickRandom([3, 6, 12, 2]) // returns one of the values in the array
|
||
|
* math.pickRandom([3, 6, 12, 2], 2) // returns an array of two of the values in the array
|
||
|
* math.pickRandom([3, 6, 12, 2], { number: 2 }) // returns an array of two of the values in the array
|
||
|
* math.pickRandom([3, 6, 12, 2], [1, 3, 2, 1]) // returns one of the values in the array with weighted distribution
|
||
|
* math.pickRandom([3, 6, 12, 2], 2, [1, 3, 2, 1]) // returns an array of two of the values in the array with weighted distribution
|
||
|
* math.pickRandom([3, 6, 12, 2], [1, 3, 2, 1], 2) // returns an array of two of the values in the array with weighted distribution
|
||
|
*
|
||
|
* math.pickRandom([{x: 1.0, y: 2.0}, {x: 1.1, y: 2.0}], { elementWise: false })
|
||
|
* // returns one of the items in the array
|
||
|
*
|
||
|
* See also:
|
||
|
*
|
||
|
* random, randomInt
|
||
|
*
|
||
|
* @param {Array | Matrix} array A one dimensional array
|
||
|
* @param {Int} number An int or float
|
||
|
* @param {Array | Matrix} weights An array of ints or floats
|
||
|
* @return {number | Array} Returns a single random value from array when number is 1 or undefined.
|
||
|
* Returns an array with the configured number of elements when number is > 1.
|
||
|
*/
|
||
|
|
||
|
|
||
|
return typed(name, {
|
||
|
'Array | Matrix': function ArrayMatrix(possibles) {
|
||
|
return _pickRandom(possibles, {});
|
||
|
},
|
||
|
'Array | Matrix, Object': function ArrayMatrixObject(possibles, options) {
|
||
|
return _pickRandom(possibles, options);
|
||
|
},
|
||
|
'Array | Matrix, number': function ArrayMatrixNumber(possibles, number) {
|
||
|
return _pickRandom(possibles, {
|
||
|
number: number
|
||
|
});
|
||
|
},
|
||
|
'Array | Matrix, Array | Matrix': function ArrayMatrixArrayMatrix(possibles, weights) {
|
||
|
return _pickRandom(possibles, {
|
||
|
weights: weights
|
||
|
});
|
||
|
},
|
||
|
'Array | Matrix, Array | Matrix, number': function ArrayMatrixArrayMatrixNumber(possibles, weights, number) {
|
||
|
return _pickRandom(possibles, {
|
||
|
number: number,
|
||
|
weights: weights
|
||
|
});
|
||
|
},
|
||
|
'Array | Matrix, number, Array | Matrix': function ArrayMatrixNumberArrayMatrix(possibles, number, weights) {
|
||
|
return _pickRandom(possibles, {
|
||
|
number: number,
|
||
|
weights: weights
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
/**
|
||
|
* @param {Array | Matrix} possibles
|
||
|
* @param {{
|
||
|
* number?: number,
|
||
|
* weights?: Array | Matrix,
|
||
|
* elementWise: boolean
|
||
|
* }} options
|
||
|
* @returns {number | Array}
|
||
|
* @private
|
||
|
*/
|
||
|
|
||
|
function _pickRandom(possibles, _ref2) {
|
||
|
var number = _ref2.number,
|
||
|
weights = _ref2.weights,
|
||
|
_ref2$elementWise = _ref2.elementWise,
|
||
|
elementWise = _ref2$elementWise === void 0 ? true : _ref2$elementWise;
|
||
|
var single = typeof number === 'undefined';
|
||
|
|
||
|
if (single) {
|
||
|
number = 1;
|
||
|
}
|
||
|
|
||
|
var createMatrix = (0, _is.isMatrix)(possibles) ? possibles.create : (0, _is.isMatrix)(weights) ? weights.create : null;
|
||
|
possibles = possibles.valueOf(); // get Array
|
||
|
|
||
|
if (weights) {
|
||
|
weights = weights.valueOf(); // get Array
|
||
|
}
|
||
|
|
||
|
if (elementWise === true) {
|
||
|
possibles = (0, _array.flatten)(possibles);
|
||
|
weights = (0, _array.flatten)(weights);
|
||
|
}
|
||
|
|
||
|
var totalWeights = 0;
|
||
|
|
||
|
if (typeof weights !== 'undefined') {
|
||
|
if (weights.length !== possibles.length) {
|
||
|
throw new Error('Weights must have the same length as possibles');
|
||
|
}
|
||
|
|
||
|
for (var i = 0, len = weights.length; i < len; i++) {
|
||
|
if (!(0, _is.isNumber)(weights[i]) || weights[i] < 0) {
|
||
|
throw new Error('Weights must be an array of positive numbers');
|
||
|
}
|
||
|
|
||
|
totalWeights += weights[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var length = possibles.length;
|
||
|
var result = [];
|
||
|
var pick;
|
||
|
|
||
|
while (result.length < number) {
|
||
|
if (typeof weights === 'undefined') {
|
||
|
pick = possibles[Math.floor(rng() * length)];
|
||
|
} else {
|
||
|
var randKey = rng() * totalWeights;
|
||
|
|
||
|
for (var _i = 0, _len = possibles.length; _i < _len; _i++) {
|
||
|
randKey -= weights[_i];
|
||
|
|
||
|
if (randKey < 0) {
|
||
|
pick = possibles[_i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
result.push(pick);
|
||
|
}
|
||
|
|
||
|
return single ? result[0] : createMatrix ? createMatrix(result) : result;
|
||
|
}
|
||
|
});
|
||
|
exports.createPickRandom = createPickRandom;
|