流程选择模型
前段时间看到赵玉平关于相亲的问题,很有意思。我希望通过概率模拟来验证这种方法的有效性。
原链接如下。有兴趣可以先了解一下原解释:管理学博士是怎么去相亲的?这个过程太真实了。最后,你居然选择了这么好的“对象”!强烈建议您学习.%相亲https://v.douyin.com/RWQQnC4/.
1.问题重述
1.1原问题描述
学生是我的媒人。每个学生向赵小姐介绍一个男朋友,并写下一个数字来代表男孩的品质。一次见一个人,一个方向不能重复。如果你决定做,就结束它;如果你决定不做,继续。
总结方法:先选4个学生(共12个)提问,记住最大值,然后向其他同学提问。当最大值大于上述最大值时,决定询问。
1.2数学模型
现在把原来的问题抽象为下面的数学过程。
随机生成n个数字;
依次向模型中输入n个数字,当决定选择其中一个时,过程停止(记录为kth,kn);
目标是使选定的数字尽可能大,并尽可能排在前n个数字中。
是:
n个数的第一个a(an,a/n=r)的最大值为m;
从第1位开始,小于等于第1位的丢弃,大于第1位的选择;
如果在最后一个数字之前没有大于A的数字,请选择最后一个数字。
在这个过程中,有这样一个问题:这n个随机数服从什么分布?让我们假设它服从0到100之间的平均分布。
2.过程实现
设n=100,a=33,模拟如下。
将numpy作为np导入
类别选择:
def __init__(self,nums):
# nums表示提供的数字集。
self.nums=nums
self.n=len(nums)
def get_max(self,a):
#从前面的A数中选择最大的一个,并记录为max_num。
自我a=a
self . max _ num=max(self . nums[0: a])
def决定(自我):
self.flag=0
因为我在射程之内
#如果遇到更大的数字,请选择。
if self . nums[I]self . max _ num :
自我选择=自我
self.flag=i
#如果整个过程没有遇到比较大的数字,只能选择最后一个。
if self.flag==0:
self . choice=self . nums[self . n-1]
def show(self):
Print('有%d个数字,其中最大值为%f,选定的数字为%f,排名为%d'%。
(self.n,max(self.nums),self.choice,sum(c.numsc.choice) 1))
if self.flag==0:
打印(在随后的数字中没有找到更大的数字,因此最后一个数字最终从所有数字中选择)
else:
打印(' %d数字' % (self.flag 1))。
n=100
a=33
nums=np.random.uniform(0,100,size=n)
c=选择(nums)
c.get_max(a)
c .决定()
c.show()
经过几次模拟,结果如下:
共有100个号码,其中最大值为96.647844,选中号码为96.647844,排名第一。
第64个号码被选中。
共有100个号码,其中最大值为99.571219,选中号码为65.277241,排名第31位。
在随后的数字中没有发现更大的数字,所以最后一个最终在所有数字中被选中。
共有100个号码,其中最大值为97.931539,选择号码为41.759912,排名第50。
在随后的数字中没有发现更大的数字,所以最后一个最终在所有数字中被选中。
共有100个号码,其中最大值为99.566610,选中号码为99.566610,排名第一。
位
选择了第73个数字
共有100个数字,其中的最大值是98.271705,选择的数字是98.271705,排第1位 选择了第82个数字
可以发现,在5次模拟中有3次选到了全局最大,效果不错,但也有两次在后续数字中未找到更大的。
直接进行100000次模拟,观察情况:
choices = [] rank = [] fail = 0 for i in range(0,100000): if i%1000==0: print(i) nums=np.random.uniform(0, 100, size=n) c=choose(nums) c.get_max(a) c.decide() choices.append(c.choice) rank.append(sum(c.numsc.choice)+1) if c.flag == 0: fail += 1
观察选出的数字的分布:
import matplotlib.pyplot as plt plt.hist(choices,100)
可以看到,大部分落在90~100之间,落在99~100之间的概率为0.28,效果较好,平均值np.mean(choices)=82.01201051783117。
观察选出的数字在原100个数字中的位次的分布:
plt.hist(rank,100)
可以看到,大部分位次落在0~10之间,选到最大值(排第1位)的概率为0.37。平均值np.mean(rank)=18.16273,平均相对位次0.18。
3.敏感性分析
当参数发生变化时,该方法是否仍能有较好的效果。
3.1小样本
现实情况中我们的精力有限,往往没有那么多的选择机会,那么,当n减少时(a/n=r近似不变),会发生什么。
n=50,a=17。进行100000次模拟,平均位次10.10,平均相对位次0.20。
n=10,a=3。进行100000次模拟,平均位次3.03,平均相对位次0.30。
n=5,a=2。进行100000次模拟,平均位次2.2,平均相对位次0.44。
随着n的减小,能够取得的平均相对位次的变化情况如下图。
可见随着n的减小,该方法的效果变差,但由于样本少,该现象情有可原。
3.2策略值r
保持n=100不变,观察r的变化对结果的影响,对r从0.1到0.9取9个值,每个值模拟10000次。
n=100 rs=np.linspace(0.1, 0.9, 9) m_choices=[] m_rank=[] m_fail=[] for r in rs: print(r) a=int(round(n*r)) choices = [] rank = [] fail = 0 for i in range(0,10000): nums=np.random.uniform(0, 100, size=n) c=choose(nums) c.get_max(a) c.decide() choices.append(c.choice) rank.append(sum(c.numsc.choice)+1) if c.flag == 0: fail += 1 m_choices.append(np.mean(choices)) m_rank.append(np.mean(rank)) m_fail.append(fail)
r对选择结果的影响:
plt.plot(rs,m_choices)
plt.plot(rs,m_fail)
当r较大时,很容易在后续数字中找不到更大的,从而获得较差的最终选择。
n=10,观察r的变化对结果的影响,对r从0.1到0.9取9个值,每个值模拟10000次。
plt.plot(rs,m_choices)
plt.plot(rs,m_fail)
当n较小时,虽然随着r的增大,在后续数字中找不到更大的数字的概率也是近乎线性增大,但是如果a太小则选不到较大的阈值,因此r在0.1到0.9之间存在最优解。
这启示我们,当基数n较大时,r的取值可适当减小,以便获得更优的结果。
4.进一步讨论
可以看到,对于该方法,当在后续数字中找不到更大的数字时,只能被迫选择最后一个数字,导致结果较差。一个后续改进的思路是,当在一段时间内(第a个数字后的一些数字中)未发现更好的时,应适当降低要求。
对于不同的n,存在不同r的最优取值,n越大,r的最优取值越小。
如果原数据服从其他分布规律,如卡方分布,F分布等,则结果可能有不同的表现,可能需要根据不同的分布采取不同的策略。
实际上,回归相亲问题,现实情况远比该数学问题复杂的多,首先每个人有自己的特点,不能被很好地量化打分,即使打分也是各方面表现有不同的分数,其次,n是不可控的,且人的思维都是不断发展变化的,挑选者不可能一成不变地遵循一个死板的策略,被挑选者也不一定在被挑选后即接受。最后,且行且珍惜。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/139154.html