随机数及按照概率生成随机数

实例一简单生成随机数:

#include <iostream>
#include <cstdlib>
using namespace std;

int Random(double min, double max);

int main(int argc, char *argv[])
{
	srand((int)time(NULL));
	int t=0;
    for(int i=0;i<10;++i)
	{
        t = Random(1, 11);
		cout << t << " ";
	}
	cout << endl;
    return 0;
}

int Random(double start, double end)
{
	return start+(end-start)*rand()/(RAND_MAX + 1.0);
}


这种种子如果在第二天会出现大量重复数据,不符合连续长时间的应用


实例二,主要改进种子的产生

#include <iostream>
#include <cstdlib>
#include <sys/timeb.h>
using namespace std;

int Random(double min, double max);

int main(int argc, char *argv[])
{
	unsigned int seedVal;
	struct timeb timeBuf;
    ftime(&timeBuf);
    seedVal=((((unsigned int)timeBuf.time & 0xFFFF)+
			  (unsigned int)timeBuf.millitm)^
			 (unsigned int)timeBuf.millitm);
    srand((unsigned int)seedVal);
	int t=0;
    for(int i=0;i<10;++i)
	{
        t = Random(1, 11);
		cout << t << " ";
	}
	cout << endl;
	
	cout << timeBuf.millitm << " " << ( timeBuf.millitm^timeBuf.millitm) << endl;

    return 0;
}

int Random(double start, double end)
{
	return start+(end-start)*rand()/(RAND_MAX + 1.0);
}



实例三,不产生重复数据的随机方法

#include <iostream>
#include <cstdlib>
#include <sys/timeb.h>
using namespace std;

int N=100,M=10;
int a[100],b[100];
int Random(double min, double max);
int NorepeatRandom(double start, double end);
int NorepeatRandom2(double start, double end);
int main(int argc, char *argv[])
{
	unsigned int seedVal;
	struct timeb timeBuf;
    ftime(&timeBuf);
    seedVal=((((unsigned int)timeBuf.time & 0xFFFF)+
			  (unsigned int)timeBuf.millitm)^
			 (unsigned int)timeBuf.millitm);
    srand((unsigned int)seedVal);
	//	NorepeatRandom(0,0);
	NorepeatRandom2(0,0);
    for(int i=0; i< M;++i)
	{
		cout << b[i] << " ";
	}
	cout << endl;
    return 0;
}
//repeat random
int Random(double start, double end)
{
	return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
//not repeate random

int NorepeatRandom(double start, double end)
{
	int i,j,k;
	for (i=0;i<N;i++)
		a[i]=i+1;
	for(i=0;i<M;i++)
     	{
		   j=rand()%(N-i);
		   b[i]=a[j];
		for(k=j;k<N-i-2;k++)
			a[k]=a[k+1];

	}
}

int NorepeatRandom2(double start, double end)
{
	int i=0;
	for(i=0;i<N;i++)
	{
		a[i]=i+1;		
	}
	i = rand()%(N-1);
	a[i] = 1;
	b[0] = i;
	for(int j=1;j< M;)
	{
		while((i=rand()%N) && (a[i]!= 1))
		{
			b[j++] = i;
			a[i] = 1;
			break;
		}
	}
}



实例四,按照一定概率产生随机数(概率为100%)

方法举例:1 20% 2 30% 3 50%

可以将20个1,30个2 , 50 个3 随机放入数组中,然后随机1-100,拿出对应数字下标下的数字。

方法二:

按照概率进行区间划分

10个数字1 2 代表1,3 4 5代表3, 6 7 8 9 10代表数字5,从而产生一定概率的随机数字

实例:

#include <iostream>
#include <cstdlib>
#include <sys/timeb.h>
using namespace std;

int Random(double min, double max);

int main(int argc, char *argv[])
{
	unsigned int seedVal;
	struct timeb timeBuf;
    ftime(&timeBuf);
    seedVal=((((unsigned int)timeBuf.time & 0xFFFF)+
			  (unsigned int)timeBuf.millitm)^
			 (unsigned int)timeBuf.millitm);
    srand((unsigned int)seedVal);
    //1 20% 2 30% 3 50%
	int i = 0, t;
	int n1=0,n2=0,n3=0;
	while(++i<100000)
	{
		t = Random(1, 11);
		if(t<=0 || t>10)
			break;
		switch(t)
		{
		case 1:
		case 2:
			++n1;
			break;
		case 3:
		case 4:
		case 5:
			++n2;
			break;
		case 6:
		case 7:
		case 8:
		case 9:
		case 10:
			++n3;
			break;
		defalt:
			break;
		}
		
	}
	cout << ((double)n1/100000*100) << "% " << ((double)n2/100000*100) << "% "<<((double)n3/100000*100) <<"% "<< endl;
    return 0;
}

int Random(double start, double end)
{
	return start+(end-start)*rand()/(RAND_MAX + 1.0);
}



实例5,按照一定概率产生随机数(非100%)

代码示例:

int a=20,b=7,c=13,d=9,e=15; a概率为20/64=0.3125 b 7/64=0.1093........

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <map>
#include <sys/timeb.h>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;

int Random(double min, double max);
int Random2(int low, int high);
void shuffle2(int* cards, int n);
string num2str(int num)
{
	stringstream ss;
	ss << num;
	return ss.str();
}

int main(int argc, char *argv[])
{
	unsigned int seedVal;
	struct timeb timeBuf;
    ftime(&timeBuf);
    seedVal=((((unsigned int)timeBuf.time & 0xFFFF)+
			  (unsigned int)timeBuf.millitm)^
			 (unsigned int)timeBuf.millitm);
    srand((unsigned int)seedVal);
	int a=20,b=7,c=13,d=9,e=15;
	int tol = a+b+c+d+e;
	int *arr = new int[tol];
	for(int i=0;i<a;++i)
		arr[i]=1;
	for(int i=a;i<a+b;++i)
	{
		arr[i]=2;
	}
	for(int i=a+b;i<a+b+c;++i)
		arr[i]=3;
	for(int i=a+b+c;i<a+b+c+d;++i)
		arr[i]=4;
	for(int i=a+b+c+d;i<tol;++i)
		arr[i] = 5;
	shuffle2(arr, tol);
	for(int i=0;i<tol;++i)
	{
		cout << arr[i]<<" ";
	}
	cout << endl;
	int tmparr[tol];
	memcpy(&tmparr[0], &arr[0], sizeof(tmparr));
	for(int i=0;i<tol;++i)
	{
		cout << tmparr[i]<<" ";
	}
	cout << endl;
    int j=0,pos;
	int tmp[4];
	int i=0;
	string s,s1,s2,s3,s4;
	ofstream outfile("./record", ofstream::out|ofstream::app);
	while(++i<1000000)
	{
		while(1)
		{
			pos = Random2(1,55);
			if(tmparr[pos]<0)
				continue;
			if(j==4)
				break;
			tmp[j] = tmparr[pos];
			for(int i=0;i<tol;++i)
			{
				if(tmparr[i] == tmp[j])
					tmparr[i] = -1;
			}	
			j++;
		}

		s1 = num2str(tmp[0]);
		s2 = num2str(tmp[1]);
		s3 = num2str(tmp[2]);
		s4 = num2str(tmp[3]);
		s = s1+"|"+s2+"|"+s3 + "|"+s4;
		cout << s <<endl;
		if(!outfile)
			cout << "open record file error\n";
		outfile<< s <<endl;
		outfile<<endl;
		cout << endl;
		memset(tmp,0, sizeof(int));
		memcpy(&tmparr[0], &arr[0], sizeof(tmparr));
		j=0;
 
	}
	outfile.clear();
	outfile.close();

    return 0;
}

int Random(double start, double end)
{
	return start+(end-start)*rand()/(RAND_MAX + 1.0);
}

int Random2(int low, int high)
{
	return low + rand() % (high - low + 1);
}
void shuffle2(int* cards, int n)
{

    for (int i = 0; i < n; i++)
    {
        int rand = Random2(0, i);
        int temp = cards[rand];
        cards[rand] = cards[i];
        cards[i] = temp;
    }
}

可能随机数产生还是不够精却

分析结果:

total=999999
1=0.328019%
2=0.127217%
3=0.181625%
4=0.126948%
5=0.23619%

还有一种思路:

int a=20,b=7,c=13,d=9,e=15

总和为:64,随机1-64的数,假如为34, a+b+c >34,则随机数为13,然后将c置为0,在求和,再次随机,依次下去...假设随机3个数字终止。

实例:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
static int k[6][2];
int a[] = {12, 34, 21, 32, 9, 16}; //设定概率
void initdata()
{
	srand(time(NULL));
	for(int i=0;i<6;++i)
	{
		k[i][0] += a[i];
	}
	for(int i=0;i<6;++i)
	{
		k[i][1] = 0;
	}

}

void setarray()
{
	for(int i=0;i<6;i++)
	{
		k[i][1] = 0;
	}
}

int getonerand()
{
	int tol = 0;
	for (int i=0; i<6; i++)
	{
		if (k[i][1] == 0)
			tol = tol + k[i][0];
	}
	int d = 1+(int)(1.0*tol*rand()/(RAND_MAX+1.0));
	int tmpsum = 0;
	for(int i=0; i<6; i++)
	{
		if (k[i][1] == 0)
		{
			tmpsum = tmpsum + k[i][0];
			if (tmpsum >= d)
			{
				k[i][1] = 1;
				return (i);
			}
		}
	}

}

int main(int argc, char *argv[])
{
    initdata();

	int j=0;
	while(j++ < 30)
	{
		for(int i=0;i<4;++i)
		{
			int t = getonerand();
			cout << a[t] << " ";
		}
		cout << endl;
		setarray();
	}
    return 0;
}


利用简单洗牌算法生成不重复的随机数:

void shuffle2(int* cards, int n)
{
    // 随机i-1中的任意一个数与i交换
    for (int i = 0; i < n; i++)
    {
        int rand = Random2(0, i);
        int temp = cards[rand];
        cards[rand] = cards[i];
        cards[i] = temp;
    }
}

int* shuffle(int* cards, int n)
{
    if (n <= 0)
        return cards;
 
    shuffle(cards, n - 1);
    int rand = Random2(0, n); 
    int temp = cards[rand];
    cards[rand] = cards[n];
    cards[n] = temp;
 
    return cards;
}

5.产生一定范围随机数的通用表示公式
要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。
要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。
要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。




  • 15
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值