Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class TrafficSplit{
- constructor(spec, volume){
- this.seed = (spec) => {
- let results = {};
- for(let i in spec) results[Object.keys(spec)[i]] = 0;
- return results;
- }
- this.weights = spec;
- this.results = this.seed(spec);
- this.volume = volume || 100;
- this.retries = 0;
- }
- weightedRand = () => {
- let i, j, table = [];
- // Fills up the table with the item (weight * 10) times
- for (i in this.weights) {
- // The constant 10 below should be computed based on the
- // weights in the spec for a correct and optimal table size.
- // E.g. the spec {0:0.999, 1:0.001} will break this impl.
- for (j = 0; j < this.weights[i] * 10; j++) {
- table.push(i);
- }
- }
- // Pick a random value from the generated table
- return table[Math.floor(Math.random() * table.length)];
- }
- views = () => {
- let views = 0;
- for(let i in Object.keys(this.results)){
- views += this.results[Object.keys(this.results)[i]];
- }
- return views;
- }
- forceFloat = (num, points = 2) => {
- return parseFloat(parseFloat(Math.round(num * 100) / 100).toFixed(points));
- }
- decide = () => {
- let _rand = this.weightedRand();
- let _totalViews = this.views();
- let _expectedWeight = this.forceFloat(this.weights[_rand]);
- let _actualWeight = Math.abs(parseFloat((this.results[_rand] / _totalViews).toFixed(2)));
- console.log('Total Views:', _totalViews);
- console.log('Random Chosen:', _rand);
- console.log('Views of Random Chosen:', this.results[_rand])
- console.log('Expected Weight:', _expectedWeight);
- console.log('Actual Weight:', _actualWeight);
- if(_actualWeight > _expectedWeight && _actualWeight !== NaN){
- console.log('Running over, calling again...\n\n');
- this.retries++;
- this.decide();
- }
- else{
- console.log('');
- this.results[_rand]++;
- return _rand;
- }
- }
- test = () => {
- let _totalViews;
- let output = [];
- // Run the program <volume> times
- for(let i = 0; i < this.volume; i++) this.decide();
- _totalViews = this.views();
- for(let i in this.results){
- let key = Object.keys(this.results)[i];
- let views = this.results[i];
- let percentage = views/_totalViews;
- let efficiency = (_totalViews - this.retries) / this.volume;
- output.push({
- 'Option': key,
- 'Views': views,
- 'Actual %': percentage * 100,
- 'Expected %': this.weights[key] * 100,
- 'Retries': this.retries,
- 'Efficiency': Math.abs(efficiency)
- })
- }
- console.table(output);
- }
- }
- let split = {0: 0.20, 1: 0.20, 2: 0.20, 3: 0.20, 4: 0.10, 5: 0.10};
- new TrafficSplit(split).test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement