Skip to content

Instantly share code, notes, and snippets.

@thers
Last active December 4, 2015 11:35
Show Gist options
  • Save thers/2fab504e992cb1df3fd9 to your computer and use it in GitHub Desktop.
Save thers/2fab504e992cb1df3fd9 to your computer and use it in GitHub Desktop.

Revisions

  1. thers revised this gist Dec 4, 2015. 1 changed file with 3 additions and 5 deletions.
    8 changes: 3 additions & 5 deletions BiasedRandom.js
    Original file line number Diff line number Diff line change
    @@ -56,11 +56,9 @@ export default class BiasedRandom {
    if (r > this.bounds[i][0] && r <= this.bounds[i][1]) {
    const v = boundrand(...this.probs[i].r);

    if (this.filter) {
    return this.filter(v);
    } else {
    return v;
    }
    return (this.filter
    ? this.filter(v)
    : v);
    }
    }
    }
  2. thers revised this gist Dec 4, 2015. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions BiasedRandom.js
    Original file line number Diff line number Diff line change
    @@ -21,9 +21,7 @@ export default class BiasedRandom {
    * @param filter
    */
    constructor (probabilities, filter = false) {
    this.probs = probabilities.sort((c, n) => {
    return c.p > n.p;
    });
    this.probs = probabilities.sort((c, n) => c.p > n.p);
    this.filter = filter;

    if (!this._checkProbs()) {
    @@ -56,7 +54,7 @@ export default class BiasedRandom {

    for (let i = 0; i < this.probs.length; i++) {
    if (r > this.bounds[i][0] && r <= this.bounds[i][1]) {
    const v = boundrand.apply(boundrand, this.probs[i].r);
    const v = boundrand(...this.probs[i].r);

    if (this.filter) {
    return this.filter(v);
  3. thers created this gist Dec 4, 2015.
    69 changes: 69 additions & 0 deletions BiasedRandom.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    function boundrand (min, max) {
    return min + (Math.random() * (max - min));
    }

    export default class BiasedRandom {

    /**
    * Ctor
    *
    * @example
    * // p means probability of this variant, r is for range of values generated
    * const probabilities = [ {p: 0.8, r: [1,5]}, {p: 0.2, r: [20,25]} ];
    * // v => v|0 is a filter for each generated value, example one is equal to Math.floor(v)
    * const weightGenerator = new BiasedRandom(probabilities, v => v|0);
    *
    * const weight = weightGenerator.generate();
    * // With a 80% probability weight will be between 1 and 5
    * // With a 20% probability weight will be between 20 and 25
    *
    * @param {Object[]} probabilities
    * @param filter
    */
    constructor (probabilities, filter = false) {
    this.probs = probabilities.sort((c, n) => {
    return c.p > n.p;
    });
    this.filter = filter;

    if (!this._checkProbs()) {
    throw new Error('Sum of probabilities cannot be more than 1');
    }

    this.bounds = [];

    let bottomBound = 0;

    for (let i = 0; i < this.probs.length; i++) {
    const entry = this.probs[i];

    this.bounds.push([bottomBound, bottomBound + entry.p]);
    bottomBound = entry.p;
    }
    }

    _checkProbs () {
    return this.probs.reduce((acc,n)=>acc+=n.p,0) === 1;
    }

    /**
    * Generates value
    *
    * @returns {*}
    */
    generate () {
    const r = Math.random();

    for (let i = 0; i < this.probs.length; i++) {
    if (r > this.bounds[i][0] && r <= this.bounds[i][1]) {
    const v = boundrand.apply(boundrand, this.probs[i].r);

    if (this.filter) {
    return this.filter(v);
    } else {
    return v;
    }
    }
    }
    }
    }