译文来自 http://pe-cn.github.io/547/

在长方形中(均匀地)随机选择两个点,可以算出两点间距离的期望值。

例如,在单位正方形中任意两点间距离的期望约为0.521405,而在宽为2长为3的长方形中任意两点间距离的期望约为1.317067。

从边长为整数n ≥ 3、含有n2个单位正方形的大正方形中,去掉一个由x × y个单位正方形组成的长方形(1 ≤ x,y ≤ n - 2),我们称剩下的图形为边长为n的带洞正方形。

当n = 3时,只有一种带洞正方形:

p547-holes-1.png

当n = 4时,不考虑旋转和翻转,你能找出9种不同的带洞正方形:

p547-holes-2.png

记S(n)是所有可能的边长为n的带洞正方形中任意两点间距离的期望之和。这里的任意两点必须在大正方形去除内部长方形后剩下的区域,也即上图中的灰色区域。

例如,S(3) = 1.6514而S(4) = 19.6564,均保留小数点后4位小数。

求S(40)并保留小数点后4位小数。

先用小格子模拟一下:

from math import sqrt 
def e547(n): #n<=30
 dist=0.0
 for i in range(n):
  for j in range(n):
   for i1 in range(n):
    for j1 in range(n):
     dist+=sqrt((j-j1)**2+(i-i1)**2)
 return dist/(n**5) #n**4条线,n是边长的比例尺

运行结果为

>>> print(e547(10))
0.5186872221213251 
>>> print(e547(20))
0.520756536423531  
>>> print(e547(30))
0.5211214715615858 

再来带洞的边长为3的。

def e547(n,m): #n<=30
 dist=0.0
 ct=0
 for i in range(n*m):
  for j in range(n*m):
   for i1 in range(n*m):
    for j1 in range(n*m):
     #if (not (i in range(n,n*2) and j in range(n,n*2))and not (i1 in range(n,n*2) and j1 in range(n,n*2)) ):
     if (not (i >=n and i<n*2 and j >=n and j<n*2)and not (i1 >=n and i1<n*2 and j1 >=n and j1<n*2) ):
      ct+=1
      dist+=sqrt((j-j1)**2+(i-i1)**2)
 return dist/(ct*n)

>>> print(e547(10,3))
1.6505096708301576
>>> print(e547(20,3))
1.651145010385864