三国志11威力加强版吧 关注:150,127贴子:4,892,938

【技术水】关于Excel抽签器随机数据的讨论

只看楼主收藏回复

Excel是个好东西。


IP属地:天津1楼2021-10-05 21:17回复
    蠢香想搞事?


    IP属地:江苏来自Android客户端2楼2021-10-05 21:18
    收起回复
      前段时间无聊的时候开了个脑洞,做了一个小小的抽签器。现在又在开吧剧了,正好放假有空写帖子,就把这个关于抽签器的脑洞写一下好了。水平有限,欢迎大家多多批评指正。


      IP属地:天津3楼2021-10-05 21:19
      回复
        一、均匀随机的局限性
        在一般的吧剧抽签器中,数据是怎么随机的呢?可能用的最多的就是excel自带的randbetween函数,这个函数很好用,比如说单元格内输入公式=randbetween(70,90),那么单元格内的结果就会随机到从70到90的21个整数,按F9就能刷新。但是,学过概率论的都知道,这种离散的随机方法属于“均匀随机”,它只能设定随机数据的上下限,但并不能改变随机数的分布。也就是说,抽到低数据、中数据和高数据的可能性是一样的。但是我们知道,在一个追求完美的制作者的角度,其实更希望随机数不是均匀的,而是在划定的范围内让随机到“极端值”的可能性更小些,让随机到“中庸值”的可能性更大些,这样才更能体现出模板设定的合理性。一个反例就是:对于武力数据,大将职业的随机范围在65到84之间,猛将职业的随机范围在75到94之间。那么大将与猛将随机到75-84这一区段的可能性都是50%,相乘就是25%,在这四分之一的概率内(对应到统计中就是约四分之一的签),大将与猛将的武力随机方案没有任何区别,因为都是75-84的均匀随机。这对于不同职业的选择是不太公平的,一定程度上消解了职业之间的差异性。


        IP属地:天津4楼2021-10-05 21:20
        回复
          另一个层面上,从设计者的角度考虑,如果选择了“大将”职业,按照正常的思路,一般都是在脑海中先浮现出“大将”所对应的大致数据范围,例如统率70-90,那么设计者当然更希望随机到80附近的可能性更大。超出这个范围的有没有可能?如果考虑到“有限的真实感”这一原则,好像大将随机到65或者更低一点也还说得过去,就相当于按照大将培养但是却不成才的少数情况。更高也可以,比如说92、93,就相当于奇才或天赋那种类型。然而,按照randbetween规则,如果把下限设定为60,上限设定为95,那么均值或者说期望就变成了77.5,偏离了设计这一职业的初衷。可见如果仅仅用这种简单的随机方案,是难以“鱼与熊掌兼得”的。
          那么,有没有一种办法让不同职业/模板的随机差异更明显一些,让每个模板的随机方案设定更有背景感、代入感一些,同时又不影响上下限设定?其实只要把“均匀随机”改成“不均匀随机”就行了。可喜的是,利用Excel公式就可以实现一些简单的不均匀随机规则,让中段数据更集中、随机概率更高,边缘数据的随机概率更小。更可喜的是,这种规则学起来相当简单。


          IP属地:天津6楼2021-10-05 21:21
          回复
            二、简单的不均匀随机方案(如果对公式不感兴趣可以跳过)
            Excel公式里最为常用的一个,不是sum,不是count,也不是vlookup,而是if。这个简单的条件分支判断为实现各种酷炫的操作提供了可能。就以随机数为例,如果想要不均匀随机,可以采用下面的方案:
            1.在单元格A1内输入公式=randbetween(1,10),产生分段随机数;
            2.在单元格B1内输入公式:
            =if(A1<=2,randbetween(60,74),
            if(A1<=8,randbetween(75,84),
            randbetween(85,94)))
            (这里提一个小tip,Excel输入公式是支持换行的,写长公式的时候更方便些)
            上面B1单元格内的这个公式在if内嵌套了一个if判断,相当于根据A1单元格的随机数产生了三种随机结果:
            当A1随机数为1-2时,B1内随机到60-74的15个数字;
            当A1随机数为3-8时,B1内随机到75-84的20个数字;
            当A1随机数为9-10时,B1内随机到85-94的15个数字。
            当然B1是最终随机结果,A1只是中间数据。换言之:随机数据分布到60-74的概率为20%,分布到75-84的概率为60%,分布到85-94的概率为20%。这样就实现了随机到中段范围数据的可能性更高,随机到边缘范围数据的可能性更低。随机到不同区段内的概率可以通过修改B1单元格内的分支条件的那几个数值来改变。如果想把概率更精细化,可以把A1里面的数值改大一些,比如说改成100;如果想要更多区段,无非就是在B1内多嵌套几个if而已。是不是很简单?
            当然,除了利用if外,别的方法也能做到不均匀随机——函数映射便是其中一种。仍然举例来说:
            1.在C1单元格内输入公式:=randbetween(61,90);
            2.在D1单元格内输入公式:=round(C1^2/100,0)。
            即把61-90的随机数平方后除以100再取整。D1单元格内的结果在37-81的范围内,然而它并不是从37-81的均匀分布。在37-81的前一半也就是37-59,实际上这一区段的随机概率是57%,也就是具有更高的可能性随机到数值较低的数据;而且数值越低,随机概率越高。如果把平方改成立方,这一规律会更明显。
            上面是平方函数的一个简单映射。当然Excel不只有平方和立方,还有开方、指数、对数等等,都可以照猫画虎弄出一个“不均匀随机”来。并且通过参数的设置,以及函数的叠加、嵌套,再加上一点点巧妙的算法,甚至可以搞出一套相当复杂的不均匀随机方案,只不过不太好把握就是了。


            IP属地:天津7楼2021-10-05 21:22
            回复
              三、概率密度函数(划重点,要考的)
              以上提出的不均匀随机方案,都是基于Excel公式直接得到的随机分布规则。相对于函数映射来说,显然if方法要更容易操作一些。其实做到这步已经可以了,毕竟抽签器也没多高要求。但对于强迫症来说,仍然会觉得这种方法不好看,它仍然有着可以精益求精的空间。
              这种方法有什么问题?
              首先,作为一个学渣和Excel公式小白,楼主看到那么多嵌套和数学公式一直觉得晕乎乎,对于掌握它果然还是比较抵触的——它对于新手不够友好。即使对于老手来说,设置公式、调节参数也是比较枯燥乏味的过程,并且这个过程不够直观可控,如果把做抽签器的热情都消耗在这里,就显得有点得不偿失了。
              其次,也是更重要的一点,用这种方法设置的公式,真的合理吗?分区段设置随机概率固然可以,不过这些区间、这些概率是不是也是脑子一热想出来的?函数映射的规则又有多少兼容性?如果存在一种“最佳”方案来设定随机规则,干嘛还要用这么复杂的嵌套复合呢?这种“最佳”随机方案,真的存在吗?
              答案是存在的。我们知道,对于一个人群的某个特征的分布,最常见也最合理的便是【正态分布】规则。如果把这种规则应用到武将数据随机中,那么数据随机的合理性一下子就有了,抽签器也一下子就高大上了起来。不过,在介绍正态分布之前呢,我们先来复习一下什么叫做【概率密度函数】。

              这个百度百科的定义很专业,但它复杂而冗长,我们做抽签器完全不需要知道这些,也不用管它是离散型还是连续型,也不要管如何归一化,我们这些小白只需要看下面这个图就可以了。(鼠绘轻喷)

              这条黑色曲线就是概率密度函数了。我们不用管它的函数值是什么,这个图里唯一有用的就是黄色部分,即区间与曲线围成的面积——这个黄色面积占这条曲线与横轴(数据范围)围成的总面积的比重就是概率。如果这个比重是0.3,就相当于往总面积里随机扔一粒芝麻,这粒芝麻分布到黄色面积里的概率就是30%,也就是说随机到50-75范围的概率是30%。至于随机到的具体值,就是芝麻位置所对应的横坐标,随机到小数的话取个整就行了。当然上面这个图并不是正态分布的概率密度函数图,正态分布是两端不封口的。


              IP属地:天津8楼2021-10-05 21:25
              回复
                在抽签器中,如果设计者可以自己【绘制】概率密度分布函数,显然就可以很容易很轻松地实现想要的随机规则了。顺便,我们来看一看前面写的那些用公式设置的随机规则,它们的概率密度函数长什么样子(示意图):

                显然,它们并不如正态分布好看,也不如正态分布合理。因为正态分布长这个样子:

                连续、对称、丝滑。那么问题来了,怎么样才能在Excel中做到这么好看的分布规律呢?能否把正态分布的概率密度函数引入到抽签器中呢?


                IP属地:天津9楼2021-10-05 21:27
                收起回复
                  四、自定义数据分布的抽签器
                  在引入正态分布之前,我们可以先试试看能不能在Excel中绘制自己想要的概率密度函数。当然,Excel是一个一个的单元格,不可能画出连续曲线来;不过,把这些单元格变小一点,似乎就可以用涂格子的办法来模拟出曲线效果。比如说下面这样。

                  好像真的可以。在小方格里输入特殊符号,例如小数点".",再用条件格式把小方格涂绿,既能直观显示,又能用公式统计,一举两得。这样涂完以后,是不是就可以近似看作一条概率密度曲线了?(下面这个蓝线是截图的时候用鼠标画的)

                  既然画曲线是可能的,那么接下来,就是想想办法怎么用画的这条概率密度曲线来抽取随机数据了。其实原理也很简单,仍然用前面提到的“扔芝麻”的办法,数一数一共有多少个绿色的格子,假如有50个,就用一个均匀随机函数randbetween(1,50),得到随机结果;假如随机到了39,然后只要从左到右数一下第39个绿色小方格所对应的横坐标就可以了。


                  IP属地:天津10楼2021-10-05 21:31
                  回复
                    当然了,尽管原理简单,设计起来还是要花一番工夫的。用各种各样的函数、添加辅助行辅助列、用公式设置条件格式什么的都是常规操作,这里就不再说明无聊的设计和调试过程,只展示一下画出的这条曲线怎么用。

                    上图是一个示例,在输入框中,可以输入单元格范围以及数据分布的上下限。单元格范围就是灰框部分,只有在这个范围的格子内打小数点,格子才会变绿;数据分布上下限则决定了刻度尺(图标上方那一行)上的数字。图中数据分布范围是70到90,很明显,现在画的这个曲线在83-84左右达到峰值,也就是说随机到这里的可能性是最大的。随机到70左右当然也有可能,不过因为左侧曲线很低,概率很小就是了。随机结果就用深绿色的竖线来显示,因为有小数,可能就会显示两条相邻的深绿色竖线了。
                    总的来说,相比于用公式设置随机规则的方案,直接涂格子画曲线的方法更加直观,对规则设计者也更友好。可是这个工作表的编码过程这么复杂,新手完全不会怎么办?简单的讲,不用考虑这些东西,因为这是一个轮子,或者说一个黑箱。使用的时候,只要勾勒曲线形状就可以了,并不需要去打开那些隐藏行、隐藏列,去查看里面复杂的公式;引用数据也可以直接把随机结果的那一个单元格引用过来,并且汇总到一起。如果复制出四个工作表,就可以画出5条不同的曲线,汇总以后就是一个武将的五维随机结果:


                    IP属地:天津11楼2021-10-05 21:33
                    收起回复
                      所以,我只做抽签器,绝对不干数值策划,设计数值太靠脑洞了


                      IP属地:广西12楼2021-10-05 21:36
                      收起回复
                        为了让五维的随机曲线设计更方便一些,还可以把五条曲线放在同一个工作表内,来定义不同类型武将五维的数据分布规律。

                        上面这个显然是“武将型”,五维中最容易拿到高数据的是武力,其次是统率,而后三维稍低些。但这并不意味着智力一定比武力低,仔细看上面画的曲线,智力是有可能比武力高的,只不过可能性比较小而已。甚至政治值都有可能比武力值高,只不过可能性微乎其微,毕竟作为武将培养的很少有成为文官的。除此之外,也可以定义出其他类型的人才,譬如五维都高的“英雄型”:

                        统武很低而魅力很高的“名媛型”:

                        政治最突出的“文官型”:

                        仅有武力突出的“猛将型”:

                        等等等等,各种类型的五维都可以自己定义,并且可以在汇总表中进行选择、抽签,得到当前选择类型的抽签结果——这便是【自定义数据分布】抽签器的雏形了。


                        IP属地:天津13楼2021-10-05 21:36
                        回复
                          五、正态分布与武将模板
                          现在,我们已经有了可以自定义的概率密度函数曲线,并且可以按照这条曲线所决定的分布规律来得到随机数。不过问题又来了,这样绘制的曲线,是“最佳方案”吗?虽然可以绘制出大致的中间高两头低的曲线形状,画曲线的时候多一格少一格好像也没什么所谓,但作为一个强迫症,仍然会觉得这样不够好,不够准确。另外,画曲线本身也是随心所欲,难以确定一个足够令人信服的标准。如果有一个标准化、自动化的东西,来代替人力,只要输入期望数据,就能让Excel自己把曲线画出来就好了。而这个“期望数据”,也就是我们所说的武将模板。
                          在模板抽签器中,一般会有一个模板武将库,里面收录了很多武将的五维信息。选择哪个模板,就意味着随机到的五维数据有更大可能性贴近这个模板。譬如,把血色周瑜的五维95/69/93/77/95收录进去,并且抽签的时候选择周瑜模板,那么随机到90/70/90/80/90的可能性显然要高于50/90/50/80/90。而这个规律利用正态分布的概率密度函数曲线,很容易实现。
                          当然,在画正态分布曲线之前,要先复习一下什么是正态分布。正态分布的概率密度函数长这样:

                          和前面一样,我们不用管这个复杂的公式,只需要看图。

                          在正态分布中,有两个重要的参数,一个是μ(读作miu),也叫均值;一个是σ(读作sigma),也叫标准差。上面这个图里,均值μ=80,意味着随机数据的均值是80,并且随机到80附近的可能性也最高。而标准差σ则决定了这条曲线的胖瘦,标准差越大,曲线越胖,也意味着随机结果更加分散;标准差越小,曲线越瘦,也意味着随机结果更加集中。对于正态分布,只要确定了这两个参数,曲线形状也就随之确定。如果把正态分布规则应用到模板抽签器,均值μ自然容易找,直接把模板数据作为μ即可;那么,标准差σ怎么确定呢


                          IP属地:天津14楼2021-10-05 21:39
                          回复
                            还记得中学的时候学过的“3σ原则”吗?对于正态分布而言,99.7%的数据会随机分布到[μ-3σ,μ+3σ]这个区间内,而区间外的几乎可以不考虑了。也就是说,如果我们希望均值是80,同时想要让武将的数据范围在80的上下15内浮动,那么就把15除以3,让标准差σ=5就可以了,这样几乎所有数据都会分布到65到95的区间。

                            把标准差暂定为5是比较合理的。如果模板数据是80,那么随机值取到65到95都有可能;但是边缘数据的随机概率仍旧小,从上面这个图可以看出,在65-70和90-95这两个区间,黄色面积只有很小一部分(2σ以外的只有5%)。而1σ以内即75-85的随机概率高达68%,越靠近均值80,随机到的可能性越高——这就是武将模板的意义,选择哪个武将作为模板,五维值就会贴近他,尽管仍然会有小概率偏离模板数据,但大多数情况还是会向模板靠拢。
                            那么接下来,仍然要研究一下如何用Excel做正态分布的随机抽签。既然已经有了概率密度函数图,那么只需要把填充小数点“.”的操作交给Excel公式就好了。还好,Excel自带函数里面有一个叫做NORMDIST的函数,它可以计算出正态分布概率密度曲线中某个点的函数值。利用这个,再加上一些归一化、整数化、比较大小等公式的设置,就能画出正态分布形状的绿色小方格来。而如果把标准差σ暂定为5,那么影响曲线形状的就只有武将模板的数据,也就是均值μ——也就是说,在模板库里选择好模板武将,数据的随机范围与分布规律就都确定好了。


                            IP属地:天津15楼2021-10-05 21:41
                            回复
                              同样地,不再展示公式的设计过程,我们只来看自动画图的结果。因为小数取整的关系,画的图可能并不是严格对称,不过也无伤大雅。

                              这里选择模板武将“青梅煮茶”,就自动生成了这个武将所对应的随机分布图,抽签的时候按F9刷新就可以了,也省去了让吧剧设计者自己涂格子的麻烦。当然,相对于通用型的“自定义数据分布”抽签器,正态分布规则的模板抽签器可以自主编辑的空间比较小,最多改一下σ,因此效率与自由度只能选择其一。


                              IP属地:天津17楼2021-10-05 21:42
                              回复