#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int getrandom(int min,int max);
void main()
{
int i,total=0;
int x[6]={0,37,49,52,20,40};
int n[6]={0,1,2,3,4,5};
int v[6]; //マーキング
int t=0; //カウント
int r=0,range=0;
srand((unsigned)time(NULL));
while(t != 5){
for(i=1;i<=5;i++){
if(v[i]==0){
total+=x[i];
}
}
//printf("total=%d\n",total);
r=getrandom(0,total);
//printf("r=%d\n",r);
for(i=1;i<=5;i++){
if(v[i]==0 && range<r && r<=x[i]+range){
printf("%d\n",n[i]);
v[i]=1;
t++;
break;
}
range=x[i]+range;
}
total=0;
}
}
int getrandom(int min,int max)
{
return min+(int)(rand()*(max-min+1.0)/(1.0*RAND_MAX));
}
乱数について
-
はじめたばかり
乱数について
Re: 乱数について
少なくともメモリ破壊はなさそうですし、最適化のバグもそうそう起こらないと思います。
理想の出力例を示していただけますか?
理想の出力例を示していただけますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 乱数について
おそらく、まず配列xの内容を先に累積和に変換し、
出た乱数の値がxのどこの間に当たるかを二分探索するのがいいと思います。
出た乱数の値がxのどこの間に当たるかを二分探索するのがいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 乱数について
配列vの内容が不定なので、たまたまv[1]~v[5]がすべて0になっていなかった場合、無限ループになりそうです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
-
はじめたばかり
Re: 乱数について
みけCAT さんが書きました:配列vの内容が不定なので、たまたまv[1]~v[5]がすべて0になっていなかった場合、無限ループになりそうです。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int getrandom(int min,int max);
void main()
{
int i,total=0;
int x[6]={0,37,49,52,20,40};
int n[6]={0,1,2,3,4,5};
int v[6]={0,0,0,0,0,0}; //マーキング
int t=0; //カウント
int r=0,range=0;
srand((unsigned)time(NULL));
while(t != 5){
for(i=1;i<=5;i++){
if(v[i]==0){
total+=x[i];
}
}
//printf("total=%d\n",total);
r=getrandom(0,total);
//printf("r=%d\n",r);
for(i=1;i<=5;i++){
if(v[i]==0 && range<r && r<=x[i]+range){
printf("%d\n",n[i]);
v[i]=1;
t++;
range=0;
break;
}
range=x[i]+range;
}
total=0;
}
}
int getrandom(int min,int max)
{
return min+(int)(rand()*(max-min+1.0)/(1.0*RAND_MAX));
}
Re: 乱数について
12行目を追加したのはいいことだと思います。
32行目は蛇足だという気がしますが、仕様がわからないので何とも言えません。
32行目は蛇足だという気がしますが、仕様がわからないので何とも言えません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 乱数について
そもそも、最初の「乱数が何回も発生してしまう」というのは仕様ではないのですか?
乱数を1回しか発生させずに全てを選択したいということですか?
逆に、最初の26行目の文を表示させなければ、乱数が何回も発生してしまうことはない、という認識でいいですか?
乱数を1回しか発生させずに全てを選択したいということですか?
逆に、最初の26行目の文を表示させなければ、乱数が何回も発生してしまうことはない、という認識でいいですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
-
はじめたばかり
Re: 乱数について
そうですが、乱数が何回も発生してしまいプログラムが終わらないんです。みけCAT さんが書きました:そもそも、最初の「乱数が何回も発生してしまう」というのは仕様ではないのですか?
乱数を1回しか発生させずに全てを選択したいということですか?
逆に、最初の26行目の文を表示させなければ、乱数が何回も発生してしまうことはない、という認識でいいですか?
乱数を発生させて1,2,3,4,5の数字だしたいんです。乱数の値が0~37の間なら1、38~86なら2、87~138なら3、139~158なら4、159~198なら5という感じです。一つ表示させたら、残りの4つの数字の中からまた乱数で表示させます。
26行目を表示させなければ、プログラムは動くときが多いんですが時間が少しかかるのでもっと精度の高いものを作りたいと思ってます。乱数が何回表示されてるかはわかりません。
Re: 乱数について
この方針で実装してみました。みけCAT さんが書きました:おそらく、まず配列xの内容を先に累積和に変換し、
出た乱数の値がxのどこの間に当たるかを二分探索するのがいいと思います。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define DEBUG
int getrandom(int min,int max);
#define N_MAX 5
int main(void) {
int x[N_MAX+1]={0,37,49,52,20,40};
int n[N_MAX]={1,2,3,4,5};
int got[N_MAX]={};
int i;
srand((unsigned)time(NULL));
for(i=0;i<N_MAX;i++) {
int ruiseki[N_MAX+1];
int j;
int r;
int left,right,mid;
int nowid;
ruiseki[0]=x[0];
for(j=1;j<=N_MAX;j++) {
ruiseki[j]=ruiseki[j-1];
if(!got[j-1])ruiseki[j]+=x[j];
}
r=getrandom(0,ruiseki[N_MAX]-1);
#ifdef DEBUG
fprintf(stderr,"ruiseki: ");
for(j=0;j<=N_MAX;j++)fprintf(stderr,"%d ",ruiseki[j]);
fprintf(stderr,"\nr = %d\n",r);
#endif
left=0;right=N_MAX-1;
while(left<=right) {
mid=(left+right)/2;
if(ruiseki[mid]>r)right=mid-1; else left=mid+1;
}
nowid=left-1;
#ifdef DEBUG
fprintf(stderr,"nowid = %d\n",nowid);
#endif
printf("%d\n",n[nowid]);
got[nowid]=1;
}
return 0;
}
#if 0
/* この乱数ではmaxを超える値が出る可能性がある */
int getrandom(int min,int max)
{
return min+(int)(rand()*(max-min+1.0)/(1.0*RAND_MAX));
}
#else
/* 苦Cより http://9cguide.appspot.com/21-02.html */
int GetRandom(int min,int max)
{
return min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX));
}
int getrandom(int min,int max){return GetRandom(min,max);}
#endif
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 乱数について
例えばmin=0,max=1で、rand()でRAND_MAXが返ってきたとすると、
RAND_MAX*(1-0+1.0)/(1.0*RAND_MAX)=(RAND_MAX*2.0)/(1.0*RAND_MAX)=2.0
となり、maxの1を超える可能性があると思いました。
RAND_MAX*(1-0+1.0)/(1.0*RAND_MAX)=(RAND_MAX*2.0)/(1.0*RAND_MAX)=2.0
となり、maxの1を超える可能性があると思いました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)