gaogaotiantian / biliscope

Bilibili chrome extension to show uploader's stats
MIT License
594 stars 46 forks source link

[BUG] 舰长的随机排列算法,并不完全随机。 #118

Closed F-park closed 10 months ago

F-park commented 10 months ago

基准测试结果(修改前 -> 修改后)(随机排列 1200000 次)

image

问题代码

https://github.com/gaogaotiantian/biliscope/blob/8bf9e20ab3aefc306a26efc3602bcd9350542eb6/scripts/ui.js#L666-L672

问题描述

Fisher-Yates shuffle 算法的思路应该是:逆向遍历数组,并将每个元素与其前面的随机的一个元素互换位置。 应该改为如下代码:

// Shuffle guardInfo
let i = guardInfo.length;
while(i) {
    let j = Math.floor(Math.random() * i--);
    [guardInfo[i], guardInfo[j]] = [guardInfo[j], guardInfo[i]];
}

基准测试代码

代码参考自这篇教程

function shuffle(guardInfo) {
  // 待测试的代码
}

// 所有可能排列的出现次数
let count = {'123': 0, '132': 0, '213': 0, '231': 0, '321': 0, '312': 0};

for (let i = 0; i < 1200000; i++) {
  let array = [1, 2, 3];
  shuffle(array);
  count[array.join('')]++;
}

// 显示所有可能排列的出现次数
for (let key in count) {
  console.log(`${key}: ${count[key]}`);
}