Picasa的网络相册无法正常打开,页面中的图片显示不了。本想采用自己的空间重新传图,但暂时没有时间修复。想看原网络相册的同学可以移步百度搜索一下,看能否解决。最新的图片除了首页为了效果手工传图。以后如果需要,所有的图片将重新更新链接。
在并行计算机上写计算程序的记录一
[
2007/02/20 09:47 | by 酒而久之 ]
2007/02/20 09:47 | by 酒而久之 ]
我的毕业论文主要的内容是写一个模拟程序。
程序将在小型计算机上运行,这就需要使用并行的方法进行程序设计。
我使用的是较为常规的MPI完成的。
积累的一些个人经验在这里写出来,如果能对大家有一些帮助最好不过;如果有什么错误,请您指点,谢谢
我使用的并行计算机是SGI的altix3700,是共享存储的小型机。但我没有使用OPENMP编程技术,因为个人认为在集群化的形势下,MPI可能更常规一些。
这台计算机的软件方面有intel的商业版编译器、一些高性能库和并行库;使用PBSPro作为作业管理系统。
程序将在小型计算机上运行,这就需要使用并行的方法进行程序设计。
我使用的是较为常规的MPI完成的。
积累的一些个人经验在这里写出来,如果能对大家有一些帮助最好不过;如果有什么错误,请您指点,谢谢
我使用的并行计算机是SGI的altix3700,是共享存储的小型机。但我没有使用OPENMP编程技术,因为个人认为在集群化的形势下,MPI可能更常规一些。
这台计算机的软件方面有intel的商业版编译器、一些高性能库和并行库;使用PBSPro作为作业管理系统。
资本模拟程序的再次更新
[
2006/03/10 23:17 | by 酒而久之 ]
2006/03/10 23:17 | by 酒而久之 ]
为了使程式更加的突出真实性,又增加了一个参数。
现在的全部假设是:
1.每个人在最开始的资本是一定的。
这是个很强的假设,但是如果没有这个假设我们无法研究资本的流向,毕竟要控制一定的变量。
2.每个人在最开始有一个在0.49到0.59之间的存款系数
统计表明近几年国内的平均储蓄比率为0.46,也就是说“投资”率是0.54。
3.每个人会根据他在上一轮的交易中的获利或者亏损状况调节他下次的投资比例。
这个符合一般的心理,人越赚钱越胆大呵呵。
为了清晰,我没有再原来的基础上修改,而是全部重写了代码。使用了“结构”来使代码更加可度。
得到的结果是,这样的心理会让资本的集中程度降低,有钱的人还是少数,但是资本被更多的人分享了。
现在的全部假设是:
1.每个人在最开始的资本是一定的。
这是个很强的假设,但是如果没有这个假设我们无法研究资本的流向,毕竟要控制一定的变量。
2.每个人在最开始有一个在0.49到0.59之间的存款系数
统计表明近几年国内的平均储蓄比率为0.46,也就是说“投资”率是0.54。
3.每个人会根据他在上一轮的交易中的获利或者亏损状况调节他下次的投资比例。
这个符合一般的心理,人越赚钱越胆大呵呵。
为了清晰,我没有再原来的基础上修改,而是全部重写了代码。使用了“结构”来使代码更加可度。
得到的结果是,这样的心理会让资本的集中程度降低,有钱的人还是少数,但是资本被更多的人分享了。
今天同学要模拟下面这种操作:
一共1000人;
每个人初始的资本是100元(这里仅仅考虑整数);
随机的抽取其中的两个人让他们发生资本的流动,其中有一个随机的流动系数(0-1之间)
做这种操作:
两人总资本=甲的资本+乙的资本;
甲的交易后资本=流动系数×两人总资本;
乙的交易后资本=两人总资本-甲的交易后资本;
这种操作进行100万次。
现在考虑每个人的资本情况(横轴为人的编号,纵轴为对应的剩余资本)作图
得到的就是在不同资本数的人的数量分布如下图:

吓我一大跳,资本流向了少数的几个人,大多数人都亏本了。
好像赌博一样,有人出老千呵呵。
我不知道怎么解释这个现象。我错了?
下面是程序代码:
#include
#include
#include
#define N 1000 //人数
#define T 1000000 //交易次数
int random(void) //生成随机数 暂时是有序的
{
int r;
r=rand()%N;
return r;
}
main()
{
//初始化
// char fname[8];
FILE *fp;
int people[N][3]; //.1编号 .2现金数量 .3开关
int p1,p2; //交易对象编号
int total;//交易双方金额总和
float j;//交易系数
int i,temp; //无用变量
for(i=0;i {
people[ i][0]=i;
people[ i][1]=100; //初始现金为100
people[ i][2]=0; //初始开关0为未选中状态
}
//交易过程
srand(time(NULL)); // 这句话是开关,打开了就会生成随机数;调试时注释可以每次以相同种子生成
for (i=0;i<=T;i++)
{
temp=random();
while(people[temp][2]==1)
{
temp=random();
}
p1=temp;
people[p1][2]=1;//选定第一个人
temp=random();
while(people[temp][2]==1)
{
temp=random();
}
p2=temp;
people[p2][2]=1;//选定第二个人
j=sqrt(random())/N*10; //0~1之间 这个计算是保证每次交易使用资金的百分之十的级别
total=people[p1][1]+people[p2][1];
people[p1][1]=j*total;
people[p2][1]=total-people[p1][1]; //交易完成
people[p1][2]=0;//释放状态
people[p2][2]=0;
}
//printf("输入文件名n");
//scanf("%s",fname);
fp=fopen("fname.txt","w+");
for (i=0;i {
printf("%dt%dtn",people[ i][0],people[ i][1]);
fprintf(fp,"%dt%dtn",people[ i][0],people[ i][1]);
}
fclose(fp);
}
写这个程序的时候学习到了一点东西:
【随机生成中的RAND_MAX】
这是一个内部定义的数,默认的最小值是32768,第一次知道是最小值。rand()生成的序列就是从0到RAND_MAX的伪随机数。
【随机序列是一定的】
相同的种子用rand()函数生成的随机数序列是一样的,这样我们调试程序才有对比和参照。
【可以使用种子生成更好的随机数】
srand()函数是用来定义种子的,time()取得系统的时间,这样得到的随机序列是比较好的。
【生成0~100的随机数的方法】
有高手说“用脚趾头想想都知道”rand()%100,当然一个正整数除以100的余数当然是100以内的。
【来自http://sms.lnd.com.cn/club/dispbbs.asp?boardid=41&id=312938】
随机数的生成:rand()和srand()函数
以下,介绍船长最喜欢的两个函数,它们的出现使C语言变得十分有趣。(个人意见)
RPG游戏弟兄们都玩过吧,其中有一种遇敌方式是踩地雷,就在当主角在地图上走的时候动不动冒出三两小兵挑衅兼找死。(烦不胜烦,船长在玩这类游戏时曾无数次想874“踩地雷”的发明者)它的实现方式是设主角所立位置为0,主角每走一步,变量加1,当变量==随机取得的数时,小兵出现。
本文要讨论的内容就是,在C语言中,是如何取得这个随机数的?
一个语句:rand();
它的作用就是随机取0到RAND_MAX之间的任何数。ANSI标准指出,RAND_MAX值的范围到少是32767,也就是双字节整数的最大值。
下面我们用一个例子来取得从1到6的随机整数:
#include
#include
main()
{
int i;
for(i=1;i<=20;i++)
printf("%10d",1+(rand()%6));
}
第2行的stdlib.h是rand()函数的头文件,第7行就是
实现功能的语句了。前面我们以经说过函数取的值是介于0到RANDMAX之前的,而我们所要的是1到6之间的整数。用脚想一想就知道:任一整数除以6所得的余数是0~5之间的整数,再加一之后就是1到6了,也就是我们的目标。利用这个原理我们使用%号对随机数进行了缩放。
OK,运行两次程序:
一:6 6 5 5 6 5 1 1 5 3 6 6 2 4 2 6 2 3 4 1
二:6 6 5 5 6 5 1 1 5 3 6 6 2 4 2 6 2 3 4 1
发现:两次运行的结果完全一样。
结论:这算什么随机数。
具有讽刺意味的是,这种重复性是rand的一个重要特点,在调试程序时,这种重复性是必不可少的,因为它可以证明对程序的修改能够正常运行。
实际上,rand函数产生的是伪随机数。但我们需要的是随机数。于是,我们需要对程序进行随机化,这需要使用标准库函数srand来实现。函数srand需要一个无符号的整型参数,在每次程序执行时用函数rand去生在一组不同的随机数。如下例:
#include
#include
main()
{
int i;
unsigned seed;
printf("Enter a seed:");
scanf("%u",&seed);
srand(seed);
for( i = 1;i<=20;i++)
printf(""%10d",1+(rand()%6));
}
程序的运行结果是当我们输入不同的SEED时,产生不同组的随机数。这句话的意思有两个:一:当输入相同的SEED时,产生的同组随机数;二:每次运行我们都要输入一个SEED。
如果我们希望不用每次输入SEED值,而且每次运行时SEED值都是不同的,我们可以用下面语句代替上面的第三块的三个语句:
srand(time(NULL));
这会使计算机自动读取自己的时钟以获得SEED值。于是我们就获值了每次运行都会改变的SEED,同样也就获得了真正的随机数。【还不是真正的呵呵】
一共1000人;
每个人初始的资本是100元(这里仅仅考虑整数);
随机的抽取其中的两个人让他们发生资本的流动,其中有一个随机的流动系数(0-1之间)
做这种操作:
两人总资本=甲的资本+乙的资本;
甲的交易后资本=流动系数×两人总资本;
乙的交易后资本=两人总资本-甲的交易后资本;
这种操作进行100万次。
现在考虑每个人的资本情况(横轴为人的编号,纵轴为对应的剩余资本)作图
得到的就是在不同资本数的人的数量分布如下图:

吓我一大跳,资本流向了少数的几个人,大多数人都亏本了。
好像赌博一样,有人出老千呵呵。
我不知道怎么解释这个现象。我错了?
下面是程序代码:
#include
#include
#include
#define N 1000 //人数
#define T 1000000 //交易次数
int random(void) //生成随机数 暂时是有序的
{
int r;
r=rand()%N;
return r;
}
main()
{
//初始化
// char fname[8];
FILE *fp;
int people[N][3]; //.1编号 .2现金数量 .3开关
int p1,p2; //交易对象编号
int total;//交易双方金额总和
float j;//交易系数
int i,temp; //无用变量
for(i=0;i
people[ i][0]=i;
people[ i][1]=100; //初始现金为100
people[ i][2]=0; //初始开关0为未选中状态
}
//交易过程
srand(time(NULL)); // 这句话是开关,打开了就会生成随机数;调试时注释可以每次以相同种子生成
for (i=0;i<=T;i++)
{
temp=random();
while(people[temp][2]==1)
{
temp=random();
}
p1=temp;
people[p1][2]=1;//选定第一个人
temp=random();
while(people[temp][2]==1)
{
temp=random();
}
p2=temp;
people[p2][2]=1;//选定第二个人
j=sqrt(random())/N*10; //0~1之间 这个计算是保证每次交易使用资金的百分之十的级别
total=people[p1][1]+people[p2][1];
people[p1][1]=j*total;
people[p2][1]=total-people[p1][1]; //交易完成
people[p1][2]=0;//释放状态
people[p2][2]=0;
}
//printf("输入文件名n");
//scanf("%s",fname);
fp=fopen("fname.txt","w+");
for (i=0;i
printf("%dt%dtn",people[ i][0],people[ i][1]);
fprintf(fp,"%dt%dtn",people[ i][0],people[ i][1]);
}
fclose(fp);
}
写这个程序的时候学习到了一点东西:
【随机生成中的RAND_MAX】
这是一个内部定义的数,默认的最小值是32768,第一次知道是最小值。rand()生成的序列就是从0到RAND_MAX的伪随机数。
【随机序列是一定的】
相同的种子用rand()函数生成的随机数序列是一样的,这样我们调试程序才有对比和参照。
【可以使用种子生成更好的随机数】
srand()函数是用来定义种子的,time()取得系统的时间,这样得到的随机序列是比较好的。
【生成0~100的随机数的方法】
有高手说“用脚趾头想想都知道”rand()%100,当然一个正整数除以100的余数当然是100以内的。
【来自http://sms.lnd.com.cn/club/dispbbs.asp?boardid=41&id=312938】
随机数的生成:rand()和srand()函数
以下,介绍船长最喜欢的两个函数,它们的出现使C语言变得十分有趣。(个人意见)
RPG游戏弟兄们都玩过吧,其中有一种遇敌方式是踩地雷,就在当主角在地图上走的时候动不动冒出三两小兵挑衅兼找死。(烦不胜烦,船长在玩这类游戏时曾无数次想874“踩地雷”的发明者)它的实现方式是设主角所立位置为0,主角每走一步,变量加1,当变量==随机取得的数时,小兵出现。
本文要讨论的内容就是,在C语言中,是如何取得这个随机数的?
一个语句:rand();
它的作用就是随机取0到RAND_MAX之间的任何数。ANSI标准指出,RAND_MAX值的范围到少是32767,也就是双字节整数的最大值。
下面我们用一个例子来取得从1到6的随机整数:
#include
#include
main()
{
int i;
for(i=1;i<=20;i++)
printf("%10d",1+(rand()%6));
}
第2行的stdlib.h是rand()函数的头文件,第7行就是
实现功能的语句了。前面我们以经说过函数取的值是介于0到RANDMAX之前的,而我们所要的是1到6之间的整数。用脚想一想就知道:任一整数除以6所得的余数是0~5之间的整数,再加一之后就是1到6了,也就是我们的目标。利用这个原理我们使用%号对随机数进行了缩放。
OK,运行两次程序:
一:6 6 5 5 6 5 1 1 5 3 6 6 2 4 2 6 2 3 4 1
二:6 6 5 5 6 5 1 1 5 3 6 6 2 4 2 6 2 3 4 1
发现:两次运行的结果完全一样。
结论:这算什么随机数。
具有讽刺意味的是,这种重复性是rand的一个重要特点,在调试程序时,这种重复性是必不可少的,因为它可以证明对程序的修改能够正常运行。
实际上,rand函数产生的是伪随机数。但我们需要的是随机数。于是,我们需要对程序进行随机化,这需要使用标准库函数srand来实现。函数srand需要一个无符号的整型参数,在每次程序执行时用函数rand去生在一组不同的随机数。如下例:
#include
#include
main()
{
int i;
unsigned seed;
printf("Enter a seed:");
scanf("%u",&seed);
srand(seed);
for( i = 1;i<=20;i++)
printf(""%10d",1+(rand()%6));
}
程序的运行结果是当我们输入不同的SEED时,产生不同组的随机数。这句话的意思有两个:一:当输入相同的SEED时,产生的同组随机数;二:每次运行我们都要输入一个SEED。
如果我们希望不用每次输入SEED值,而且每次运行时SEED值都是不同的,我们可以用下面语句代替上面的第三块的三个语句:
srand(time(NULL));
这会使计算机自动读取自己的时钟以获得SEED值。于是我们就获值了每次运行都会改变的SEED,同样也就获得了真正的随机数。【还不是真正的呵呵】



