방개
비밀번호를 잊어버리셨나요?

코드

확률이 있는 Random 함수

    • 글자 크기

누군가의 질문으로 심심해서 짜보았습니다. ^^

 

코드 설명은 없으나,... 어떤 식으로 진행되는 코드냐면

 

"뿁고자 하는 범위에 100을 곱한 뒤 그 부분을 특정 퍼센트 비율로 쪼개서 각각의 구간에 내가 원하는 값을 매기면" 그 비율만큼 확률이 올라가겠죠~

 

예를 들어서, 1부터 3까지 중 1을 50%확률로 뽑히게 해봅시다.

 

그러면, 1~3 범위에 각각 100을 곱하여 100~300범위에서 수를 뽑습니다.

그럼 100~300(거리: 200)의 범위에서 50%에 해당하는 100~200으로 수가 뽑힌다면, 이를 1로 가정하는 것입니다. 나머지는 균등분배하면 되겠죠.

 

다시, 1~5 범위에서 1과 2를 각각 50%, 40%로 뽑는 스크립트를 작성해봅시다.

100~500으로 100을 곱한  범위를 만들어 준 후, 여기서 50%지점은 100~300, 여기서부터 또 전체의 40%만큼 범위를 조정해주면은 300~460이 됩니다.

즉, 100부터 500까지의 범위에서 Random 명령어를 쓴 뒤에, 100~300의 범위의 수가 나오면 1, 300~460의 범위가 나오면 2라고 합니다. 460보다 크고 500보다 작은 범위(10%의 확률이겠죠)가 걸리면~ 3부터 5까지에서 다시 균등 분배 하면 되는 것입니다. 이론상 3.3%씩 가져가겠지요.

 

무튼.. 이런 원리로 작성된 함수입니다.

Rand(Min, Max, PercentageArr)
{
	MinCorrection := Min * 100, MaxCorrection := Max * 100
	NumSection := MaxCorrection - MinCorrection
	Random, var, MinCorrection, MaxCorrection
	
	arrIndex := []
	
	Loop, % Max
	{
		if (PercentageArr[A_index] != "")
		{
			arrIndex.Push(A_index)
			var%A_index% := PercentageArr[A_index]
		}
	}

	MaxValue := 0
	Loop, % arrIndex.Length()
	{
		varIndex := arrIndex[A_index]
		MinValue := MaxValue
		MaxValue := MinValue + NumSection * (var%varIndex% / 100)
		if (MinCorrection + MinValue <= var && var <= MaxValue + MinCorrection)
		{ 
			result := varIndex
			break
		}
	}

	if (result = "")
	{
		Loop
		{
			Random, var, min, max
			isJungBok := false
			Loop, % arrIndex.Length()
			{
				if (var = arrIndex[A_index])
				{
					isJungBok := true
					break
				}
			}
			if (isJungBok = false)
			{
				result := var
				break
			}
		}			
	}

	return result
}

 

사용법은 간단합니다.. 키 밸류 형태로 확률을 받기 때문에, 아래와 같이 확률을 적어주시면 됩니다.

Rand(1, 4, {1:50, 3:40})

이 호출부의 내용은 1이 나올 확률을 50%, 3이 나올 확률을 40%로 정해준 뒤 1부터 4까지 중 수를 뽑아 나온 결과를 반환합니다.

 

Loop, 10000
{
	var := Rand(1, 4, {1:50, 3:40})
	Count%var%++
}

MsgBox, % "1 : " count1 "회 (" Round((count1 / 10000) * 100, 2) "%), 2 : " count2 "회 (" Round((count2 / 10000) * 100, 2) "%), 3 : " count3 "회 (" Round((count3 / 10000) * 100, 2) "%), 4 : " count4 "회 (" Round((count4 / 10000) * 100, 2) "%)"

이런식으로 한번 작성해보겠습니다. 10000회 반복을 하여 각각의 수가 나온 횟수(Count1~4)와 확률을 표시해보았습니다.

4.png

1이 나올 확률과 3이 나올 확률을 각각 50%, 40%로 제한해두었으므로, 1만회를 반복하면 1이 약 5000회, 3이 약 4000회가 나올 것입니다. 출력을 해보니 5088회, 3934회로 확률다운 확률이 나왔습니다. 나머지 2와 4는 따로 지정해주지 않았으므로, 남은 10%를 균등 분배하여 각각 5%정도씩 나오겠네요.

 

물론, "확률"이기에 정확히 그 퍼센티지대로 나오기는 힘듭니다. 동전을 두 번 던지면 무조건 앞면 한번 뒷면 한번 나오는 것이 아니니까요.

 

다만 큰 수의 법칙에 따라, 무한히 이 함수를 호출하게 된다면 그 값은 우리가 지정해준 확률로 수렴할 것입니다.

 

    • 글자 크기

댓글 달기

서버에 요청 중입니다. 잠시만 기다려 주십시오...