study/알고리즘 문제 풀이

[javaScript]뽑기 당첨 확률 (누적 확률, 랜덤 뽑기)

dddzr 2023. 6. 14. 17:24
// 각 등수별 남은 개수와 총 개수
const prizes = [
  { rank: 1, remaining: 2, total: 5 },
  { rank: 2, remaining: 1629, total: 4000 },
  { rank: 3, remaining: 1965, total: 5000 },
  { rank: 4, remaining: 4030, total: 10000 },
  { rank: 5, remaining: 4033, total: 10000 }
];

// 등수별 확률 및 누적 확률 계산
const probabilities = prizes.map(prize => prize.remaining / prize.total);
const cumulativeProbabilities = probabilities.reduce((acc, curr, index) => {
  if (index === 0) {
    acc.push(curr);
  } else {
    acc.push(acc[index - 1] + curr);
  }
  return acc;
}, []);

// 뽑기
const randomValue = Math.random();
let selectedRank = null;
for (let i = 0; i < cumulativeProbabilities.length; i++) {
  if (randomValue <= cumulativeProbabilities[i]) {
    selectedRank = i + 1;
    break;
  }
}

// 결과 출력
console.log(`뽑힌 등수: ${selectedRank}`);

각 등수별로 확률을 계산합니다. 등수의 확률은 "남은 개수 / 총 개수"로 계산할 수 있습니다. 이를 등수별 확률 리스트에 저장합니다.

예를 들어, 1등의 경우 확률은 2/5, 2등의 경우 확률은 1629/4000과 같이 계산됩니다.
확률 리스트: [2/5, 1629/4000, 1965/5000, 4030/10000, 4033/10000]
등수별 확률을 이용하여 각 등수가 선택될 확률의 범위를 계산합니다. 이를 누적 확률 리스트에 저장합니다.

누적 확률 리스트는  이전 등수의 누적 확률에 현재 등수의 확률을 더한 값을 저장합니다.
예를 들어, 위의 확률 리스트를 누적하여 계산하면 [2/5, 4069/8000, 6039/10000, 10069/20000, 14102/20000]가 됩니다.
0부터 1 사이의 랜덤한 숫자를 생성합니다. 이를 뽑기 확률값으로 사용합니다.

랜덤 값이 누적 확률 리스트의 특정 구간에 속하면 해당 등수가 선택되는 방식으로 동작합니다.

예를 들어, 

1등: 0.4 (누적 확률: 0.4)
2등: 0.40725 (누적 확률: 0.80725)
3등: 0.393 (누적 확률: 1.2)

이 경우, 랜덤 값이 0부터 0.4 사이에 속하면 1등이 선택되고, 0.4부터 0.80725 사이에 속하면 2등이 선택되며, 0.80725부터 1 사이에 속하면 3등이 선택됩니다. 각 등수별로 확률이 반영되어 있기 때문에 상대적으로 확률이 높은 등수가 선택될 확률이 높아집니다.