一个wordle小挂

前段时间看到了 wordle 这个游戏,觉得挺有意思。我刚开始的策略是前几个词尽可能把 26 个字母覆盖改一遍,然后最后一次机会就是一个排列组合的问题了。这样做一是因为我想要猜中的把握大一点(非酋实惨);二是因为我没有对可猜测单词集合的整体认识,不知道猜哪个词能筛选掉更多的不合法答案。今晚趁着背不进近代史,刚好思考了一下,顺便写了写。

初步想法

首先可以从源码里找到合法的长度为 5 的单词(记为 validWords)以及可能出现的答案(记为restWords)。

一个自然的想法是先建一棵至多六层的决策树,然后沿着树跑就行。但是这棵树每一个节点至多有上万个分支。鉴于我只给了自己一晚上的时间,要把这个决策树搜出来还是心里没底的,因为剪枝都得一点一点去试。

那有没有办法不做预处理,每次在线处理询问呢?换句话说,猜哪个词会让 restWords 尽可能减少呢?

假设我们猜一个词 v,可能返回的情况有不多于 3 5 3^5 35 种(每个位置灰黄绿三种可能),restWords 也被划分到这些情况之中,记第 i 种情况下有 c i c_i ci 种可能的答案,一个想法是用 c i c_i ci 的期望值,即 e v a l ( v ) = ∑ c i 2 ∣ r e s t W o r d s ∣ eval(v)=\sum \frac{c_i^2}{|restWords|} eval(v)=restWordsci2 作为衡量 v 好坏的标准。在 3B1B 的视频里,提出了另一种方法。

信息量

信息量和事件发生的概率成反比,比如经典的“明天太阳从东边升起”和“明天吐鲁番下雨”的例子。具体来说,有
h ( x ) = − log ⁡ 2   p ( x ) h(x) = -\log_2\ p(x) h(x)=log2 p(x)
而信息熵可以理解为所有可能的事件的信息量期望,表示某件事的不确定程度:
H ( X ) = − ∑ i p ( x i ) ⋅ log ⁡ 2   p ( x i ) H(X) = -\sum_i p(x_i) \cdot \log_2\ p(x_i) H(X)=ip(xi)log2 p(xi)
其实上面说的“所有可能的事件的信息量期望”和“某件事的不确定程度”乍一看是不容易建立起什么等价的关系的,但用期望表示不确定程度实际上是很符合直觉的。考虑事件 A,B,C,D 发生的概率都为 0.25,可以计算发生哪件事的信息熵为 0.25 × 4 × log ⁡ 2 4 = 2 0.25\times 4\times \log_2 4=2 0.25×4×log24=2;如果概率分别为 0.97,0.01,0.01,0.01,那么发生哪件事的信息熵为 0.24 < 2 0.24<2 0.24<2。因为 BCD 事件发生的可能性太小了,即便知道了 A 会发生,好像也没有那么吃惊了。

观察函数 f ( x ) = − x ⋅ log ⁡ 2   x f(x)=-x\cdot \log_2\ x f(x)=xlog2 x 的图像也可以清楚地知道,概率非常靠近 0 或非常靠近 1 的事件对熵的影响不大。

回到游戏

回到主题,我们实际上是用“信息熵”来衡量猜某个词的好坏。也就是每一回合我们都希望猜一个信息熵最大的词语,希望问出一个信息熵尽可能大的问题以期望获得更多信息,或者说让各种事件在我们的问题下更加“分散”。

几个问题

注意,如果只按上述分析,程序会猜一些属于 validWords 而不属于 restWords 的词语,因为它们的信息熵更大。但这在最后一次猜测会遇到问题,因为如果可能成为答案的词不多了的话,直接猜答案可能会是更好的选择。
那怎么衡量熵和概率之间的关系?直接将二者线性组合或许是个方法,但不够合理。
我们想要的实际上是猜词的期望次数尽可能少。猜一个词的期望就是 p*1 + (1-p) * (1 + (H))

你可能感兴趣的:(实践记录,信息熵,算法)