연속된 메모리 공간에 할당되고 모두 동일한 타입으로 사용된다.

 

void func(int arr[]); // sizeof(arr) : 8
// void func(int* arr);

int main() {
    int arr[] = { 1, 2, 3, 4, 5 }; // sizeof(arr) : 20
    func(arr);
    
    return 0;
}

배열을 함수의 인수로 넘겨주면 주소값이 전달되기 때문에 포인터의 크기가 나온다.

인수가 배열이라는 것을 명시적으로 알려줄 뿐 사실은 포인터와 완전히 동일하다.

 

◾ 배열의 요소를 뒤집을 때 투 포인터를 사용하면 시간 복잡도는 O(N/2), 공간 복잡도는 그대로이다.

 

부분 배열

◾ 배열의 크기가 N이라면 부분 배열들의 개수는 N^3에 근접한다.

◾ 3중 for문을 사용하면 배열의 부분 배열들을 출력할 수 있다. (i=0<n, j=0<n, k=i<=j)

 

부분 배열의 합 : 브루트 포스

더보기
int largestSubarraySum(int arr[], int n) {
    int largestSum = 0;

    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            int subarraySum = 0;
            for (int k = i; k <= j; ++k) {
                subarraySum += arr[k];
            }
            largestSum = max(largestSum, subarraySum);
        }
    }
    return largestSum;
}

완전 탐색에 의해 계산되고 공간 복잡도는 O(1), 시간 복잡도는 O(N^3)이다.

반복문을 두개로 줄일 수 있으므로 O(N^2)까지 낮출 수 있다.

 

부분 배열의 합 : 누적합

더보기
int largestSubarraySum(int arr[], int n) {
    vector<int> prefix(n, 0);
    prefix[0] = arr[0];
    
    for (int = 1; i < n; ++i)
        prefix[i] = prefix[i-1] + arr[i];
        
    int largestSum = 0;

    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            int subarraySub = i > 0 ? prefix[j] - prefix[i-1] : prefix[j];            
            largestSum = max(largestSum, subarraySum);
        }
    }
    return largestSum;
}

공간 복잡도는 O(N), 시간 복잡도는 O(N+N^2) = O(N^2)이다.

 

부분 배열의 합 : Kadane 알고리즘

더보기
int largestSubarraySum(int arr[], int n) {
    int currentSum = arr[0];
    int largestSum = arr[0];
    
    for (int i = 1; i < n; ++i) {
        currentSum = max(currentSum + arr[i], arr[i]);
        largestSum = max(largestSum, currentSum);
    }
    
    return largestSum;
}

현재 누적합과 최대 누적합을 별도로 관리하여 선형으로 계산해나간다.

공간 복잡도는 O(1), 시간 복잡도는 O(N)이다.

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Vector Data Structure  (0) 2023.02.08
Pointers & Dynamic Memory  (0) 2023.02.07
2D Arrays  (0) 2023.02.07
Character Arrays/Strings  (0) 2023.02.03
Basic Sorting Algorithms  (0) 2023.02.03

116. 평균값 정리

도박사의 오류(평균의 오류)라는 것이 있다.

동전을 연속으로 6번 던졌을 때, 5번 연속 앞면이 나온다면 다음 시행시 확률상 뒷면이 나올거라 기대하는 것이다.

하지만 완전한 독립시행이라서 언제나 50%이다.

 

큰 수의 법칙을 떠올리며 시행횟수가 많아질수록 점점 평균에 근접할거라고 착각하는 것이다. 하지만 이는 다르게 생각하면 균형을 맞추기 위해 뒷면이 나올 확률이 증가해야 한다는 결론에 도달하게 된다.

완전한 독립시행에서 종속시행이라는 결론을 도출하는 것인데 이는 말도 안되는 오류이다.

 

이성적으로 보면 말도 안되지만 그런 확률을 겪은 플레이어가 오류에 빠지지 않게 할 수는 없다. 왜냐면 확률이 안정적인 평균으로 수렴할만큼의 수많은 시행횟수를 시도하는 플레이어는 거의 없다고 봐도 무방하기 때문이다. 게다가 거기까지 도달하기 위해 겪는 부정적인 경험을 무시할 수 없다.

 

그래서 큰 수의 법칙에 의해 확률이 수렴하기 전의 확률 변동을 받아들이게 하기 위해서는 완전한 독립시행이 아닌 종속시행으로 어느정도 보정하는 경우도 있다. (ex:강화실패 시 확률 상승)

확률보정을 유저가 느끼지 못하게 뒤에서 조절할수도 있고 강화시도처럼 직접 확인할수 있게 제공할수도 있으므로 상황에 맞게 선택하여 사용하면 된다.

 

 

117. 베이즈의 정리

확률 이론에서 가장 중요한 식이다.

 

여기에서 유도된 식이다. P(B)로 나누면 베이즈의 정리가 된다.

베이즈의 정리는 조건부 확률을 구하는 한 가지 방법이다.

 

정말 유명한 문제로 베이즈의 정리를 증명해보자.

 

몬티홀 문제

아무런 선택을 하지 않았을 때 상품을 얻을 확률은 P(1)=P(2)=P(3)=1/3 으로 동일하다.

하지만 문을 고르고 사회자가 꽝인 문을 연 뒤에 선택을 바꿨을 때, 확률이 변동하게 된다.

 

참가자가 1번 문을 고른 상태에서 사회자가 2번 문을 열 확률을 b라고 해보자.

 

참가자는 언제나 1번문을 열고, 사회자는 절대 상품이 들어있는 문을 열 수 없으므로 확률은 위와 같다.

 

P(A|b) : b문을 열었을 때, A문에 경품이 있을 확률

P(A) : A문에 경품이 있을 확률

P(b|A) : A문에 경품이 있을 때, 진행자가 B문을 선택할 확률

 

식에 대입하며 계산하면 1/3이 나온다. 진행자가 문을 열든 말든 내가 처음 골랐을 때의 확률은 그대로이다.

하지만 선택을 바꾸면 남은 확률이 합산되기 때문에 2/3으로 변동한다. 사회자가 정보를 알고 정답문을 절대 열지 않는다는것이 핵심이다.

 

 

118. 누적분포함수

확률질량함수, PMF

 

누적분포함수, CDF

 

확률밀도함수, PDF

 

 

119. 엘로(ELO) 평점 시스템

두 유저간 등급 점수의 차이가 있으면 누가 이겼는지에 따라 점수의 증감량이 다르다.

전통적인 ELO 시스템은 로지스틱 함수를 사용하여 계산한다.

 

로지스틱 함수의 기본형

L : 곡선의 최댓값

k : 증가율

x0 : 그래프의 중앙점

 

플레이어 A가 이길 확률

Ra, Rb : A, B 플레이어의 현재 평점

10, 400과 같은 상수는 일종의 매직 넘버이다. 상대방보다 평점이 400점 높다면 승률이 10배 높다는 의미이다.

800점 높으면 100배 높아진다.

400은 임의의 수이기 때문에 게임의 상황에 맞게 변경해도 된다.

 

Sa : 승/무/패별로 얻는 점수 (0~1)

Ea : 플레이어가 이길 확률

k : 최대 점수 상수

 

승률을 구했으면 경기 결과에 따라 가중치를 두어 점수의 가감이 이루어진다.

이길 확률이 낮은 플레이어가 이기게 되면 Sa-Ea는 1에 가깝기 때문에 많은 점수를 얻고 반대로 이길 확률이 높은 플레이어가 지게되면 -1에 가깝기 때문에 많은 점수를 잃는다.

보통 k는 32로 두는편이다. 물론 임의의 수로 설정해도 무관하다. 증감되는 수의 최대치일 뿐이다.

 

평점 산정 시스템이 필요한 경우 ELO 평점 시스템으로 시작하는게 단순해서 이해와 구현이 쉽다.

하지만 리터럴 상수에 의존하기 때문에 상수값을 잘 설정해야 한다는 단점이 있다.

또한 기본적으로 1:1 상황에서만 동작이 가능하므로 ELO 평점 시스템은 맞지 않고 플레이어들의 실력이 같은 분포 곡선을 그리고 있어야한다는 가정이 있어야하지만 실제로는 편차가 존재하기 때문에 정규화 등의 과정을 거쳐서 수정하여 적용해야 한다.

'이론 > 게임수학' 카테고리의 다른 글

[게임수학] 확률과 통계 (3)  (0) 2023.01.16
[게임수학] 확률과 통계 (2)  (0) 2023.01.16
[게임수학] 확률과 통계 (1)  (0) 2023.01.14
[게임수학] 회전과 보간 (4)  (0) 2023.01.13
[게임수학] 회전과 보간 (3)  (0) 2023.01.13

112. 확률의 기초

3또는 다이아 카드를 뽑을 확률

교집합을 빼는 이유는 겹치는 부분이 두번 더해졌기 때문이다.

 

 

113. 연속 시행

독립사건의 연속시행


독립사건의 연속시행은 기존의 결과가 이후의 결과에 영향을 주지 않기때문에 두 확률을 곱하면 구할 수 있다.

예를 들면 주사위를 두번 던져서 6을 연속으로 뽑을 확률이다.

 

종속사건의 연속시행은 기존의 결과가 이후의 결과에 영향을 주기 때문에 수형도를 그려서 각각의 경우를 맞는 조건에 따라 계산해야한다.

예를 들면 카드 두장을 뽑아서 에이스를 연속으로 뽑거나 두장 중 에이스를 한번이라도 뽑을 확률이다.

 

수형도의 모든 확률을 더하면 반드시 1이 나온다. 만약 1이 나오지 않았다면 잘못 작성한것이다.

 

B는 A에 종속되어있기 때문에 독립시행일때와 식이 다르다.

 

 

114. 여사건 법칙

위의 종속사건의 연속시행을 계산하는 경우라면 사실 모든 확률을 더하는것보다 해당되지 않는 경우를 빼는것이 더 쉽고 빠르게 구할 수 있다. 모든 경우는 아니고 이게 더 쉬운 경우가 있다는 것이다. 또한 종속사건의 연속시행 뿐만 아니라 독립사건의 연속시행에도 당연히 적용할 수 있다.

 

예를 들면 동전을 6번 던져서 최소 한번 이상 앞면이 나올 확률이다. 총 64가지의 경우의 수가 생기는데 이를 수형도를 통해 모든 확률을 더하기보다는 앞면이 한번도 안나오는 경우의 수는 딱 한가지이기 때문에 1에서 이 확률만 빼주면 된다.

 

확률을 구하기 어려운것 같으면 반대로 뒤집어서 생각해보아야 한다.

 

 

115. 이론적 확률과 경험적 확률

시행 횟수(표본의 집단)가 많을수록 이론적 확률에 근접하게된다. 큰 수의 법칙이다.

확률을 이론적으로 구할 수 있지만 따로 경험적 확률이 있어야 하는 이유는 뭘까? 바로 검증때문이다.

확률을 코드로 작성하다보면 실수 또는 예상치 못한 부분에서 변수가 발생하여 의도치 않은 결과가 나올 수도 있다.

 

또는 애니팡같은 게임들은 가능한 조합과 무작위성을 추측하여 이론적 확률을 계산하기 매우 어렵기때문에 매우 많은 시뮬레이션을 통해 직접 데이터를 확인하는 경우가 있다.

'이론 > 게임수학' 카테고리의 다른 글

[게임수학] 확률과 통계 (4)  (0) 2023.01.17
[게임수학] 확률과 통계 (2)  (0) 2023.01.16
[게임수학] 확률과 통계 (1)  (0) 2023.01.14
[게임수학] 회전과 보간 (4)  (0) 2023.01.13
[게임수학] 회전과 보간 (3)  (0) 2023.01.13

106. 왜도

대칭적인 정규분포

정규분포는 확률과 통계에서 많이 사용된다.

정규분포에서 최고점은 최빈값에 해당되지만, 대칭적인 정규분포에서는 산술평균, 중앙값, 최빈값 모두에 해당된다.

 

양의 왜도 또는 오른쪽으로 왜곡된 정규분포

정규분포가 양의 왜도를 가지면 산술 평균과 중앙값은 최빈값보다 커진다. 반대로 음의 왜도를 가지면 최빈값보다 작아진다.

 

 

107. 사분위간 범위

양 끝에 존재하는 극단치는 스팬을 크게 만든다. 실제로 관심 있는 데이터는 극단치를 제외한 가운데 부분이기 때문에 사분위간 범위라는것을 사용한다.

말이 어려운것 같지만 전체 범위를 4등분한 사이에 있는 값들의 범위이다. (1/2)

 

전체 중앙값과 양쪽으로 나뉜 범위에 대한 2개의 중앙값

Q1~Q3 사이의 값들이 사분위수 범위이다.

 

 

108. 표준편차

먼저 분산을 알아야한다. 분산은 산술평균을 구해서 각 데이터와 산술평균과의 차이를 제곱하여 다시 산술평균을 내는 것이다.

이렇게 구한 분산의 제곱근이 표준편차가 된다. 산술평균값에 표준편차값을 ±하여 만들어진 범위안에 대부분의 값들이 위치하게 된다.

 

모집단의 표준편차 (μ: 산술평균)

단, 주의해야할점이 하나 있다. 모든 데이터를 포함하는 모집단인지, 혹은 일부 데이터만 포함된 표본집단인지 여부에 따라 n의 값이 달라진다.

모집단인 경우 위의 공식 그대로 쓰고 표본집단인 경우에는 n-1을 사용한다. 그 이유는 오차범위를 넓힘으로써 표본에서 잃어버렸을수도 있는 데이터를 고려해주기 위함이다.

 

또한 표본집단의 표준편차는 σ가 아닌 s로 표기한다.

 

표본집단의 표준편차

계산은 똑같은데 표기만 달라질뿐이다. 조금 번거롭다고 생각될지 모르지만 기호만 보고도 어떤 표준편차인지 알 수 있다.

 

 

109. 상관

상관은 데이터간에 관계가 있는지 여부를 알 수 있다.

 

상관여부를 시각적으로 확인할 수 있는 가장 쉬운 방법

1. 가능한 많은 점이 지나도록 선분을 긋는다.

2. 선의 위쪽과 아래쪽에 거의 같은 수의 점이 있도록 한다.

3. 점들이 선으로부터 멀리 떨어지지 않아야 한다.

 

상관관계를 표현하는 상관계수를 r이라고 한다. -1과 1사이의 값을 가질 수 있고 -1이면 완벽한 음의 상관관계, 1이면 완벽한 양의 상관관계, 0이면 아무런 상관이 없다.

 

r을 구하는 방법은 모집단의 산술평균을 먼저 구하고 같은 행의 두 값을 곱한 뒤에 산술평균을 낸다. (공분산)

이 공분산을 x의 표준편차와 y의 표준편차를 곱한 값으로 나눠주면 r을 구할 수 있다.

 

상관계수 r을 구하는 방법

보통 0.7보다 큰 값이면 큰 양의 상관관계, 0.5~0.7이면 중간정도의 양의 상관관계, 0.3~0.5는 약한 양의 상관관계, 0~0.3은 상관관계가 없다고 본다.

 

 

111. 데이터 정규화

어떤 데이터셋 x가 주어졌을 때, 해당 데이터셋의 최소값과 최대값, 그리고 단일 데이터들이 필요하다.

각 단일 데이터마다 위의 연산을 수행하면 0~1사이의 정규화된 값으로 조정된다. 만약 0~1이 아닌 다른 범위가 필요하다면 해당 결과에 (범위 최대값 - 범위 최소값)을 곱해준 뒤에 범위 최소값을 더해주면 된다.

 

a=범위 최소값, b=범위 최대값

'이론 > 게임수학' 카테고리의 다른 글

[게임수학] 확률과 통계 (4)  (0) 2023.01.17
[게임수학] 확률과 통계 (3)  (0) 2023.01.16
[게임수학] 확률과 통계 (1)  (0) 2023.01.14
[게임수학] 회전과 보간 (4)  (0) 2023.01.13
[게임수학] 회전과 보간 (3)  (0) 2023.01.13

101. 데이터 들여다보기

보통 게임의 데이터는 원시 상태라서 바로 읽기에는 무리가 있다. 이를 읽기 쉽게 만들기 위해 사용되는 보편적인 방법은 도수분포표를 만드는 것이다.

 

도수분포표를 토대로 그린 단일변수 차트

차트를 그림으로써 시각적으로 5단계와 6단계 사이에 무언가 문제가 있다는 사실을 추측할 수 있게 된다.

다만 어떤 문제인지는 구체적으로 확인할 수 없고 추정만 가능하다. 이 때 추가적으로 버그리포트나 플레이어 피드백 등을 확인하여 문제점을 구체화 시켜야 한다.

 

막대차트 대신 상황에 맞춰서 파이차트도 그릴 수 있다. 한가지 권장사항으로 차트 툴에서 제공하는 3D 차트는 피하는것이 좋다.

 

 

102. 백분율

40의 100%는 40이고 100의 40% 역시 40이다. 이를 이용하여 백분율 암산을 더 쉽게 할 수 있다.

수식으로 정리하면 x% of y = y% of x이다. 25의 24%를 구하는 것보다 24의 25%를 구하는게 훨씬 쉽다.

 

값의 증가율을 구하는 식

예시 하나를 들어보자. 어떤 플레이어가 랭크게임을 시작하기 전의 레이팅이 1123이었고 끝난후의 레이팅이 1251이면 11.3%가 증가한 것이다.

 

 

103. 시그마 표기법

반복문을 작성하는 것과 같다. 시그마는 그저 모든 요소를 더할 뿐이다.

 

 

104. 평균

평균에는 산술평균, 중앙값, 최빈값 총 3가지가 존재한다.

 

◾ 산술평균 : 우리가 아는 그 평균.

장점 : 연속적인 수치자료에 사용될 수 있다 (예: 킬 평균)

단점 : 수치자료가 아닐 때 사용할 수 없다. (예: 유저들의 선호무기)

극단치가 있을 때 값이 왜곡된다. (예: 99명의 0킬과 1명의 1000킬 산술평균은 10킬)

 

◾ 중앙값 : 데이터 셋의 가운데 값. 원소의 개수가 짝수인 경우 가운데를 기준으로 좌우값의 산술평균값을 산출한다.

장점 : 극단치와 관계가 없어진다.

단점 : 정렬이 되지 않으면 사용이 불가능하다. 마찬가지로 수치자료에만 사용이 가능하다.

 

◾ 최빈값 : 데이터 셋에서 가장 많이 나타난 값.

 

 

105. 극단치

어떤 데이터를 다루던 간에 극단치는 존재할 수 있다.

 

위와 같은 산포도에서 극단치가 존재하는 경우 우리는 세 가지 선택을 할 수 있다.

첫번째, 그냥 무시하는 것이다. 극단치도 데이터의 일부이기 때문이다. 다만 해당 수치를 무시할 뿐이다.

두번째, 데이터 셋에서 제외시킨다. 너무 눈에 띄는 극단치라면 제외하고 싶기 때문이다.

세번째, 어떤 기준에 의해 데이터를 반영하여 원래 되어야 했을 값을 추정하여 값을 조정한다.

 

세가지 방법중 상황에 따라 필요한것을 선택하면 된다.

보통 데이터의 무결성을 위해 극단치까지 포함된 보고서와 극단치를 처리한 보고서 총 2개를 작성하는게 일반적이다.

'이론 > 게임수학' 카테고리의 다른 글

[게임수학] 확률과 통계 (3)  (0) 2023.01.16
[게임수학] 확률과 통계 (2)  (0) 2023.01.16
[게임수학] 회전과 보간 (4)  (0) 2023.01.13
[게임수학] 회전과 보간 (3)  (0) 2023.01.13
[게임수학] 회전과 보간 (2)  (0) 2023.01.12

+ Recent posts