多少个0到1之间的随机数之和大于1?

一个简单的01背包问题
服务器君一共花费了163.054 ms进行了4次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

数学常数最令人着迷的就是,它们常常出现在一些看似与之毫不相干的场合中。 随便取一个 0 到 1 之间的数,再加上另一个 0 到 1 之间的随机数,然后再加上一个 0 到 1 之间的随机数??直到和超过 1 为止。一个有趣的问题:平均需要加多少次,才能让和超过 1 呢?答案是 e 次,自然对数。

下面用程序模拟:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 11
int main()
{
	int sum = 0;
	int i, wait;
	double val, random;
	srand(time(NULL));
	for (i=0; i<NUM; i++)
	{
		val = 0;
		while(val <1)
		{
			random = rand()/(double)RAND_MAX;
			printf("%f \n", random);
			val+=random;
			sum++;
		}
		printf("第%d次测试完毕 \n", i);
	}
	printf("平均需要 %f 次 \n",sum/(double)NUM);
	scanf("%d", &wait);
	return 0;
}

程序运行结果:

  
0.857692
0.320536
第0次测试完毕
0.147221
0.663350
0.700186
第1次测试完毕
0.613086
0.967589
第2次测试完毕
0.633747
0.918577
第3次测试完毕
0.297678
0.709006
第4次测试完毕
0.580554
0.894955
第5次测试完毕
0.927702
0.112247
第6次测试完毕
0.578814
0.012268
0.030488
0.066317
0.048189
0.252083
0.439344
第7次测试完毕
0.238136
0.988189
第8次测试完毕
0.114628
0.657918
0.603290
第9次测试完毕
0.511704
0.642293
第10次测试完毕
平均需要 2.636364 次

下面我们修改下程序,比如测试10000组数据,然后算平均次数:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10000
int main()
{
	int sum = 0;
	int i, wait;
	double val, random;
	srand(time(NULL));
	for (i=0; i<NUM; i++)
	{
		val = 0;
		while(val <1)
		{
			random = rand()/(double)RAND_MAX;
			//printf("%f \n", random);
			val+=random;
			sum++;
		}
		//printf("第%d次测试完毕 \n", i);
	}
	printf("平均需要 %f 次 \n",sum/(double)NUM);
	scanf("%d", &wait);
	return 0;
}

程序运行结果:

平均需要 2.727400 次

这个值就非常接近自然对数e,其值约等于2.718281828。

那么我们可以打印出这100000个测试数据,然后统计,需要1个随机数和就大于等于1有几组测试数据,需要2个随机数和就大于等于1有几组测试数据。。。把其分布打印出来。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TIMES 100000
#define COUNT 11
int main(void)
{
	int i,j;
	double sum,ave;
	long int Sum =0;
	int count[TIMES] = {0};
	int number[COUNT] = {0};
	srand(time(NULL));
	for(i=0;i<TIMES;i++)
	{
		sum = 0;
		while(sum<1)
		{
			sum += rand()/(double)RAND_MAX;
			count[i]++;
		}
	}
	for(i=0;i<TIMES;i++)
	{
		for(j=1;j<COUNT;j++)
		{
			if(count[i] == j)
			number[j]++;
		} 
	}
	for(j=1;j<COUNT;j++)
	{
		printf("%d\t%d\t%f\n",j,number[j],number[j]/(double)TIMES);
	}
	for(i=0;i<TIMES;i++)
	{
		Sum += count[i];
	}
	ave = Sum/(double)TIMES;
	printf("%f\n",ave);
	//system("ping -n 2 127.0.0.1 >NUL 2>NUL");
	getch(); 
}

程序运行结果:

1       4       0.000040
2       49817   0.498170
3       33620   0.336200
4       12360   0.123600
5       3344    0.033440
6       744     0.007440
7       94      0.000940
8       14      0.000140
9       3       0.000030
10      0       0.000000
2.719190

本文地址:http://www.nowamagic.net/librarys/veda/detail/467,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/467

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《设计模式:可复用面向对象软件的基础》 Erich Gamma (作者), Richard Helm (作者), Ralph Johnson (作者), John Vlissides (作者), 李英军 (译者), 等 (译者)

《设计模式:可复用面向对象软件的基础》是引导读者走出软件设计迷宫的指路明灯,凝聚了软件开发界几十年设计经验的结晶。四位顶尖的面向对象领域专家精心选取了最具价值的设计实践,加以分类整理和命名,并用简洁而易于重用的形式表达出来。本书已经成为面向对象技术人员的圣经和词典,书中定义的23个模式逐渐成为开发界技术交流所必备的基础知识和语汇。

更多计算机宝库...