公司动态

数学建模竞赛实战:基于信息熵的Wordle求解策略与可视化分析

📅 2026/8/28 1:18:46
数学建模竞赛实战:基于信息熵的Wordle求解策略与可视化分析
1. 从“思路”到“成品”一次完整的数模竞赛解题复盘去年带队参加美赛我们组选的正是C题。说实话拿到题目那一刻看到“Wordle”这个关键词心里是既兴奋又没底。兴奋的是这不像一些纯理论题那么抽象它有一个具体的、大家可能都玩过的游戏作为背景没底的是如何从一个简单的猜词游戏提炼出有深度的数学模型并做出让评委眼前一亮的数据分析和可视化。网上流传的所谓“思路解析”和“示例代码”往往点到为止或者干脆就是一堆代码的堆砌缺乏从问题理解到模型构建再到代码实现和论文呈现的完整逻辑链条。今天我就以那次参赛的真实经历为蓝本抛开那些华而不实的噱头拆解一下如何系统性地攻克这类“数据分析策略优化”型的美赛C题。无论你是正在备赛还是对数学建模感兴趣希望这篇超过5000字的复盘能给你带来一些实实在在的、能“抄作业”的启发。我们的目标很明确不是简单地复现一个Wordle求解器而是要回答题目背后的一系列问题——如何量化猜测策略的优劣如何设计一个“智能”的猜测策略如何用数据验证你的策略比别人或基准策略更有效最终如何将你的思考过程、模型结果清晰、有力、美观地呈现在论文里这个过程恰恰是数学建模竞赛的核心定义问题、建立模型、求解分析、呈现结果。下面我就按照我们实际推进的流程分几个核心部分来展开。2. 问题拆解与核心指标定义我们到底要建什么模很多队伍一开始就埋头找算法、写代码这是大忌。美赛C题通常会给一个开放性的现实问题第一步必须是精确理解题目要求并将其转化为可量化、可建模的科学问题。2.1 理解题目背景与约束当年的C题核心是分析Wordle游戏。我们需要明确游戏规则5个字母的单词6次猜测机会每次猜测后获得颜色反馈绿色字母位置都正确黄色字母正确但位置不对灰色字母不存在于目标词中。题目通常会要求我们做几件事评估策略对给定的一些猜测策略例如总是以某个固定词开头进行评价。设计策略创建自己的、更优的猜测策略。进行分析可能涉及不同词表、猜测次数分布、困难单词分析等。撰写报告将分析过程、结果和结论写成论文。我们的首要任务是将这些模糊的要求“数学化”。例如“评估策略的优劣”就需要定义一个或多个性能指标。2.2 定义关键性能指标KPIs这是建模的基石。我们不能只说“这个策略好”而要说“这个策略在XX指标上表现更优”。我们团队当时定义并讨论了以下几个核心指标平均猜测次数Average Number of Guesses, ANG最直观的指标。对词表中的每一个单词作为目标词用你的策略去猜记录猜中所需的次数然后求平均值。ANG越低策略效率越高。这是我们的核心优化目标。猜测次数分布光看平均值可能掩盖问题。一个策略可能平均3.5次猜中但可能有10%的单词需要6次即失败边缘。因此我们需要统计猜测次数的直方图关注最大猜测次数和失败率猜测次数6的比例。一个稳健的策略应该让分布更集中尾部更短。首次猜测后的平均剩余候选词数量这个指标衡量策略的“信息获取效率”。一个好的首次猜测应该能最大程度地缩小可能性空间。计算首次猜测后根据反馈颜色剩余的可能目标词集合的平均大小。这个值越小说明首次猜测的“区分度”越高。计算复杂度/时间虽然比赛不严格考核但在模型描述中可以提及。一个理论上最优但需要超级计算机运行一天的策略其实际应用价值有限。注意在论文中你需要明确声明你采用哪些指标以及为什么。我们选择了ANG作为主要比较指标同时用分布图展示稳健性用信息论概念如熵来佐证我们策略的设计原理这样逻辑就很完整。2.3 确定建模边界与假设任何模型都有边界。我们需要明确词表使用官方Wordle词表约2300个答案词还是包含更多允许猜测的词题目通常会有说明或提供数据。我们以官方答案词表作为目标词集合以更大的允许猜测词表作为策略的猜测空间。策略的“知识”你的策略算法是否“知道”完整的词表在真实游戏中玩家是知道词表存在的虽然不精确知道是哪个词。因此假设策略知晓词表是合理的这属于离线策略优化。如果策略不知道词表那就是在线学习复杂度过高不适合比赛。反馈的确定性假设游戏反馈是完美准确的不考虑任何错误。把这些想清楚并写在论文的“问题重述”或“模型假设”部分能体现你思考的严谨性。3. 策略设计从朴素方法到信息论优化这是整个项目的技术核心。策略的本质是一个函数输入是当前已知的反馈信息历史猜测及其颜色结果输出是下一个要猜的单词。3.1 基准策略建立比较的基线在展示自己的“神策略”之前必须先有几个简单的策略作为对比基线否则无法体现优越性。我们实现了以下两个随机策略每次猜测时从当前符合所有历史反馈约束的候选词列表中随机选择一个。这是最弱的基线。固定首词随机后续策略比如总是以“CRANE”一个包含常见字母且无重复的单词开头然后后续猜测采用随机策略。这可以用来测试一个“好”的首词究竟能带来多少提升。实现这些基准策略的代码很简单但至关重要。它们的ANG将成为我们优化策略需要超越的“及格线”。3.2 核心策略基于信息熵的贪婪算法这是我们策略的核心也是很多优秀论文采用的思路。其思想来源于信息论每次猜测应选择那个能提供最大期望信息量即减少最多不确定性的单词。具体步骤与原理候选词集Possible Solutions维护一个列表S包含所有与至今所有反馈都一致的单词。初始时S就是整个答案词表。计算每个猜测单词的“价值”对于每一个可以考虑的猜测单词g可以来自更大的猜测词表我们模拟如果用它去猜可能会得到什么样的反馈模式颜色组合。对于每一种可能的反馈模式f我们计算如果得到该反馈剩余的候选词数量count(S, g, f)。即在S中有多少单词如果作为目标词会对猜测g给出反馈f。计算该反馈模式出现的概率p(f) count(S, g, f) / |S|。计算得到该反馈后所获得的信息量信息熵的减少。一个常用的简化度量是期望剩余候选词对数的负值或直接最小化期望剩余候选词数量。更经典的是计算期望信息增益E[Information Gain] Σ p(f) * log2(|S| / count(S, g, f))这个公式的含义是选择g后剩余不确定性的期望减少量。log2(|S| / count(S, g, f))表示如果得到反馈f不确定性减少了多少比特。概率加权求和就是期望值。实际上为了计算方便很多实现包括我们采用一个等价的目标最小化“期望剩余候选词数量Expected Remaining Candidates”的某种形式或者直接选择那个能最均匀地分割当前候选集的单词。一个非常流行的启发式标准是最小化“最坏情况下的剩余候选词数量”但这不一定能优化平均次数。选择与猜测选择能使期望信息增益最大或期望剩余候选词最少的单词g*作为本次猜测。提交猜测获得真实反馈。更新候选集利用真实反馈f_real过滤S新的S { word in old_S | feedback(word, g*) f_real }。重复回到步骤2直到猜中或达到6次限制。为什么这个方法有效它模拟了一个理性决策者的思考过程在众多选择中选择那个最能“缩小搜索范围”的选项。从数学上看它是在每一步进行局部最优选择贪婪虽然不能保证全局最优即绝对最小的平均猜测次数但在实践中效果极好且计算上可行。3.3 代码实现关键细节与优化直接实现上述算法计算量巨大。对于每一步都要遍历猜测词表~13000词中的每个词g对每个g又要遍历当前候选集S最多~2300词来计算所有可能的反馈分布。这是 O(|G| * |S|) 的复杂度需要优化。我们的优化实践预计算反馈模式最耗时的操作是计算feedback(target, guess)。我们可以预先计算一个巨大的矩阵feedback_matrix[target_idx][guess_idx]将反馈编码为整数例如三进制数。这样在模拟中只需要查表速度极快。虽然初始化这个矩阵需要一些时间约几分钟但一旦计算完成后续所有模拟都受益。# 伪代码示例反馈编码例如0灰1黄2绿 def encode_feedback(feedback_tuple): # feedback_tuple 如 (2,0,1,0,0) 代表 绿灰黄灰灰 code 0 for color in feedback_tuple: code code * 3 color return code # 预计算矩阵 n_answers len(answer_list) n_guesses len(guess_list) feedback_mat np.zeros((n_answers, n_guesses), dtypenp.int32) for i, target in enumerate(answer_list): for j, guess in enumerate(guess_list): feedback_mat[i, j] encode_feedback(get_feedback(target, guess))缩小猜测词搜索空间在每一步并非所有 ~13000 个词都是好的候选。一个常见的启发式方法是只在当前候选集S中寻找最优猜测词。即我们只考虑那些有可能是答案的词来猜。这能极大减少计算量且理论上有支持在信息论上最优猜测词往往就在候选集中。我们实现时将这一步作为一个可配置的选项并对比了效果。缓存与剪枝对于相同的候选集S其最优猜测是确定的。如果遇到之前计算过的S可以通过对S中单词ID排序后哈希来判断可以直接查缓存避免重复计算。这在模拟大量单词时能节省大量时间。首词的特殊处理第一步没有历史反馈候选集S就是整个答案词表。计算全局最优的首词是一个经典问题。我们可以离线计算好。通过运行我们的算法在第一步时我们计算出“CRANE”、“SALET”、“RAISE”等词的信息增益并选择最优的作为我们策略的固定首词。在我们的计算中“SALET”表现略优于“CRANE”。在论文中我们展示了不同首词的期望信息增益对比表格这本身就是一个很好的分析点。4. 实验、分析与数据可视化用证据说话模型和策略建好了接下来就是用数据验证并将结果清晰地展示出来。这部分是论文获得高分的关键。4.1 实验设计我们对完整的答案词表约2300词进行模拟测试策略我们的信息熵贪婪策略两种变体猜测词范围限制在S内 vs 使用全量猜测词表。对比策略随机策略、固定首词随机策略。评估指标记录每个目标词下的猜测次数计算ANG、成功率≤6次猜中的比例、猜测次数分布。4.2 核心结果可视化这里分享几个我们当时做的且效果很好的图表1. 猜测次数分布直方图并列对比这是最重要的图之一。将不同策略的猜测次数分布放在一起对比一目了然。import matplotlib.pyplot as plt import seaborn as sns # 假设有四个策略的结果列表results_entropy, results_random, ... strategies [Entropy (Restricted), Entropy (Full), Fixed First Random, Pure Random] all_results [results_entropy_res, results_entropy_full, results_fixed, results_random] fig, axes plt.subplots(2, 2, figsize(12, 10)) axes axes.flatten() for ax, strategy_name, results in zip(axes, strategies, all_results): ax.hist(results, binsrange(1, 9), alignleft, rwidth0.8, edgecolorblack) ax.set_xlabel(Number of Guesses) ax.set_ylabel(Frequency) ax.set_title(f{strategy_name}\nAvg{np.mean(results):.3f}, Win%{np.sum(np.array(results)6)/len(results)*100:.1f}%) ax.set_xticks(range(1, 8)) ax.grid(axisy, alpha0.75) plt.tight_layout() plt.savefig(guess_distribution_comparison.png, dpi300) plt.show()这张图能清晰显示我们的熵策略分布高度集中在3、4次猜测尾部6次以上极少而随机策略分布分散失败率高。2. 平均猜测次数ANG对比条形图简洁明了地展示核心指标的优劣。ang_values [np.mean(r) for r in all_results] std_values [np.std(r) for r in all_results] # 可以加误差棒 plt.figure(figsize(8,5)) bars plt.bar(strategies, ang_values, color[skyblue, lightgreen, orange, lightcoral]) plt.ylabel(Average Number of Guesses (ANG)) plt.title(Comparison of Average Performance) plt.ylim(0, max(ang_values)*1.1) # 在柱子上标注数值 for bar, v in zip(bars, ang_values): plt.text(bar.get_x() bar.get_width()/2, bar.get_height()0.05, f{v:.3f}, hacenter, vabottom) plt.grid(axisy, alpha0.3) plt.tight_layout()3. 累积分布函数CDF图这张图能更好地展示“在X次猜测内解决的概率”。plt.figure(figsize(10,6)) for strategy_name, results in zip(strategies, all_results): sorted_counts np.sort(results) cdf np.arange(1, len(sorted_counts)1) / len(sorted_counts) plt.plot(sorted_counts, cdf, marker., linestyle-, linewidth2, labelstrategy_name) plt.xlabel(Number of Guesses Required) plt.ylabel(Cumulative Probability) plt.title(Cumulative Distribution Function (CDF) of Guesses Needed) plt.axvline(x6.5, colorgray, linestyle--, alpha0.5, label6-guess limit) plt.legend() plt.grid(True, alpha0.3) plt.tight_layout()从CDF图可以轻松读出我们的策略在4次猜测内解决约80%的单词而随机策略可能连50%都不到。4. “困难词”分析表格与词云分析那些需要5次或6次才能猜中的单词困难词的特征。我们计算了这些单词的字母频率、元音辅音比例、是否包含稀有字母如J, Q, Z等。表格列出Top 10困难词及其被猜中的次数。词云将困难词按猜测次数加权生成词云视觉上突出“最难”的词。4.3 深入分析为什么这些词难仅仅展示结果不够需要分析。我们发现困难词通常有几种类型字母模式常见如“SWILL”包含S, W, I, L这些常见字母导致前几次反馈信息量低难以区分。存在重复字母如“FERRY”重复的R。我们的反馈模式颜色对重复字母的处理需要特别小心算法必须能正确处理。属于“单词家族”一组单词彼此之间非常相似如“SILLY”, “SALLY”, “SULLY”直到最后一步才能区分开。我们在论文中用一小节专门分析这些案例并展示我们的策略是如何一步步推理的可以附上猜测序列的日志这极大地增强了论文的说服力和故事性。5. 论文撰写与可视化呈现的实战技巧代码跑出结果只是成功了一半如何写在论文里是另一半。5.1 模型描述部分不要只扔公式和代码。用流程图描述策略的核心循环。初始候选集 S 全部答案词 While 未猜中且次数6: 1. 对于每个候选猜测词 g计算其相对于当前S的期望信息增益 EIG(g)。 2. 选择 EIG(g) 最大的词作为本次猜测 g*。 3. 提交 g*获得真实反馈 f。 4. 用 f 过滤 SS {w in S | feedback(w, g*) f}。配合文字说明每个步骤的数学含义和计算方式如信息增益公式。5.2 结果分析部分先总后分先给出核心结论我们的策略ANG为3.42显著优于基准策略的4.89再展开细节。图表结合每一个重要的图表下面都必须有详细的文字描述。不要写“如图1所示”而要写“从图1的分布对比可以看出熵策略的猜测次数高度集中在3-4次其分布曲线陡峭且右尾极短这表明策略具有高效率和强稳健性。相比之下随机策略的分布则平坦且分散。”指出异常与解释如果图表中有异常点比如某个词猜了6次主动分析它说明原因如上文的“困难词分析”。这体现了你思考的深度。5.3 可视化美学与一致性配色统一全文图表使用一致的配色方案。例如我们的策略用蓝色系基准策略用灰色或红色系。可以使用seaborn的set_palette或set_style。字体清晰确保图表中的坐标轴标签、图例字体足够大在论文PDF中清晰可读。保存图片时DPI设置为300。多子图排版像上面的分布对比图使用subplots整齐排列比分开画四张图更专业。附录代码将核心的、可读性高的算法代码放在附录中。代码要有简要注释但不必每行都注。重点展示算法框架和关键函数。6. 常见陷阱与我们的踩坑记录回顾整个过程有几个坑是新手极易掉进去的词表混淆Wordle有两个词表——答案词表~2300词和允许猜测词表~13000词。在模拟时目标词必须来自答案词表而猜测词可以来自允许猜测词表取决于策略设计。弄混会导致结果完全错误。我们一开始就错了导致ANG异常地低后来仔细核对数据源才纠正。反馈逻辑错误实现get_feedback(target, guess)函数是基础但处理重复字母非常棘手。例如target“ABBEY” guess“BLEED”。第二个E是什么颜色规则是优先分配绿色然后从左到右分配黄色且每个目标字母最多只能匹配一次。必须严格按照这个逻辑实现我们在这里调试了很久。建议用大量边缘案例测试你的反馈函数。性能瓶颈与优化过早一开始不要过度优化。先实现一个正确但慢的版本比如用集合操作过滤候选词确保逻辑正确。得到正确结果后再用预计算矩阵、缓存等方法进行优化。我们一开始就想一步到位写高性能代码结果bug频出反而耽误时间。忽略随机性随机策略的结果每次运行都不同。为了公平比较应该对随机策略进行多次模拟比如100次取ANG的平均值并报告其方差。我们在论文中给出了随机策略的均值和95%置信区间这样对比更有说服力。可视化过于花哨或简陋避免使用3D饼图、彩虹色等不专业的图表。坚持使用柱状图、折线图、直方图、散点图等学术圈接受的格式。同时图表不能只有一个标题必须有清晰的坐标轴标签、单位、图例。那次美赛我们最终获得了Meritorious Winner一等奖。回过头看胜出的关键不在于用了多高深的算法而在于完整、清晰、有深度的解决问题流程从精准的问题量化到合理的模型设计信息熵再到严谨的实验验证和深入的结果分析最后用专业、美观的方式呈现出来。整个过程中代码和可视化是工具是为你严密的逻辑和深刻的洞察服务的。希望这篇基于真实项目经验的超长解析能帮你避开我们踩过的坑更自信地应对未来的数模挑战。记住思路永远比代码更重要。