我们为 Toolz 发布会提供了一份小赠品,我以懒惰的方式绘制了图:我将进入者列表粘贴到电子表格中,添加了一列 =RAND()者, 并且按它排序。它起作用了, 但一个以做统计为生的朋友看了看我的肩膀说, "你知道那其实并不统一,对吗?"他没错, 那天晚上我掉进的兔子洞, 是Toolz现在有专有的一个重要部分 列表随机化器 that does the shuffle as the right way。this guide is what I learned, written for anyone who needs to pull name of a hat and want the hat to be olden。
TL;博士: List 随机化器要么随机(shuffle)重新订购整个列表,要么从中抽取随机样本(pick),好的使用 Fisher-Yates 洗牌和一个加密随机源,因此每个订购的可能性都相同。使用洗牌进行轮次订单和座位,并选择赠品和样本。该工具运行客户端,默认情况下无需替换即可抽奖,因此获胜者是唯一的,并且拒绝抽取比列表所持有的更多唯一项目。
Laravel和React上构建SaaS产品,所以我在这里关心两件事:数学正确,以及让界面足够明显,你永远不会怀疑抽奖是否公平,结果两者都比听起来更重要。
什么是列表随机化器?
List 随机化器取一个项目列表,每行一个,随机重新排列或采样。公平洗牌是一个解决的问题,答案错误,看起来正确:通过随机键排序是有偏差的,而 Fisher-Yates 洗牌则没有,浏览器提供无偏差位通过 crypto.getRandomValues().粘贴在名字、奖品、任务、团队或想法中,它要么将整个列表按洗牌顺序递回,要么挑选出你要求的获奖者人数,它是从碗中绘制折叠的单据的软件版本,其优点是它消除了人类在尝试手工选择"随机"时引入的安静偏见。
操作真的只有两个,知道你想要的是整个技能。Shuffle 返回你给它的每个项目,只是按照新的随机顺序,所以没有添加或丢失任何内容。Pick 返回一个子集,从池中抽出一组项目。抽奖是一种选择。在单口喜剧中决定谁先出现是一种洗牌。大多数人至少一次触及错误的,通常尝试 "洗牌并拿下前三名 "当 Pick 数为三时,一步完成相同的事情。
公平洗牌实际上是如何运作的?
这是我的统计学家朋友所接触到的部分。电子表格技巧,为每行分配一个随机数并进行排序,感觉随机但不统一。排序算法进行比较,当两个随机键恰好接近时,联系和比较如何解决的微小偏差会泄漏到结果中。在小列表上,偏差很小,但它是真实的,对于任何以公平为重点的东西,"足够接近"并不是一个很好的答案。
Fisher-Yates shuffle的方法是正确的,有时在Donald Knuth普及了原位版本之后称为Knuth shuffle,由Ronald Fisher和Frank Yates在1938年描述,并由Richard Durstenfeld在1964年给出了它的现代计算机形式,其想法很简单,将列表从最后一个项目走到第二个位置,从列表的开头到当前位置,随机选择一个索引,然后交换这两个项目,因为每次交换都从一个缩小的,定义明确的范围中抽取,每个可能的排序都以完全相等的概率在线性时间运行,触摸每个项目一次,并且不需要超出列表本身的额外内存。
的 列表随机化器 直接使用这个算法。当您不替换地选择时,它就是同一个洗牌提前停止:洗牌列表,然后取前 N 个项目。这保证了获胜者是不同的,并且每组可能的获胜者都有同等的可能性。
随机性从何而来?
算法只像供给它的随机数一样公平,如果随机性的来源是可预测的或有偏差的,那么完美的洗牌仍然会产生偏差的结果,这就是浏览器赢得保留的地方。
现代浏览器暴露 crypto.getRandomValues(W3C Web Cryptography API)的一部分,它用从操作系统熵池中抽取的加密强随机值填充数组,那是一个比它强得多的源 Math.random的,它是一个快速的伪随机生成器,从来没有打算用于任何可预测性重要的东西,随机化器更喜欢 crypto.getRandomValues 并且只回落到 Math.random 当加密源确实不可用时,当前浏览器上几乎永远不会可用。
我必须做对还有一个微妙之处。要将随机的 32 位数字变成从 0 到 N 减 1 的无偏索引,不能只取除以 N 后的余数,因为除非 N 均匀地划分为该范围,否则低索引出现的频率会稍微增加。修复方法是拒绝采样:计算适合该范围的 N 的最大倍数,如果抽取落在该截止值之上,则将其丢弃并再次抽取。它需要花费可忽略不计的额外抽取次数,并完全消除偏差。该工具在其选择的每个索引上执行此操作,这是直到丢失为止没有人注意到的细节。
如何使用随机化器?
界面有一个按钮和几个选择,下面是我运行它的方式。
将您的列表粘贴到输入框中,每行一项。如果您从电子表格中复制出一个逗号分隔的单元格,请将输入分隔符切换为逗号,它将在逗号上分割。默认情况下,修剪和空白行为处于开启状态,因此杂散空行和意外引导空间不会成为幻象条目。
选择您的模式 Shuffle 重新排序所有内容 Pick 抽奖获胜者 如果您选择 Pick,会出现一个小面板,您可以在其中设置抽奖次数以及是否允许重复。请留出重复次数以进行赠品,因此每个获胜者都是不同的人。只有当您真正想要替换采样时,例如当您模拟骰子样抽奖并且相同的值可以合法地重复时,才会打开重复次数。
击随机化,每次你都会得到一个新鲜的、独立的结果,所以如果你想重绘你只需再点击一次,一键复制输出,粘贴到你的公告、你的票证,或者结果需要居住的地方,如果你要求比列表所能提供的更多的唯一赢家,工具告诉你,而不是悄悄返回一个简短或重复的列表,这是我见过其他工具犯的一个错误。
实际上,我粘贴的列表遍布地图。有些日子它是抽奖的客户电子邮件列,有些日子是我团队中审查下一次拉取请求的名称,曾经是步行距离内的每家餐厅,因为没有人可以决定午餐。该工具不在乎物品是什么,只关心它们之间的距离是否干净。这就是为什么输入选项值得一秒钟关注:如果您的来源是电子表格单元格,逗号分隔符可以节省您的手工编辑,如果是带有空行的混乱复制粘贴,则空白默认值会在抽奖前悄悄清理。格式化输入的一分钟是您无需争论是否将杂散空行计入条目的一分钟。
我应该什么时候洗牌,什么时候挑选?
2种模式涵盖了不同的工作,下表就是我开始的时候希望有的速查表。
| 你想... | 用 | 重复 | 为什么 |
|---|---|---|---|
| 决定发言或轮流顺序 | 洗牌 | 不适用 | 每个人都待在里面,秩序是公平的 |
| 抽取一名赠品获胜者 | 挑选,数一 | 关闭 | 单一唯一结果 |
| 抽取几位获奖者 | 挑选,N 伯爵 | 关闭 | 独特的获胜者,没有双下倾 |
| 将人员分配到两个团队 | 洗牌,然后分手 | 不适用 | 将洗牌名单分成两半 |
| 样品替换为模拟 | 挑选,N 伯爵 | 论 | 相同的项目可能会通过设计重复出现 |
| 随机分配播放列表或阅读列表 | 洗牌 | 不适用 | 重新排序,无需掉落任何东西 |
经验法则:如果物品的计数保持不变,则洗牌。如果您想要的物品数量少于投入的数量,请选择。团队分配是人们过度思考的一个。洗牌完整列表,然后将前半部分作为 A 队,其余部分作为 B 队,并且两支球队的规模都是随机且平衡的。
公开赠品是否足够公平?
是的,原因值得简单说明,因为 "fair" 是工具的全部价值。 Fisher-Yates 洗牌、加密随机源和拒绝采样的组合意味着每个参赛者都有相同的机会,每组可能的获胜者都有同等的可能性。这比物理抽签更有力,因为滑动尺寸、折叠以及碗的混合程度都会引入偏差。
由于抽奖完全在您的浏览器中运行,因此您可以在流或会议期间在屏幕上实时进行抽奖,这是人们希望从公开抽奖中获得的透明度。没有什么内容发送到服务器,因此在点击和公告之间没有可以篡改结果的隐藏步骤。如果您想要审计跟踪,请屏幕记录抽奖:进入者列表可见,点击可见,获奖者立即出现。
我的名单是私人的吗?
这比它第一次出现更重要,因为人们随机化的列表通常不公开。候选入围名单、内部团队名称、客户条目和电子邮件列表都很敏感。随机化器使用普通的 JavaScript 在本地处理所有内容。您的列表从未上传、记录或存储,并且您可以在浏览器网络选项卡中确认这一点,单击随机化根本不会发出请求。一旦页面加载,它也会保持离线工作。
这是 Toolz 故意采取的立场,我在笔记中写下了推理 在线工具中的数据隐私。随机化器是一个很好的例子,说明了为什么它很重要:输入通常是一个真实的人列表,而真实的人列表正是你不希望坐在某个你从未审计过的服务器上的请求日志中的那种东西。
一些让抽奖更干净的习惯
Draw前先清理列表,打开如果一个人可能出现两次,则删除重复项,因此双条目不会秘密地将他们的赔率加倍,默认情况下,掉落空行是打开的,但值得一看,以确保尾随的空行没有被计算在内。
将计数与奖品相匹配 在 Pick 模式下,将计数设置为您需要的确切获奖人数并留下重复。如果您有三个奖品,请一次抽取三个奖品,而不是单次抽取三次,这样可以避免同名尴尬的情况在单独的点击中出现两次。
Redraw 公开,而不是秘密,如果获胜者不符合资格,在观看的人面前移除他们并重新绘制,公平性来自于过程可见,而不是来自于第一次点击的结果是最终的结果。
Keep it in the browser。I ship 的每一个工具一样,本地处理是默认的,因为它更快,而且私密。如果您正在组装一个小型实用程序的个人套件,则 随机数生成器 自然地与随机化器配对进行数值绘制,并且更广泛 开发人员生产力工具 roundup解释了为什么浏览器优先的工具箱值得构建。
值得一看的相关工具
如果随机选择是反复出现的需要,那么几个邻居就坐得很近。 随机数生成器 (crypto-grade)随机性相同的范围内绘制数字,这是当您选择的东西是一个值而不是列表中的项目时,您想要的 UUID 生成器 为记录和测试数据生成唯一标识符。 密码生成器 将相同的强随机源应用于生成安全密码。这三个都运行在浏览器中,没有注册,与随机化器完全相同,并且我覆盖了中该系列的标识符侧 密码生成器指南。
常见问题
列表随机化器如何工作?
该工具每行读取您的列表中的一项,然后重新订购每件物品或绘制您请求的获奖者。 洗牌使用 Fisher-Yates 算法,该算法在列表中遍历一次,并用随机选择的早期位置交换每个项目,产生一个均匀的随机顺序。 随机位置来自浏览器加密生成器,因此结果是真正的无偏见。
随机化真的公平吗?
是的。它借鉴了现代浏览器中内置的加密随机源 crypto。getRandomValues,并使用拒绝采样,因此没有索引比其他索引更有可能。结合 Fisher-Yates 洗牌,列表的每一次可能的排序都有同等的机会,这比手动洗牌或带有随机密钥的电子表格排序更公平。
如何从名单中随机挑选一个获胜者?
每行粘贴您的姓名,切换到选择模式,将计数设置为 1,然后单击随机化。 该工具返回一个随机名称。 要一次抽取几个获胜者,请将计数设置得更高并使重复禁用,以便每个获胜者都是独一无二的。
洗牌和挑选有什么区别?
shuffle 以新的随机顺序返回整个列表,因此没有添加或删除任何内容,仅重新排列。 Pick 返回一个子集,从列表中提取您指定的获奖者数量。 使用随机播放订单或座位,并选择赠品、样品或从较大的群体中选择几个人。
同一项目可以多次挑选吗?
Only if you enable repeats。默认情况下,Pick模式抽奖没有替换,所以每个赢家都是不同的项目,这是抽奖或赠品所需要的。打开重复允许用替换进行采样,其中相同的项目可以再次出现,这对于模拟很有用。
为什么它不能选择比我的列表更多的独特项目?
不重复,每个获胜者必须是一个不同的项目,因此您不能从八个列表中抽取十个独特的获胜者。 发生这种情况时,工具会告诉您而不是返回错误的结果。 降低计数以匹配您的列表大小或启用重复,以便可以重复使用项目。
我的列表是否上传到服务器?
No。所有解析和随机化都是在浏览器本地运行的,使用普通的JavaScript,并且没有任何传输,记录或存储,您可以在浏览器网络选项卡中确认这一点,当您单击Randomize时,不会提出任何请求。一旦页面加载,它也会离线工作。
我可以用它来抽奖或赠品吗?
是的。 每行粘贴您的参赛者一号,使用重复禁用的“选择模式”,并将计数设置为奖品数量。 每次点击都能吸引一套新鲜的、独立的独特的获奖者。 因为抽奖是无偏的,并且在客户端发生,您可以在屏幕上实时运行它以获得透明度。



