怎样才能使用产生1和3之间的数的函数1和9之间的一个数? 的概率,以获得任何数量的1和9之间必须是相同的,所以rand3()+ rand3()+ rand3()不是一个好的解决方案。
Answer 1:
尝试直角状产品:
Rand9() = 3 * (Rand3() - 1) + Rand3()
随着3 *(Rand3() - 1)你让子区间1-3,4-6和7-9同样可能。 随着+ Rand3()然后你会在该次区间同样选择。
写成一个产品:
3 * (Rand3() - 1) + Rand3() -> {1, 4, 7} X {+1,+2,+3} -> {1,2,3,4,5,6,7,8,9}
Answer 2:
该解决方案的主要思想是建立3*3
矩阵。
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
function init() { const rand3 = generateMathRandom(3); let randFunc = rand3; const start = 9; const end = 10; let i = start; console.time('---start'); while (i < end) { randFunc = generateRandom(i, 3, rand3); healthCheck(i, randFunc); i++; } console.timeEnd('---start'); i = start; console.time('---start-math'); while (i < end) { randFunc = generateMathRandom(i); healthCheck(i, randFunc); i++; } console.timeEnd('---start-math'); } function generateMathRandom(range) { return function () { return Math.floor(Math.random() * range); } } // range - target random range number : eg 9 // lowerRange - base random range number : eg 3 // func - function which generate random with the range of lowerRange : eg rand3 function generateRandom(range, lowerRange, func) { return function () { const results = []; let times = 1; let matRange = lowerRange; let mat = Math.sqrt(range); while(mat > lowerRange) { mat = Math.sqrt(mat); times ++; matRange *= lowerRange; } const noneStart = Math.floor(matRange * matRange / range) * range; for (let i = 0; i < matRange; i++) { results.push([]); for (let j = 0; j < matRange; j++) { const num = i * matRange + j; if (num < noneStart) results[i].push(num % range); else results[i].push(-1); } } while (true) { const row = new Array(times).fill(1).map(n => func()).reduce((a, c) => a * lowerRange + c, 0); const col = new Array(times).fill(1).map(n => func()).reduce((a, c) => a * lowerRange + c, 0); if (!results[row]) { debugger; } if (results[row][col] == undefined) { debugger; } if (results[row][col] === -1) continue; return results[row][col]; } } } function healthCheck(range, func = null, count = 100000) { const funcToCheck = func || rand[range] || null; if (!funcToCheck) { console.log('Function is not provided'); return; } const health = new Array(range).fill(0); const checkCount = count - count % range; // To do correct check. for (let i = 0; i < checkCount; i++) { health[funcToCheck()]++; } const result = health.map((cnt, index) => ({ _value: index, rate: (cnt / checkCount * 100).toFixed(5) })); // console.log('Random result:', result); let minRate = 100, maxRate = 0; for (let i = 0; i < range; i++) { minRate = Math.min(Number(result[i].rate), minRate); maxRate = Math.max(Number(result[i].rate), maxRate); } console.log('Random health<' + range + '>: ' + healthOutput(range, maxRate - minRate)); } function healthOutput(range, rangeOffset) { const healthThreshold = 2; // It should be lower for the best Alghorithms const threshold = healthThreshold; if (rangeOffset < threshold * 0.2) { return 'The Super! -> ' + rangeOffset.toFixed(5); } else if (rangeOffset < threshold * 0.5) { return 'The Best! --> ' + rangeOffset.toFixed(5); } else if (rangeOffset < threshold * 1) { return 'Good work! -> ' + rangeOffset.toFixed(5); } else if (rangeOffset < threshold * 2) { return 'Not bad! ---> ' + rangeOffset.toFixed(5); } return 'Worst! -----> ' + rangeOffset.toFixed(5); } init();
文章来源: Random generator Rand9() using Rand3()