【思考题】控制随机数
mathcad吧
全部回复
仅看楼主
level 12
朱老剑客 楼主
(1)给出n个0~10之间的随机数,n>2,使各随机数两两之间的差的绝对值>2。如{2,5,9},这3个数两两之间的差的绝对值>2。
(2)给出X、Y两个随机向量,每个向量中含有n个随机数,n>5,使Y对X做的散点图中所有的点均处于下图所示两个函数所包围的阴影面积内。
(3)给出n个0~10之间的随机数,n>2,使所有随机数的和等于10。如2+3+5=10。
(4)给出n个0~10之间的随机数,n>2,使所有随机数的积等于300。如5×10×3×2=300。
2015年09月21日 03点09分 1
level 12
朱老剑客 楼主
注意!
第(4)问,我发现实数积很难控制,尤其是在MC这种用浮点进行数值计算的软件里,会有系统误差,所以第(4)问改为:
(4)给出n个0~10之间的随机数,n>2,使所有随机数的积约等于300,即round(所有随机数的积)=300。
2015年09月21日 03点09分 2
level 12
朱老剑客 楼主
还有,第(3)问和第(4)问,在解题过程中肯定会发现,并不是所有的数都是随机的,至少有一个数不能是随机数,嗯,正确的表述我想应该是“n-1个随机数”。嗯,我在题中的表述不很严谨,各位见谅哈
2015年09月21日 04点09分 5
level 11
既然是有约束的,我感觉这就不能叫“随机数”了,叫“找出满足以下条件的数”。
2015年09月21日 09点09分 6
嗯,随你怎么理解,大概意思就是这样的吧。可能是因为需要使用随机数生成函数,所以我才会说是随机数的吧。
2015年09月21日 10点09分
回复
���Ͻ���
:我首先想到的是用for遍历各种组合,不用随机数,随机的话很容易产生大量重复组合。
2015年09月21日 10点09分
level 12
朱老剑客 楼主
@angelycs ,这样的组合理论上有无穷种,穷举不尽的。我这个题是想让各位做出几个程序,可以控制随机数函数让它能够产生满足条件的数组。
2015年09月21日 11点09分 7
level 11
我审题出错,看着题干中的举例就默认为要找的数都是整数了。
2015年09月21日 11点09分 8
level 11
上面这几个按要求生成n维的随机数的题,我只能解第二题,因为它是个2维随机变量,只需先随机产生满足要求的横坐标,再求得对应纵坐标区间,然后再从该区间随机取值即可。
2015年09月22日 23点09分 9
level 11
第三个也成。
手机发帖,就用伪代码说明下思路吧,如果有表达不清楚的地方请提出来。
rSumEq10(n)={
result[n-1]=0 #提前声明一个n维的出向量
L=10 #和为10
rv=0 #RandomValue 存储随机值的变量,初始为0
for(i=1 to n -1){ #循环n-1次,产生n-1个随机值
rv=runif(1,0,L)[0] #生成一个[0,10]的随机值
result[i-1]=rv #存进result
向量内
L=L-rv #用L减去刚刚生成的随机数,得到剩下的随机数的取值范围
}
#循环体结束,生成了n-1个随机值
result[n-1]=L #最后一个数只能取唯一的值
return result #返回result
}
2015年09月23日 01点09分 10
用rnd函数代替runif可以少写两个参数
2015年09月23日 02点09分
level 11
第四个问题,思路同上,把rv的初始值设置为1,循环体中L=L-rv改为L=L\rv,其余不变。
2015年09月23日 01点09分 11
嗯,这样做就不能满足[0,10]个条件了
2015年09月24日 01点09分
回复
angelycs
:“的条件”。手机打字依然不习惯。
2015年09月24日 01点09分
level 11
第一个问题,没能找到合适的数学公式来生成,我采取了暴力点的方式:
随机生成[0,10]间的随机数,判断是否满足两两绝对值大于2,如果不是,重复上述步骤。
按照要求,我认为n应该不能大于6。
在判断是否满足要求时,采用了先按大小排序,然后提取了两个子矩阵,一个从第一行到倒数第二行,一个从第二行到最后一行,用第二个子矩阵减第一个就能得到量量的绝对值向量,判断这个绝对值向量是否全大于2就成。
偷个懒拍照上传吧。
2015年09月23日 03点09分 13
疏忽了,测试时为了防止死循环设置了循环次数为100,真正使用时应当将for循环体改为while循环体,找到合适的随机值时终止循环。n应该设置为小于5,因为等于6的时候只有唯一解[0,2,4,6,8,10],要随机生成这个组合需要时间太长,直接给出这个组合更合适。
2015年09月23日 03点09分
level 12
朱老剑客 楼主
第1题干得差不多了,先贴思路吧:
(1)给出n个0~10之间的随机数,n>2,使各随机数两两之间的差的绝对值>2。如{2,5,9},这3个数两两之间的差的绝对值>2。
设随机数两两之间的差为q。
当q≥2,且“0~10”表示为[0,10]时,n.max=6,{0,2,4,6,8,10};
当q≥2,且“0~10”表示为(0,10)时,n.max=5,此时,各元素与{1,3,5,7,9}有关。
此题需要讨论的是:当q>2,且“0~10”表示为(0,10)时的情况。
因为n>2,且n为整数,所以n.min=3,所以n的取值范围为{3,4,5}。
因为有n个随机数,所以所得到的向量中的元素肯定不相等,所以向量可进行升序或降序排列。
假设n=3:
最小的元素a的取值范围为(0,10-2×2)=(0,6);
中间的元素b的取值范围为(0+2,10-2)=(2,8);考虑b>a+2,因此其范围为(a+2,10-2);
最大的元素c的取值范围为(0+2×2,10)=(4,10);考虑c>b+2,因此其范围为(b+2,10)。
得到3元素的通解为:
嗯,再把这个修改一下就是这道题的通解了。
2015年09月23日 04点09分 14
level 11
随机变量与常数或随机变量的四则运算得到的值依然是随机变量。
关于符号求解等号[→]与数值计算等号[=]的区别,以及关于内存调用,我有以下认识。
先说内存调用,mc直接调用内存进行符号计算这话没错,但是若把这作为mc的特点就不太正确了,因为所有的软件都是通过内存操作完成变量的声明读取存储的,包括函数体的代码也是存放在内存中的,调用函数计算的过程就是让CPU按顺序执行一段内存中的代码。
内存中有堆(heap)和栈(stack),每次声明一个新的变量包括数组,就会在堆中划出一片内存空间作为该变量内容的存储地,根据变量类型的不同,划分的空间大小也不同。而函数体的内容也是存放在堆中的,函数名只是一个入口,告诉CPU本函数在内存中的位置。每个内存空间都有自己的起始地址,CPU通过地址来访问这些内存中的内容(寻址)。在给变量划分内存时 堆里的空间不必按顺序划分,两个变量可以相隔很远。
栈则不同,在存入(入栈)时,先进入的变量必须放在底,在读取(出栈)时,最顶上的变量先出去。所有函数的参数都在栈中,每调用一个函数,都会在栈里按从右往左的顺序把函数的参数一个个压入栈中,但不一定是这些参数的值,有可能是这些参数在堆中的内存空间的地址。栈的分配是不能由人为操作的。
在进行函数调用时,CPU会进行一系列固化的步骤进行内存读写,保证函数按照给定的参数正常运行相关代码(代码在堆里)并在调用完成后返回到调用前的代码处执行下一句代码。
只要没有人为编写代码指定要将计算中的值写入硬盘,那么一切都只是在内存里进行。
2015年09月23日 05点09分 15
level 11
基于此,再说说符号求解等号[→]与数值计算等号[=]的区别,在mc中数值计算与符号计算常常有巨大的差别比如上面那个rnd函数,我认为这只是由两种计算使用的引擎不一样导致的,与内存调用方式无关,因为CPU调用函数只有一种方式,只有调用的函数不一样,没有调用的方式不一样。
当在mc中使用a:=rnd(5)=0.785 (包含后面那个等号) 给a赋值时,等价于a=0.785。堆中分配一个float型变量的内存空间,a这个变量现在等价于那片内存的地址,每次读取或改变a的值,都是对这片内存进行读写。
但是,若是这样的语句 a:=rnd(5) (后面没有了等号),由于rnd是一个函数名,a在这里不再是一个存储rnd(5)结果的内存的地址,而是rnd这个函数体开始的地址,参数为5,这种指向一个函数地址的变量有个名字叫做“函数指针”。
当使用符号计算[→]来计算a时,符号计算引擎识别了该函数指针所指向的函数体rnd并显示出来(符号计算结果经常是各种函数),而当使用数值计算[=]计算a时相应引擎则是调用了函数指针指向的函数体rnd(5),并将结果存在了内存中的某个地方,在mc中a变量的值便指向了那片内存空间,使得再次读取a时值不变。但此时mc中的a在内存中依然是个函数指针,所以mc中的变量并不像其他编程软件中的变量,它的类型不是唯一的。
由于mc并不是很底层的软件,它自己应该也做了很多封装,所以也不好说它里面显示的变量是否就完全是内存中真正使用的变量。
关于内存调用这块,太久没有看相关的汇编和编程资料了,难免有误,欢迎指正。
2015年09月23日 05点09分 16
level 12
朱老剑客 楼主
第1题我的编程如下:
再做一个验算函数:
然后咱们验算一下:
这对其他的n值也是有效的,只不过n>6的时候会出现大于10的数。
2015年09月23日 05点09分 17
level 12
朱老剑客 楼主
回16楼,确实如@angelycs 所说:
还望能多多聊聊计算机编程的基础知识哈。:)
2015年09月23日 05点09分 18
level 12
朱老剑客 楼主
以上,我假定步长为+2,因此第一个数的震荡最大,越往上震荡越小。如果假定步长为-2的话,这个规律就会反过来了吧。嗯,所以对第1题一定还有更好的解。
2015年09月23日 05点09分 19
因为这n个变量不是独立的,所以第一个数决定后就会影响后面数的取值也就是波动范围。这但是和“贝特朗问题”的现象有点像,不同的随机生成方式会对应不同的结论,先生成最小值,最大值的波动就小;先生成最大值,最小值的波动就小,两种结论不一样,但都对。
2015年09月23日 06点09分
level 12
朱老剑客 楼主
第2问:
上图中,可以看到在阴影面积的左右两角处,点很密集,也就是说数据点在阴影面积中并不是均匀分布的。这个跟MC的rnd()无关,而是我的程序本身有问题——我先定义了一系列X轴方向均匀分布的点,然后把它们套在Y轴方向的f(x)-g(x)的范围内,等于是使一个正方形的平面根据阴影面积在Y轴方向上进行了相应的压缩。
如果要使点的分布均匀化,需要在X轴方向布点的时候就考虑到阴影的面积,也就是积分面积,把这个面积作为输出点的权重,但这就需要将阴影面积以X轴方向进行均匀的细致的划分,然后计算各划分的面积,然后以这个面积与总面积的比值作为允许安排的点的数量的权重。
把上面的这段话再简化一下,先算积分,之后又算微分,随机点的个数在X轴方向上的分布就等于:(f(x)-g(x))×10000/总面积。但具体到怎么能够让MC按照要求产生相应数量的随机点,我还没有可行的办法。
2015年09月23日 09点09分 20
确实,这样取点不应对x均匀地取点。你说的微分积分算出来的东西,在概率论中称作二维随机变量(x,y)关于x的边缘概率密度fx(x),就是取到x等于ξ时的概率,有了这个之后可以有办法让mc产生对应的随机变量X
2015年09月24日 02点09分
《概率论与数理统计》(浙江大学第四版)377、378页有关于生成特定概率分布连续随机变量的方法介绍:对概率分布函数F(x)求反函数F'(x),然后用函数F'(rnd(1))就可以生成所需的随机变量了。
2015年09月24日 02点09分
level 12
朱老剑客 楼主
第3问:
验算:
2015年09月23日 10点09分 21
这样做有个风险,生成类似(1,9,0)这样含有0的数,而且好像也不是均匀的(需要验证)。得换个方式,试试在[0,10]之间随机生成n-1个不同位置点,将长度为10的线段分割成n段,计算每段长度。
2015年09月27日 23点09分
level 12
朱老剑客 楼主
第4问我不知道怎么做[汗]貌似没有什么规律可循。[泪]
2015年09月23日 11点09分 22
level 12
朱老剑客 楼主
我知道怎么做第4问了哈,先不写出来,看看有没有人写出其他的解。[呵呵]
2015年09月23日 11点09分 23
1 2 尾页