Skip to content

Instantly share code, notes, and snippets.

@micoli
Created December 27, 2017 10:22
Show Gist options
  • Select an option

  • Save micoli/099bc039ac28ce356108f02f988b0db2 to your computer and use it in GitHub Desktop.

Select an option

Save micoli/099bc039ac28ce356108f02f988b0db2 to your computer and use it in GitHub Desktop.
function weightedRandomA(corpus){
// https://stackoverflow.com/questions/12672765/elegant-way-to-generate-a-random-value-regarding-percentage
var totalWeight=0;
var sortedCorpus=[];
var n,k;
for (k in corpus){
totalWeight+=corpus[k];
sortedCorpus.push({'k':k,'v':corpus[k]});
}
sortedCorpus.sort(function(a,b){
return b.v - a.v;
});
var r = Math.random()*totalWeight;
for(k in sortedCorpus){
r-=sortedCorpus[k].v;
if(r<=0){
return sortedCorpus[k].k;
}
}
}
function weightedRandomB(corpus){
var weightedCorpus=[];
var n;
for (k in corpus){
for (n=0;n<Math.ceil(corpus[k]);n++){
weightedCorpus.push(k);
}
}
var alea = Math.floor(Math.random() * (Math.floor(weightedCorpus.length-1) +1));
return weightedCorpus[alea];
}
class weightedRandomCorpusA{
constructor(corpus){
// https://stackoverflow.com/questions/12672765/elegant-way-to-generate-a-random-value-regarding-percentage
this.totalWeight=0;
this.sortedCorpus=[];
var k;
for (k in corpus){
this.totalWeight+=corpus[k];
this.sortedCorpus.push({'k':k,'v':corpus[k]});
}
this.sortedCorpus.sort(function(a,b){
return b.v - a.v;
});
}
pick (){
var r = Math.random()*this.totalWeight;
for(k in this.sortedCorpus){
r-=this.sortedCorpus[k].v;
if(r<=0){
return this.sortedCorpus[k].k;
}
}
}
}
class weightedRandomCorpusB{
constructor(corpus){
this.weightedCorpus=[];
var n;
for (k in corpus){
for (n=0;n<Math.ceil(corpus[k]);n++){
this.weightedCorpus.push(k);
}
}
}
pick (){
var alea = Math.floor(Math.random() * (Math.floor(this.weightedCorpus.length-1) +1));
return this.weightedCorpus[alea];
}
}
function testAll(corpus){
var testOne = function (corpus,fn){
function _(v,n){
return (' ').repeat(n - (''+v).length).substr(0,n)+(''+v)
}
var result={};
var t1,t2,o,res;
t1 = new Date().getTime();
var n=100000;
for (var i=0;i<n;i++){
if(fn){
res = fn(corpus);
}else{
res = corpus.pick();
}
if(!result.hasOwnProperty(res)){
result[res]=0;
}
result[res]+=1;
}
t2 = new Date().getTime();
for (var k in result){
result[k]=Math.round(result[k]/n*100)
}
return JSON.stringify({'TotalTime':_(t2-t1,7),'OneTime':_((t2-t1)/n,10),'result':result});
}
console.log('method A',testOne(corpus,weightedRandomA));
console.log('method B',testOne(corpus,weightedRandomB));
console.log('class A',testOne(new weightedRandomCorpusA(corpus)));
console.log('class B',testOne(new weightedRandomCorpusB(corpus)));
console.log('-----------');
}
testAll({0:10,1:85,2:5});
testAll({0:1,1:1,2:2,3:1});
testAll({0:100,1:100,2:100,3:200});
testAll({0:530,1:100,2:100,3:1000});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment