Uh oh!
There was an error while loading. Please reload this page.
forked from trekhleb/javascript-algorithms
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweightedRandom.test.js
More file actions
Latest commit
64 lines (55 loc) · 2.86 KB
/
Copy pathweightedRandom.test.js
File metadata and controls
64 lines (55 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
importweightedRandomfrom'../weightedRandom';
describe('weightedRandom',()=>{
it('should throw an error when the number of weights does not match the number of items',()=>{
constgetWeightedRandomWithInvalidInputs=()=>{
weightedRandom(['a','b','c'],[10,0]);
};
expect(getWeightedRandomWithInvalidInputs).toThrow('Items and weights must be of the same size');
});
it('should throw an error when the number of weights or items are empty',()=>{
constgetWeightedRandomWithInvalidInputs=()=>{
weightedRandom([],[]);
};
expect(getWeightedRandomWithInvalidInputs).toThrow('Items must not be empty');
});
it('should correctly do random selection based on wights in straightforward cases',()=>{
expect(weightedRandom(['a','b','c'],[1,0,0])).toEqual({index: 0,item: 'a'});
expect(weightedRandom(['a','b','c'],[0,1,0])).toEqual({index: 1,item: 'b'});
expect(weightedRandom(['a','b','c'],[0,0,1])).toEqual({index: 2,item: 'c'});
expect(weightedRandom(['a','b','c'],[0,1,1])).not.toEqual({index: 0,item: 'a'});
expect(weightedRandom(['a','b','c'],[1,0,1])).not.toEqual({index: 1,item: 'b'});
expect(weightedRandom(['a','b','c'],[1,1,0])).not.toEqual({index: 2,item: 'c'});
});
it('should correctly do random selection based on wights',()=>{
// Number of times we're going to select the random items based on their weights.
constATTEMPTS_NUM=1000;
// The +/- delta in the number of times each item has been actually selected.
// I.e. if we want the item 'a' to be selected 300 times out of 1000 cases (30%)
// then 267 times is acceptable since it is bigger that 250 (which is 300 - 50)
// ans smaller than 350 (which is 300 + 50)
constTHRESHOLD=50;
constitems=['a','b','c'];// The actual items values don't matter.
constweights=[0.1,0.3,0.6];
constcounter=[];
for(leti=0;i<ATTEMPTS_NUM;i+=1){
constrandomItem=weightedRandom(items,weights);
if(!counter[randomItem.index]){
counter[randomItem.index]=1;
}else{
counter[randomItem.index]+=1;
}
}
for(letitemIndex=0;itemIndex<items.length;itemIndex+=1){
/*
i.e. item with the index of 0 must be selected 100 times (ideally)
or with the threshold of [100 - 50, 100 + 50] times.
i.e. item with the index of 1 must be selected 300 times (ideally)
or with the threshold of [300 - 50, 300 + 50] times.
i.e. item with the index of 2 must be selected 600 times (ideally)
or with the threshold of [600 - 50, 600 + 50] times.
*/
expect(counter[itemIndex]).toBeGreaterThan(ATTEMPTS_NUM*weights[itemIndex]-THRESHOLD);
expect(counter[itemIndex]).toBeLessThan(ATTEMPTS_NUM*weights[itemIndex]+THRESHOLD);
}
});
});