c언어 난수 생성 질문드립니다.
글쓴이: duse0001 / 작성시간: 화, 2015/10/27 - 2:32오후
#include <stdio.h> #include<stdlib.h> #include<time.h> #include<windows.h> int running(int var1) { if (var1 == 0) //20%확률(이김) 일때 1리턴 return 1; else return 0; //80%확률(짐) 일때 0리턴 } int win(int money, int var2) { if (var2 == 0) //1등 3배 return money * 3; else if (var2 == 1) //2등 2배 return money * 2; } int lose(int money) { return money; } int game(int var1, int var2, int* money, int betting) { int res; //srand((unsigned)time(NULL)); res = running(var1); if (res == 1) { if (var2 == 0) { *money = *money + win(betting, var2); printf("money : %10d \t betting: %10d Win*3\n", *money, betting); return 0; } if (var2 == 1) { *money = *money + win(betting, var2); printf("money : %10d \t betting: %10d Win*2\n", *money, betting); return 0; } //*money = *money + win(betting, var2); //printf("money : %10d \t betting: %10d Win\n", *money, betting); //return 0; } else if (res == 0) { *money = *money - lose(betting); printf("money : %10d \t betting: %10d Lose\n", *money, betting); return 1; } // return money; } int main(void) { int i = 0, var1, var2, end; static int cnt = 0; static int cnt2 = 0; int money = 10000000000; int betting = 10000; srand((unsigned)time(NULL)); //_sleep(100); var1 = rand() % 5; var2 = rand() % 2; ////for (i = 0; i < 20; i++) ////{ //// var1 = rand() % 5; //// var2 = rand() % 2; //// printf("%d %d\n", var1, var2); ////}rand값확인 유효값확인완료 // ////money=game(var1, var2, &money, betting); ////printf("money : %4d\n", money); //for (i = 0; i < 20; i++) //{ // var1 = rand() % 5; // var2 = rand() % 2; // game(var1, var2, &money, betting); // printf("money : %4d\n", money); //} ////1회게임완료 while (1) { srand((unsigned)time(NULL)); //_sleep(100); var1 = rand()% 5; var2 = rand()% 2; betting = 10000; end = game(var1, var2, &money, betting); cnt++; if (end == 1) //패했을시 { while (1) //이길때까지 반복 { srand((unsigned)time(NULL)); //_sleep(100); betting *= 2; var1 = rand() % 5; var2 = rand() % 2; end = game(var1, var2, &money, betting); cnt++; cnt2++; if (end == 0) break; if (money < 0) { printf("bankrupt!!!\n"); printf("count : %d, continuous cnt : %d\n", cnt, cnt2 + 1); return 0; } //_sleep(7); } } if (money < 0) { printf("bankrupt!!!\n"); printf("count : %d, continuous cnt : %d\n", cnt, cnt2 + 1); return 0; } printf("count : %d, continuous cnt : %d\n", cnt, cnt2 + 1); cnt2 = 0; } return 0; }
18연패할 확률이 0.0180144%(10만분의18) 인데 실제로 돌려보면 1000번도 못가서 파산합니다..
시드값을 time으로줘서 1초도 안되는 시간에 같은값을 같는거 같은데 time(NULL)말고 다른 값을 시드로 주는 방법이 있을까해서 여쭈어봅니다.
Forums:
랜덤이란 "현재까지 알려진 수를 가지고 유추해도 그
랜덤이란 "현재까지 알려진 수를 가지고 유추해도 그 다음에 나오게 될 수를 전혀 알 수 없는 것을 의미"합니다.
-----
설마 다음 수를 유추할 수 있을까? 하지만, 유추를 해내기도 합니다. 단순 수식으로 만들어진 랜덤인 경우 seed만 알면 금방 유추가 되겠지요.
그래서, ....
안전한(다음 수를 추측이 불가한 정도가 큰~) 랜덤을 발생하기 위해서는 다양한 하드웨어 장비를 이용하기도 합니다.
리눅스의 경우 하드웨어 말고, 소프트웨어로 2가지 디바이스(논리) 파일를 제공합니다.
/dev/random ---- 안전(안전한 값을 내보낼 만큼 준비가 되었을때(엔트로피 값이 높을 때), 리턴, 보통 처음사용시에는 리턴이 잘~ 되지만, 시간이 흘러 소진되면 점점 느려지다가 멈추기도 한다. 물론, 시간이 지나면 계속 진행된다.; 이를 리턴받는 측 입장에서는 블록킹이라고도 하고, 이를 이용한 상위 구현에 따라 랜덤 함수 호출에서 멈출 수(블록) 있음; 어떤 자바 암호화 API는 이를 사용했는데, 그래서 멈추기도 함 유의)
/dev/urandom ---- 안전하지 않음(대신 호출과 즉시 값을 리턴)
입니다.
이 파일 중 하나를 열어서, 정수/문자열이던지 취향대로 읽으면 됩니다. 예를 들어, 파일을 열고, 정수포인터로 읽기하면 된다는 얘기지요.
그리고, 계속 읽어도, 무한하게 랜덤이 나오지요.
-------------------
참고로,...
원하는 랜덤 수가 특정 통계분포에 부합되게 발생하게 하려면 아래 링크를 참조.
예를 들어, Poisson 분포 성질을 갖는 어떤 시뮬레이션을 하려면 unsigned int gsl_ran_poisson (const gsl_rng * r, double mu) 를 호출해서 하면 되겠네요.
https://www.gnu.org/software/gsl/manual/html_node/Random-Number-Distributions.html
이 외에도 랜덤은 다양한 수학,과학등의 라이브러리에서 제공되니, PRNG scientific library등으로 검색하면 좋은 결과들이 기대됩니다.
time() 대신 gettimeofday() 쓰셔야
time() 대신 gettimeofday() 쓰셔야 할듯. time()은 초 단위까지이고, gettimeofday()는 밀리초까지 가능합니다.
gettimeofday()로 만족스럽지 않다면 rdtsc 같은 클럭카운트 cpu 명령을 인라인 어셈블리로 집어넣는 방법도 있습니다.
Written By the Black Knight of Destruction
srand를 그렇게 쓰시면 안돼요
srand는 처음에 시작할 때 한번만 하는 거고, 그 다음엔 계속 rand만 불러야 제대로 된 난수를 만들어서 쓸 수 있습니다.
rand를 부르면서 중간에 srand를 부르면 얼핏 생각하기엔 "더 랜덤"할 것 같지만 사실 srand가 인자를 이용해 난수발생기를 초기화해 버리는 역할을 하기 때문에 덜 랜덤한 안좋은 난수가 나옵니다.
지금 코드처럼 time(NULL)을 쓰면 더 말할 것도 없구요. 이번에도 주사위가 3, 다음에도 3, 그 다음에도 3... 이렇게 나오면서 "하지만 3이란 숫자 자체는 랜덤하게 구해진 거라고!" 하는 격이죠.
댓글 달기