5

나는 Project Euler에서 280th 문제를 해결하려고 노력 중이며 이에 대해 다음 시뮬레이션을 작성했습니다.랜덤 정수를 "충분히"생성하는 방법은 무엇입니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/time.h> 

/* Directions 

    1 
2  3 
    4 
*/ 

int grid[5][5] = { 
    {0, 0, 0, 0, 2}, 
    {0, 0, 0, 0, 2}, 
    {0, 0, 0, 0, 2}, 
    {0, 0, 0, 0, 2}, 
    {0, 0, 0, 0, 2} 
}; 

int InitPos[2] = {2, 2}; 

int MaxExp = 5000000; 

bool Success = false; 
int StepCount = 0; 
int ExpNumber = 1; 
int AntsBag = 0; 
void Init(); 
void CarryFood(int * pos); 
void LeftFood(int * pos); 
bool checkMovability(int * pos, int direction); 
bool moveToDirection(int pos[2], int direction); 
bool checkSuccess(); 
void ShowResult(); 


int main(int argc, char const *argv[]) 
{ 
    timeval curTime; 
    gettimeofday(&curTime, NULL); 
    int milli = curTime.tv_usec/1000; 


    time_t t; 
    srand((unsigned)time(&t)); 

    //timeTData*.txt corresponds to using "time(&t)" above 
    //milliData.txt corresponds to using "milli" variable above 
    //timeTUnsigData*.txt corresponds to using "(unsigned)time(&t)" above 

    printf("%% Experiment Number : %d \n", MaxExp); 
    while(ExpNumber <= MaxExp) 
    { 
     Init(); 
     int pos[2]; 
     pos[0] = InitPos[0]; 
     pos[1] = InitPos[1]; 
     do{ 
      int direction = (rand() % 4) + 1; 
      if (moveToDirection(pos, direction)) 
      { 
       StepCount++;  
      } 
      if (pos[1] == 4&&grid[pos[0]][4]==2&&AntsBag==0) 
      { 
       CarryFood(pos); 
      } 
      if (pos[1] == 0&&grid[pos[0]][0]==0&&AntsBag==2) 
      { 
       LeftFood(pos); 
      } 
      checkSuccess(); 
     } 
     while(!Success); 

     ShowResult(); 
     ExpNumber++; 
    } 

    return 0; 
} 

void Init() 
{ 
    Success = false; 
    StepCount = 0; 
    AntsBag = 0; 
    int gridInit[5][5] = { 
     {0, 0, 0, 0, 2}, 
     {0, 0, 0, 0, 2}, 
     {0, 0, 0, 0, 2}, 
     {0, 0, 0, 0, 2}, 
     {0, 0, 0, 0, 2} 
    }; 
    for (int i = 0; i < 5; ++i) 
    { 
     for (int j = 0; j < 5; ++j) 
     { 
      grid[i][j] = gridInit[i][j]; 
     } 
    } 
} 

void ShowResult() 
{ 
    /* 
    for (int i = 0; i < 5; ++i) 
    { 
     printf("\n"); 
     for (int j = 0; j < 5; ++j) 
     { 
      printf("%d ", grid[i][j]); 
     } 
    } 
    */ 
    printf("%d %d\n", StepCount, ExpNumber); 
} 

void CarryFood(int * pos) 
{ 
     AntsBag = 2; 
     grid[pos[0]][4] = 0; 
} 

void LeftFood(int * pos) 
{ 
     AntsBag = 0; 
     grid[pos[0]][0] = 2; 
} 

bool checkMovability(int * pos, int direction) 
{ 
    switch(direction) 
    { 
     case 1: 
     { 
      if(pos[1]==0){ 
       return false; 
      } 
      break; 
     } 
     case 2: 
     { 
      if (pos[0]==0) 
      { 
       return false; 
      } 
      break; 
     } 
     case 3: 
     { 
      if (pos[0]==4) 
      { 
       return false; 
      } 
      break; 
     } 
     case 4: 
     { 
      if (pos[1]==4) 
      { 
       return false; 
      } 
      break; 
     } 
     default: 
     { 
      printf("Wrong direction input is given!!\n"); 
      return false; 
      break; 
     } 
    } 
    return true; 

} 

bool moveToDirection(int * pos, int direction) 
{ 
    if (!checkMovability(pos, direction)) 
    { 
     return false; 
    } 

    switch(direction){ 
     case 1: 
     { 
      pos[1] -= 1; 
      break; 
     } 
     case 2: 
     { 
      pos[0] -= 1; 
      break; 
     } 
     case 3: 
     { 
      pos[0] += 1; 
      break; 
     } 
     case 4: 
     { 
      pos[1] += 1; 
      break; 
     } 
     default: 
     { 
      printf("I'm stunned!\n"); 
      return false; 
      break; 
     } 
    } 
    return true; 
} 

bool checkSuccess() 
{ 
    for (int i = 0; i < 5; ++i) 
    { 
     if (grid[i][0] != 2) 
     { 
      return false; 
     } 
    } 
    //printf("Success!\n"); 
    Success = true; 
    return true; 
} 

출력을 * .txt 파일로 재지 정하고 다음 옥타브 코드로 단계 수의 예상 값을 찾으십시오.

clear 
load data.txt 
n = data(:,1); 

output_precision(15); 

mean(n) 

%% The actual data 

%% milliData1 -> 430.038224000000 
%% milliData2 -> 430.031745000000 

%% timeTData1 -> 430.029882400000 
%% timeTData2 -> 430.019626400000 

%% timeUnsigData1 -> 430.028159000000 
%% timeUnsigData2 -> 430.009509000000 

는 그러나, 나는 당신이 위의 결과에서 볼 수 있듯이 내가 다른 결과를 얻을 수 두 번 동일한 코드를 실행합니다. (즉, 참고, 나는 이유에 대해 서로 다른부터 srand (..) 입력을이 시도 나는 설명 할 것이다).

제가 생각하기에이 실험의 확률 분포는 같아야하기 때문에 제가 개미의 무작위 방향에 대해 1-4 사이의 임의의 정수를 어떻게 생성하는지에 대한 이유라고 생각했습니다. 내가 실험을 많은 시간 (이 특별한 경우 5000000 번) 반복한다면 말입니다.

그래서 내 첫 번째 질문은 정말 내가 임의의 정수를 생성하는 방법과 관련된 문제입니까? 그렇다면 우리는 어떻게이 문제를 극복 할 수 있습니까? 즉, 무작위로 정수를 생성하면 같은 실험을 여러 번 반복 할 때 이들 사이의 기대 값이 내가 얻은 결과보다 작아 질 수 있습니다.

+2

나는이 문제를 시뮬레이션보다는 수학으로 풀기를 원한다고 생각합니다. 상태의 그래프를 구성하고 평균을 계산하기 위해 분석 할 수 있습니다. 그러나, 잘 모르겠다. –

+0

입력 값은 아마도 100-1000과 같이 큰 편차를 가지므로 5m 데이터 포인트는 사용자가 보여주는 것만 큼 중요하게 생각합니다 (예 : 430.03 ± 0.02). 입력 난수가 주요한 문제는 아닐 것이다. 그러나 임의성없이 해결할 수 있습니다. 해당 과목의 학년 수준 자료에 대한 "마크로프 체인 예상 단계 수"를 검색하십시오. – Veedrac

+0

@Veedrac 입력의 분산을 어떻게 알 수 있습니까? 그 오류 막대는 어떻게 계산 했습니까? – onurcanbektas

답변

1

당신은이 값보다 균일 한 분포를 생성

std::mt19937 gen{std::random_device{}()}; 
std::uniform_int_distribution<int> dist{1, 4}; 

int randNumber = dist(gen); 

같은 것을 사용할 수 있습니다.