[t:/]$ 지식_

가중 랜덤값 뽑기

2021/08/10

검색하면 다양한 알고리즘이 있으나 내가 아니 우리가 그렇게 과학적인 사람이 아니다. 사실 수학적으로 정확정밀할 필요도 없는데 뭔가 복잡한 알고리즘을 쓰긴 귀찮다.

간단히는 정규분포의 확률밀도함수의 곡선식을 찾아쓰면 되는데, 계산이 좀 복잡하다.

보통 필요한 것은 정렬된 벡터 - 1차원 배열에서 대가리부터 자주 뽑히게 만드는 것이다. 정규분포의 함수를 사용한다면 이 함수가 0보다 큰 값을 취하게 만든 후 평균 = 0, 시그마 = 배열 길이 대비 적당한 값. 으로 정해서 인덱스를 취하도록 하면 된다.

즉, 평균 = 0이므로 인덱스=0인 배열의 대가리를 가장 자주 뽑는다. 시그마를 5로 결정하면 대가리부터 2시그마인 인덱스 = 10안에서 95%가 뽑힌다. 배열의 크기가 100이라면 인덱스 < 10안에서 95%를 뽑게 만들 수 있다는 뜻. 시그마를 배열의 길의 어느 선까지 내려오게 할 것인가, 확률 밀도 함수를 양의 값만 취하므로 이를 어떻게 처리할까 고민하면 된다. 파이썬 같이 다 지원하면 지원하는 정규분포용 랜덤 함수를 쓰면 된다.

나는 지금 lua를 쓰잖아?

귀찮을 때는 이렇게 하는 것도 방법이다.

x^n 곡선에서 n이 커질 수록 곡선은 급하게 상승한다. 우리는 자연인이고 우주의 법칙을 따르니까 대충 n대신 e = 2.718의 곡선을 사용해보자.

math.random()^2.718을 하면 어찌될까?

랜덤은 0~1에서 자주 나오는데 곡선의 y값이 작은 x값에 몰려있다. 가중 랜덤이 되는 것이다.

https://www.desmos.com/calculator?lang=ko 에서 그려보면 도움이 된다.

나는 수학을 못하므로.. 이런 곳에서 다차 함수를 이리저리 그려보고 최적화 식으로 사용할 때가 종종 있다.

결과적으로 배열의 길이가 10일때, 다음 식이면 대가리가 자주 뽑히는 랜덤이 나온다. 물론 수학적으로 큰 의미는 없다. 대충이다. 대충. lua 코드에서 이렇다.

print (math.floor(10 * math.random()^2.718))

이제 배열의 대가리쪽을 자주 뽑는 가중 랜덤식이 완성됐다. 나님은 수학을 모르고 이 정도면 쓸만하다. 별 것도 아닌데 잘난척이 길었다.









[t:/] is not "technology - root". dawnsea, rss