其他题目---从5随机到7随机及其扩展

来源:互联网 发布:完美日记化妆品知乎 编辑:程序博客网 时间:2024/06/07 06:05

【题目】

  给定一个等概率产生1~5的随机函数 rand1To5如下:

def rand1To5():    return int(random.random()*5) + 1

  除此之外,不使用任何额外的随机机制,请用rand1To5实现等概率随机产生1~7的随机函数rand1To7。

【补充题目】

  给定一个以p概率产生0,以1-p概率产生1的随机函数rand01p如下:

def rand01p():    p = 0.83  #p可以随意改变    return 0 if random.random() < p else 1

  除此之外,不使用任何额外的随机机制,请用rand01p实现等概率随机产生1~6的随机函数rand1To6。

【进阶题目】

  给定一个等概率随机产生1~M的随机函数rand1ToM如下:

def rand1ToM(m):    return int(random.random() * m) + 1

  除此之外,不能使用任何额外的随机机制。有两个输入参数,分别为m和n,请用rand1ToM(m)实现等概率随机产生1~n的随机函数rand1ToN。

【基本思路】

  原问题。
  1、rand1To5() 等概率产生1,2,3,4,5
  2、rand1To5()-1 等概率产生0,1,2,3,4
  3、(rand1To5()-1)*5 等概率的产生0,5,10,15,20
  4、(rand1To5()-1)*5+rand1To5()-1 等概率的产生0,1,2,3…23,24
  5、如果步骤4产生的结果大于20,重新随机,直到产生的结果在0~20之间。
  6、步骤5的结果再进行%7,然后再加1,就是最终的结果。

#python3.5def rand1To5():    return int(random.random()*5) + 1def rand1To7():    num = (rand1To5()-1) * 5 + rand1To5() - 1    while num > 20:        num = (rand1To5()-1) * 5 + rand1To5() - 1    return num % 7 + 1

  补充题目。
  虽然rand01p方法是以p的概率产生0,以1-p的概率产生1,但是rand01p产生01和10的概率却都是p(1-p),可以利用这点来实现等概率随机产生0和1的函数。

def rand01():    num = rand01p()    while num == rand01p():        num = rand01p()    return num

  有了等概率产生0和1的函数,接下来的步骤和原问题类似。先实现随机产生0~3的随机函数,再利用0~3的随机函数实现随机产生1~6的随机函数。

def rand01p():    p = 0.83    return 0 if random.random() < p else 1def rand01():    num = rand01p()    while num == rand01p():        num = rand01p()    return numdef rand0To3():    return rand01()*2 + rand01()def rand1To6():    num = rand0To3() * 4 + rand0To3()    while num > 11:        num = rand0To3() * + rand0To3()    return num % 6 + 1

  进阶题目。
  1、将n-1转换成m进制数,假设结果转换成数组为 k = [a,b,c,d,e]
  2、使用rand1ToM(m)函数产生结果数组 res = [A,B,C,D,E],如果res所表示的数值大于k所表示的数值,将res丢掉重新随机,直到产生的结果小于或等于k,这时产生的res的范围就在0~n-1之间,但是此时res所表示的数还是m进制的。
  3、将res数组转换成10进制整数。
  4、将步骤3的结果加1就是最终的结果。

def rand1ToM(m):    return int(random.random() * m) + 1def rand1ToN(n, m):    def getMSysNum(value, m):        res = []        while value != 0:            res.append(value % m)            value //= m        return res[::-1]    def getRandMSysNumLessN(nMSys, m):        res = []        lastEqual = True        index = 0        while index < len(nMSys):            res.append(rand1ToM(m) - 1)            if lastEqual:                if res[-1] > nMSys[index]:                    index = 0                    res = []                    continue                else:                    lastEqual = True if res[-1] == nMSys[index] else False            index += 1        return res    def getNumFromMSysNum(mSysNum, m):        res = 0        for i in range(len(mSysNum)):            res = res * m + mSysNum[i]        return res    nMSys = getMSysNum(n-1, m)    randNum = getRandMSysNumLessN(nMSys, m)    return getNumFromMSysNum(randNum, m) + 1