实验环境:
python2.7
运行时重定向到输出文件即可:
python x.py > result.log
我们打算分三种情况模拟:
一,模拟直线末端为孤立点的情况,以P6为例进行模拟
二、模拟直线最中间的点为孤立点的情况,以P5,9为例进行模拟
三、模拟直线非最中间、非末端的点为孤立点的情况,以P5,10为例进行模拟
代码模拟思想是:
对于n个点,使用一个n-1长度的数组来放置n-1个随机数
数组中每个元素初始为-1,表示该数两侧的点没有连接,
后期若该元素为非-1,则表示该数两侧的点有连接,成为“相邻数对”
对于直线两端的端点,必须有“连续的2个-1”才表示能继续选择“相邻数对”
对于直线非两端的端点,必须有“连续的3个-1”才表示能继续选择“相邻数对”
每次选择“相邻数对”后,都要检查当前直线是否还能继续放置数对,
若不能继续放置数对,则跳出while循环,进行下一轮实验。
-----------------------------------------------------------------------------------------------
一、首先模拟Pn(n=6),代码如下:
#=*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
n=6
a = [-1] * (n-1) #定义一个长度为10的list
print a
# 100个点,来模拟101个数,初始化为-1,-1表示该数左右两侧没有连接
#如果最终结果中有两个数为空(-1),则表示,这两个数之间的点是孤立的。
#如果最终结果中有一个数为空(-1),则表示,这两个数之间没有点孤立
#如果运行过程中存在连续三个数为空(-1),说明该轮随机过程还没结束,需要继续进行。
#判断第i个点孤立的充分必要条件是:a[i-1]!=-1并且a[i-2]!=-1
def print_a(a):#输出随机产生的最终结果
print"\n--------最终产生的点对----"
print"a=",a
for index,item in enumerate(a):
if index==0 and item!=-1:
print"1 - 2",
if index==0 and item==-1:
print"1 2",
if index>0 and item!=-1:
print '-',index+2,
if index>0 and item==-1:
print index+2,
print"\n"
print"-"*30
import random
Flag=0#用来判断当前直线上是否还剩下可以选择的数对,0表示不存在,1表示还存在可以选择的“相邻数对”
i_nopairs=n-1#检验Pn是否为孤立点
i_isolated=0#统计第i个点最终被孤立的次数
i_pairs=0#统计第i个点最终不被孤立的次数
experiment=30000#总实验次数
for index in range(experiment):
print"-----------------------------index=%d-------------------------------"%index
a = [-1] * (n-1)#新的一轮实验开始,整个队列清零
while True:
Flag=0
point_pairs= random.randrange(0,n-1,1)#产生的随机数∈[0,n-1),共n-1个,下标范围是0~n-2
print"point_pairs=",point_pairs
if (point_pairs!=n-2 and point_pairs !=0) and point_pairs-a[point_pairs-1]==point_pairs-a[point_pairs+1]==point_pairs+1:#确保左右两侧都没有点对,才能落子
a[point_pairs]=point_pairs
if point_pairs==0 and a[1]==-1:#最左侧的点对,落笔时需要考虑确保第2个点和第3个点没有连接成对
a[point_pairs]=point_pairs
if point_pairs==n-2 and a[n-3]==-1:#最右侧的点对,落笔时需要考虑确保第2个点和第个点没有连接成对
a[point_pairs]=point_pairs
print"-"*10
print a[point_pairs]
print"-"*10
for i in range(n-3):#检查整条直线中是否还有可选择“相邻数对”的余地,如果没有了,那么本轮实验结束
if a[i]+a[i+1]+a[i+2]==-3:#············○ a[i] ○ a[i+1] ○ a[i+2] ○············
Flag=1
break
if a[0]+a[1]==-2 or a[n-3]+a[n-2]==-2:#直线开头最多只能空两个数,表示的含义是○ ○ ○-○······
Flag=1
break
#---------------------------------------
if Flag==1:
continue
if Flag==0:
if a[i_nopairs-1]==-1:
i_isolated=i_isolated+1
print(a)
break
#------------------------------这里对Pn进行验证----------------------------------------------------------
experiment=experiment*1.0
print"i_isolated=",i_isolated
print"The ratio of ith point isolated is:",i_isolated/experiments
实验结果是:
上述模拟实验为30000轮,最终第6个点被孤立的频率是11007/30000
书上理论计算P6=11/30
所以理论计算与实验结果十分接近
--------------------------------------------------------------------------------------------------------------
二、接下来模拟Pi,n(i=5,n=9,这是对称情况,i处于最中央),代码如下:
#=*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
n=9
i_nopairs=5#想孤立第5个点
a = [-1] * (n-1) #定义一个长度为10的list
print a
# 100个点,来模拟101个数,初始化为-1,-1表示该数左右两侧没有连接
#如果最终结果中有两个数为空(-1),则表示,这两个数之间的点是孤立的。
#如果最终结果中有一个数为空(-1),则表示,这两个数之间没有点孤立
#如果运行过程中存在连续三个数为空(-1),说明该轮随机过程还没结束,需要继续进行。
#判断第i个点孤立的充分必要条件是:a[i-1]!=-1并且a[i-2]!=-1
def print_a(a):#输出随机产生的最终结果
print"\n--------最终产生的点对----"
print"a=",a
for index,item in enumerate(a):
if index==0 and item!=-1:
print"1 - 2",
if index==0 and item==-1:
print"1 2",
if index>0 and item!=-1:
print '-',index+2,
if index>0 and item==-1:
print index+2,
print"\n"
print"-"*30
import random
Flag=0#用来判断当前直线上是否还剩下可以选择的数对,0表示不存在,1表示还存在可以选择的“相邻数对”
i_isolated=0#统计第i个点最终被孤立的次数
i_pairs=0#统计第i个点最终不被孤立的次数
experiment=128000#总实验次数
for index in range(experiment):
print"-----------------------------index=%d-------------------------------"%index
a = [-1] * (n-1)#新的一轮实验开始,整个队列清零
while True:
Flag=0#每次选择”相邻数对“时,假定整条直线已经没有剩下可以选择的数对了。
point_pairs= random.randrange(0,n-1,1)#产生的随机数∈[0,n-1),共n-1个,下标范围是0~n-2
print"point_pairs=",point_pairs
if (point_pairs!=n-2 and point_pairs !=0) and point_pairs-a[point_pairs-1]==point_pairs-a[point_pairs+1]==point_pairs+1:#确保左右两侧都没有点对,才能落子
a[point_pairs]=point_pairs
if point_pairs==0 and a[1]==-1:#最左侧的点对,落笔时需要考虑确保第2个点和第3个点没有连接成对
a[point_pairs]=point_pairs
if point_pairs==n-2 and a[n-3]==-1:#最右侧的点对,落笔时需要考虑确保第2个点和第个点没有连接成对
a[point_pairs]=point_pairs
print"-"*10
print a[point_pairs]
print"-"*10
for i in range(n-3):#检查整条直线中是否还有可选择“相邻数对”的余地,如果没有了,那么本轮实验结束
if a[i]+a[i+1]+a[i+2]==-3:#············○ a[i] ○ a[i+1] ○ a[i+2] ○············
Flag=1
break
if a[0]+a[1]==-2 or a[n-3]+a[n-2]==-2:#直线开头最多只能空两个数,表示的含义是○ ○ ○-○······
Flag=1
break
#---------------------------------------
if Flag==1:
continue
if Flag==0:
if a[i_nopairs-2]==a[i_nopairs-1]==-1:#a[i_nopairs-2] i a[i_nopairs-1]
i_isolated=i_isolated+1
print(a)
break
#------------------------------这里对Pi,n进行验证----------------------------------------------------------
experiment=experiment*1.0
print"i_isolated=",i_isolated
print"The ratio of ith point isolated is:",i_isolated/experiments
实验结果为:
实验结果显示:
第5个点为孤立的频率是17934/128000
书上理论计算结果为9/64
所以理论计算结果与实验结果十分接近
---------------------------------------------------------------------------------------------------------
三、接下来模拟Pi,n(i=5,n=10,这是非对称情况,i不再处于中央),稍作修改,代码如下:
#=*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
n=10
i_nopairs=5#想孤立第5个点
a = [-1] * (n-1) #定义一个长度为10的list
print a
# 100个点,来模拟101个数,初始化为-1,-1表示该数左右两侧没有连接
#如果最终结果中有两个数为空(-1),则表示,这两个数之间的点是孤立的。
#如果最终结果中有一个数为空(-1),则表示,这两个数之间没有点孤立
#如果运行过程中存在连续三个数为空(-1),说明该轮随机过程还没结束,需要继续进行。
#判断第i个点孤立的充分必要条件是:a[i-1]!=-1并且a[i-2]!=-1
def print_a(a):#输出随机产生的最终结果
print"\n--------最终产生的点对----"
print"a=",a
for index,item in enumerate(a):
if index==0 and item!=-1:
print"1 - 2",
if index==0 and item==-1:
print"1 2",
if index>0 and item!=-1:
print '-',index+2,
if index>0 and item==-1:
print index+2,
print"\n"
print"-"*30
import random
Flag=0#用来判断当前直线上是否还剩下可以选择的数对,0表示不存在,1表示还存在可以选择的“相邻数对”
i_isolated=0#统计第i个点最终被孤立的次数
i_pairs=0#统计第i个点最终不被孤立的次数
experiment=80000#总实验次数
for index in range(experiment):
print"-----------------------------index=%d-------------------------------"%index
a = [-1] * (n-1)#新的一轮实验开始,整个队列清零
while True:
Flag=0#每次选择”相邻数对“时,假定整条直线已经没有剩下可以选择的数对了。
point_pairs= random.randrange(0,n-1,1)#产生的随机数∈[0,n-1),共n-1个,下标范围是0~n-2
print"point_pairs=",point_pairs
if (point_pairs!=n-2 and point_pairs !=0) and point_pairs-a[point_pairs-1]==point_pairs-a[point_pairs+1]==point_pairs+1:#确保左右两侧都没有点对,才能落子
a[point_pairs]=point_pairs
if point_pairs==0 and a[1]==-1:#最左侧的点对,落笔时需要考虑确保第2个点和第3个点没有连接成对
a[point_pairs]=point_pairs
if point_pairs==n-2 and a[n-3]==-1:#最右侧的点对,落笔时需要考虑确保第2个点和第个点没有连接成对
a[point_pairs]=point_pairs
print"-"*10
print a[point_pairs]
print"-"*10
for i in range(n-3):#检查整条直线中是否还有可选择“相邻数对”的余地,如果没有了,那么本轮实验结束
if a[i]+a[i+1]+a[i+2]==-3:#············○ a[i] ○ a[i+1] ○ a[i+2] ○············
Flag=1
break
if a[0]+a[1]==-2 or a[n-3]+a[n-2]==-2:#直线开头最多只能空两个数,表示的含义是○ ○ ○-○······
Flag=1
break
#---------------------------------------
if Flag==1:
continue
if Flag==0:
if a[i_nopairs-2]==a[i_nopairs-1]==-1:#a[i_nopairs-2] i a[i_nopairs-1]
i_isolated=i_isolated+1
print(a)
break
#------------------------------这里对Pi,n进行验证----------------------------------------------------------
experiment=experiment*1.0
print"i_isolated=",i_isolated
print"The ratio of ith point isolated is:",i_isolated/experiment
实验结果是:
由实验结果可知,10个点中,第5个点为孤立点的频率为:10960/80000
由书上理论可知:P5,10=P5·P6=(3/8)(11/30)=11/80
所以实验结果与理论结果十分接近。