C++에서 랜덤하게 숫자를 출력하되 특정숫자를 특정 비율로 하는 방법은 없나요?

pong0923의 이미지

이번에 학교에서 자료구조론을 듣는데요
정작 자료구조 자체보다 주변것들이 더 어렵네요 ;;

n * n 인 두 행렬의 곱과 관계된 문제인데,
두 행렬을 각각 알아서 만들어야 하거든요?

랜덤하게 출력하되 0의 비율이 70%, 80%,90%가 되도록 하여서
세 케이스에 대해서 테스트를 진행해야하는데...

행렬을 만들 때
랜덤하게 숫자를 출력하되 0이 특정 비율만큼으로 나오도록 하는 방법이나 기능이 있나요?

혹시 없다면.. 아이디어좀..
랜덤함수를 따로 제작해야하나..ㅠ

p.s
일단은.. 랜덤함수로 숫자를 찍되, 0이 나올때마다 갯수를 카운트해서
앞으로 나와야 할 0의 갯수와 앞으로 출력해야 할 숫자의 갯수가 같으면
다 0으로 찍어버리게 만들어놨는데요
이러면 골고루 안나와서.. 랜덤이라는 의미가 퇴색하잖아요 ㅠㅠ

snowall의 이미지

가령, 10x10행렬을 만든다고 하고, 그중 70%가 0인 행렬을 만든다고 하면
0이 아닌 숫자 30개를 생성하고, 0을 70개를 넣어줍니다. 이제 100개의 숫자는 준비가 되었죠.
그리고, 100개의 난수를 발생시킨 후, 순서대로 100개의 숫자에 매칭시킵니다.
(난수, 숫자) 쌍이 만들어 지면, 이제 난수를 크기 순서대로 정렬해 줍니다.
그럼, 0이 정확히 70%가 포함된 난수열이 생성됩니다.

--------------------------
snowall의 블로그입니다.
http://snowall.tistory.com

피할 수 있을때 즐겨라! http://melotopia.net/b

pong0923의 이미지

원래 라이브러리 함수중에는 그런 기능이 없나보죠?ㅠㅠㅠ

흠~
만들고나서 한번 더 섞어주란 말씀이시죠?ㅋ
시간은 좀 걸릴것 같은데 괜찮은데요? ^^* ㅋㅋ

참고하겠습니다~ 고맙습니다 ^^

Deios의 이미지

'보통 값에 난수를 사용 하는데 이 경우에서는 위치에(도) 난수를 사용한다'라는 표현도 가능할것 같네요.

값 난수, 위치 난수 라고 표현하는것도 봤었습니다.

뭘 할때 저 위치 난수를 사용할까? 라는 의문을 가지고 있었는데, 이런곳에서 사용이 가능하겠네요 ^^

================================
http://deios.kr
$find / -perm 750 | grep girl

$

================================
http://deios.kr
$find / -perm 750 | grep girl

$

bootmeta의 이미지

첫 0~99 범위 난수 발생 값이 70이하 값(70%확률)이면 0, 그렇지 않으면 다시 원하는 범위 난수 발생

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
 
#define MY_RAND_MAX   10
 
int weight_random( int weight )
{
    return ((random() % 100) <  weight) ? 0: (random() % MY_RAND_MAX);
}
 
int main(void)
{
    srandom((unsigned int) time(NULL));
 
    int i;
 
    for (i = 0; i < 20; i++)
    {
        printf("random value = %d\n",  weight_random(70));
    }
}
terzeron의 이미지

방법은 bootmeta님의 것이 좋습니다. 제가 생각한 것과 똑같은 로직을 작성하셨더군요.

다만, C++에서는 rand() 대신에 srng를 쓸 수 있습니다.
제가 블로그에 적어놓은 내용을 참고하시면 됩니다.

bushi의 이미지

머리가 딸려서, 왜 좋은 방법인지 모두지 알아내지 못하겠습니다.

'난수' 라는 것은 말이죠, 백만스물두개가 모두 같은 수여도 이상할 게 하나도 없는 것 아닌가요 ?
어떤 식의 '예측'도 불가능한 게 좋은 난수발생기잖습니까. 그런데 어떻게 '확률'과 엮입니까 ?

문제에서 '난수'의 '갯수'는 이미 상수로 정해져 있습니다.
그런데 왜 '갯수'를 '확률'적으로 때려맞추기 위해 '난수'를 끌어다붙이는게 좋은 건가요 ?

균일분포인 '난수'를 정규분포화하는 것이라면, 접근 방법이 조금 다르지 싶은데요.

OTL

sangwoo의 이미지

문제가 좀 더 확실히 정의되어야 할 것 같습니다.
0의 갯수가 확실히 고정되어야 하는지, (예를 들어 nxn matrix라면 0의 개수가 n * n * 0.7로 고정되어 있는지) 아니면 random variable이 0이 될 확률이 70%이면 되는 건지 문제만 보면 명확하지가 않네요. 그것부터 먼저 확실히 정해야 할 것 같습니다. 제가 아래에 적은 글은 문제가 후자인 경우입니다.
----
Let's shut up and code.

----
Let's shut up and code.

snowall의 이미지

sangwoo님이 지적하신대로 문제가 명확하지 않은 부분이 있습니다.
sangwoo님이나 bootmeta님의 방법은 0이 나올 확률이 70%이고(즉, 0의 수가 70%가 되지 않을 수도 있지요)
제 방법은 0이 정확히 70%가 들어가 있게 되죠.

저는 문제를 읽고 0이 정확히 70%만큼 들어가 있으면 되는 거라고 해석했습니다.

만약 문제가 0이 나올 확률이 70%인 것으로 충분하다면 bootmeta님의 방법이 더 좋은 겁니다.
--------------------------
snowall의 블로그입니다.
http://snowall.tistory.com

피할 수 있을때 즐겨라! http://melotopia.net/b

bushi의 이미지

'난수' 에 대한 정의를 찾아보고, 다시 본인을 평가해보세요. 점수가 올라갈겁니다.

OTL

snowall의 이미지

제가 난수가 뭔지 몰라서라기보다는, 문제를 해석하는 방법의 차이인 것 같은데요.

--------------------------
snowall의 블로그입니다.
http://snowall.tistory.com

피할 수 있을때 즐겨라! http://melotopia.net/b

bushi의 이미지

0과 RAND_MAX 사이에 있는 임의의 정수라는 조건 외에는 아무런 조건도 없습니다.
규칙이 없어야 한다는 게 규칙이죠. 불규칙이 아니라 무규칙입니다.

문제가 뭐건 간에, 그 문제를 어떤 식으로 해석하건 간에
((random() % 100) < 70) 과 같은 방법으로 확률을 조정할 수 있다는 발상은 항상 틀립니다.

OTL

snowall의 이미지

문제 본문에 "0이 70%, 80%, 90%가 되도록"이라는 표현이 있기 때문에 조건이 생깁니다.

이 조건을 맞추기 위한 풀이가 여러개 제시된 거구요.

--------------------------
snowall의 블로그입니다.
http://snowall.tistory.com

피할 수 있을때 즐겨라! http://melotopia.net/b

auditory의 이미지

"0이 랜덤하게 70% 나와야한다" 라는 문제의 조건에서 모호성이 생깁니다.

1. 0이 정확하게 70%를 차지하면서 랜덤한 순서로 생겨야한다는 것인지,
2. 각각의 숫자를 발생시킬때 발생마다 독립적으로 0.7의 확률로 0이 발생하기를 기대하는것인지,

두가지 모두로 해석가능합니다.

2의 경우 한번의 시행(=n*n개의 숫자발생)에서는 70%의 0이 생기지 않을 수 있지만,
그 시행 횟수를 늘릴수록 평균적으로 70%에 가까와지겠지요.

1의 경우에는 한번의 시행에서도 반드시 70%의 0이 보장되기는 하지만,
각각의 숫자 발생이 서로 독립이 아니고 서로 영향을 주게 됩니다.

전산분야에서는 1번인 경우가 많은것 같습니다만,
수치해석등의 다른 응용분야에서는 2번을 말하는 경우가 더 많습니다.

원글의 문제 (sparse matrix의 곱셈의 연산량 평가인듯..)
의 경우에 2번으로 해석하는것이 더 옳아보이고, (bootmeta님 방법)
여러번의 시행을 해서 평균값을 구하는게 좋겠습니다.

terzeron의 이미지

너무 난수의 정의에만 집착하시는데, 컴퓨터에서 사용하는 난수 발생기라는 것은
어차피 진짜 난수 발생기가 아니라 pseudo random number generator입니다.

게다가 이 문제의 경우 특정한 확률로 0이 나타날 것을 요구하는 사항이 있기 때문에
애초부터 우리가 말하는 난수 발생기의 요건을 충족시키지 못합니다.

그리고 bushi님의 말씀은 상당히 무례하게 들립니다.

bushi의 이미지

의사난수발생기에 대해 언급될 단계가 아직 아닌 것 같은데,
쓰신 글의 전체적인 뉘앙스가
'문제에 따라선 random() 이 의사난수발생기이기때문에 그러한 방법을 적용할 수도 있다'
인 것 같아서 두드리겠습니다.

컴퓨터 프로그램으로 발생시키는 난수를 '의사'라고 부르는 이유는,
똑같은 환경에서 똑같은 절차를 거치면 얼마든 똑같은 결과를 얻는 것이 가능하기 때문에 '의사'라고 부릅니다.
최근에 개나 소나 다 달고 나오는 h/w random 도 마찬가집니다.
똑같은 환경에서 똑같은 절차를 거치는 것을 최대한 방해하도록 s/w 를 구현하면 성능상의 불이익이 있기 때문에
그 대안으로 제공되는 h/w '의사난수발생기'입니다.
보안이 어쩌구저쩌구 암호화가 어쩌구저쩌구하는 시류에 편승한거겠죠.
h/w random 이 s/w random 보다 더 random 해서 더 안전하다의 개념이 아닙니다.
필요할 때 잽싸게 뱉어주자는 거고,
재현에 기술력이 좀 더 필요하면 금상첨화겠지만
어떤 식으로든 재현가능하면, 그러니까 재현이 불가능하다는 것을 증명하지 못하면 모두 '의사'죠.
그래서 '난수발생기는 우주 저 건너편에...'라는 말도 나오잖습니까.

아무튼,
제가 불끈한 것은,
애초에 그럴 듯한 방향을 제시한 분 마저도
문제를 해석하기에 따라 저게 더 좋다며 사마외도의 길로 빠지려해서입니다.
난수발생기를 사용해서 언젠가는 30%가 되는 식을 만들 수 있냐 없냐조차도 (제 모자란 수학때문이지만) 의심스러운데.
잘해야 정규분포로 바꾸는 뭔가를 만들고, 통계적인 기대치에 대한 수학적 근거로 제시할 수 있을까요.

너무 불끈한 것 같아 후회가 되긴 합니다.
불쾌감을 느낀 분들께...
폐를 끼쳐 죄송하고, '저런 사가지 없는 새퀴!' 라고 한마디하시고 풀어주세요.

OTL

snowall의 이미지

음...제가 그 애초에 그럴듯한 방향을 제시한 사람인 것 같아서 질문드리는데요

원래 문제가, 원래 문제의 문장을 어떻게 해석하느냐에 따라 다른 문제가 된다는 건 이해 하셨을 거라고 생각합니다.

그렇다면, 두가지 다른 문제를 푸는데 더 적합한게 있을 거고, 저는 제가 판단하기에 다른 방법이 더 낫다고 생각해서 그게 더 좋다고 의견을 냈는데, 그게 왜 사마외도로 빠지는 길인지가 궁금합니다.
그리고 저는 "만약 문제가 0이 나올 확률이 70%인 것으로 충분하다면 bootmeta님의 방법이 더 좋은 겁니다."라고 해서 조건도 붙였는데 말이죠.

--------------------------
snowall의 블로그입니다.
http://snowall.tistory.com

피할 수 있을때 즐겨라! http://melotopia.net/b

auditory의 이미지


애초에 제시된 그럴듯한 방향이라는것도 이미 널리 사용하는 방법이고,
사마외도의 길이라고 주장하는 방법도 전문 분야에서도 수없이 사용되고 있는 방법입니다.
언젠가는 30%가 당연히 만들어지고, 수학적 근거도 당연히 제시됩니다.
정규분포 이야기를 왜하시는지 모르겠지만(CLT?),
이 토론에서 정규분포는 아무 연관도 없습니다.
의사랜덤도 관련없고요.

bushi의 이미지

의사난수발생기는 ..
random() 처럼 컴퓨터로 만들어내는 난수발생기의 구현자체가 님이 말씀하시는 것과 딴판으로 가짜인데다가
어차피 문제의 요건을 충족하기 위해선 진짜든 가짜든 적용이 불가하다.
.. 라고 제가 이해할 만한 댓글에 답하는 댓글에서 처음 언급됐습니다.
요약하면 '의사와 진짜의 차이는 정밀도나 분포도 뭐 이딴게 아니라 재현가능성일 뿐이다' 구요.
이 댓글 이전에는 한번도 언급된 적이 없으니 토론과 직접적인 관련은 없습니다.

random을 분포로 표현하면 균일분포가 맞을 겁니다.
정규분포는 가운데가 솟아있는 백두산 모양의 그래프고요.
균일분포를 정규분포로 바꾸는 데 적용할만한 기술들과 논문들이 많더군요(이건 방금 검색해 봤으니 확실한 사실입니다).
심지어 언어(혹은 프레임웍)의 기본함수에서 아예 정규분포형태를 가지는 random 을 제공하기도하고요. (이것도 방금 검색)
아무튼, 파라미터 조정해서 양쪽 평탄작업을 좀 하고, 오른쪽 경사면을 날려버리면 원하는 f(x) 가 나올 것이 분명하기에 정규분포를 언급했고,
수학적 근거라는 것도 이것을 얘기한 겁니다.

이 토론은 정규든 아니든간에 '분포'와 밀접한 관계가 있다고 생각하지만,
이 글을 적는 이 시점까지도 자신있게 밀어붙이진 못 하겠습니다.
(사실 의사난수발생기에 대한 언급은 이 '분포'에 대한 토론이 끝나갈 때 쯤 나올 것으로 예상했습니다.)

불쾌감을 느끼실 분들이 또 생길가 걱정되니,
전문분야에서 사용할 정도로 인정받는 정파의 초식 ((random()%100)<70) 에 반기를 들었던 철부지의 헤프닝으로 이쯤에서 그쳤으면합니다.
서로 설득당할 마음이 없는 사람끼리 모여서 계속 떠드는 것 같아 원래 질문 글을 올리셨던 분에게 죄송할 뿐입니다.

OTL

auditory의 이미지

설득하는게 아니라,
잘못된 정보를 너무 자신있게 주장하시길래,
잘못된 부분을 알려드리는겁니다.

자기 생각을 이야기하는건 그게 옳든 그르든 별로 상관없지만,
남의 주장을 틀렸다라고 이야기하려면 본인이 정말 잘 알아야죠.

바로 윗글에도 잘못된 부분이 여러군데 있지만,
말씀하신대로 그만하도록 하죠.

추가로 한가지만 말씀드리면
((random()%100)<70) 이 초식이 균일분포의 랜던변수를
정규분포로 바꾸는것을 가능하게 하는 기본 개념입니다.

sangwoo의 이미지

0~100까지의 숫자를 대상으로, 30%를 0으로 해야 한다고 하면,
저는 아마 -233~100 까지의 숫자를 uniformly generate 한 다음에, 0보다 작은 녀석들은 다 0으로 바꿀 것 같네요.
----
Let's shut up and code.

----
Let's shut up and code.

brucewang의 이미지

문제는 자료분포에서 0의 비율이 70,80,90% 인 세가지 데이터셋을 만들고,
그 데이터셋을 랜덤하게 배열해 놓으면 되는것 아닌가요?

데이터셋을 만들지 않고 그자리에서 출력하는 것이라면
총 loop 중에 7,8,90% check point만 우선 만들어 놓은 다음에
그 point 가 아닌 부분은 0이외의 랜덤값을 집어 넣으면 되겠네요.

지정된 분포 그대로 값이 나오는 면에서 snowall님의 첫 구현이 의도에 근접한 것 같네요.

-------------------------------------------------
$yes 4 8 15 16 23 42

-------------------------------------------------
$yes 4 8 15 16 23 42

익명 사용자의 이미지

0과 1사이 균일분포 난수발생기 c코드 어떻게 만들죠??

익명 사용자의 이미지

그냥 0~99개의 숫자중에 0이 70%라면..
1~99 즉 99개의 숫자가 30%가 될때 나머지 70% 숫자의 갯수가 몇개냐인걸 보면되요.
그럼 231이 나옵니다.

즉 231+99 = 330이라는 값이 나오는데.
-230 ~ 99까지의 숫자중 0 이하는 다 0이 나온것으로 가정하면 0이 확률적으로 70%가 되어서 찍히게됩니다.

익명 사용자의 이미지

원래 글 작성자의 글을 잘 읽어보면 0이 나올 확률이 70%라고 하지 않고, 0의 비율이 70%라고 하고 있습니다.
즉 10x10 행렬이라면 0의 개수가 딱 70개 나오면 됩니다.

random()을 중첩한다던지, -230~99사이의 랜덤 넘버를 만드는 것은 그런 행렬을 많이 만들면 만들수록 70%에 근접하게 되겠지만 일률적으로 딱 70개가 나오지는 않게 되겠죠.

또한 원래 글을 잘 읽어보면 0의 비율이 70%라고만 했지, 0 이외의 숫자가 1~99라는 식으로 특정하지 않았습니다. 예를 들어 '행렬의 요소는 unsigned int면 된다'는 조건이라면 확률 70% 조건이라도 -230~99와 같은 방법으로는 말끔한 구현이 나오기 힘듭니다.

원래 글만 본다면, 맨처음 답변이 가장 정확한 답변으로 보입니다. 0의 비율이 70%인 NxN 행렬을 만드는 것이지, 0이 나올 확률이 70%인 random 함수를 구현하는 문제가 아니니까요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.