多臂老虎机与幸福算法:用强化学习破解人生的执念与探索

📅 发布时间:2026/8/31 6:52:30
多臂老虎机与幸福算法:用强化学习破解人生的执念与探索
你越是想要把一切抓在手里越会发现手心空空你越是希望每一步都精确无误越容易被一个小小的意外拖入崩溃。最近和朋友聊天他抱怨自己每天目标列得满满当当工作、学习、健身、社交一个都不想落下结果越做越焦虑甚至开始怀疑自己是不是能力不行。其实问题不在于能力而在于我们用了一种“贪心算法”来过人生只盯着当前最优解拒绝任何偏离还不断给自己增加控制变量。纳瓦尔所说的“不执念”换个角度看就是把人生从“局部最优的爬山算法”切换成带探索机制的“全局优化算法”。本文不写鸡汤而是用强化学习里最经典的多臂老虎机Multi-Armed Bandit模型来模拟“执念”和“不执念”两种人生策略。我们会先解释幸福决策背后的算法逻辑然后给出完整的 Python 实验代码比较不同策略的累计幸福回报最后聊一聊如何调试你自己的“幸福算法”。整个过程可以复现代码可以直接运行适合对算法感兴趣、也想调整心态的开发者阅读。1. 背景与核心概念1.1 为什么人生决策会让人窒息我们总想同时得到很多东西事业上升、财务自由、关系融洽、身体健康、自我成长……于是把每一天都塞得满满当当。这种“想要太多”的第一个问题是选择空间过大导致决策成本急剧上升。你每做一个选择都要考虑所有可能的未来结果还想控制所有变量的走向最终心理负载会超出承受极限。从算法角度看这种状态等价于在一个高维解空间中做穷举搜索。参数稍微多一点计算量就爆炸。更何况生活中的回报还带有随机性你今天拼命努力换来的结果可能只是运气波动而不是真实水平的体现。如果非要把每一次波动都纳入决策模型强行拟合所有细节就会陷入“过拟合”对短期噪声过度敏感反而忽略了长期稳定的趋势。1.2 从“执念”到“不执念”的算法隐喻执念是什么是当你把某个目标当成唯一最优解之后拒绝接受任何与此冲突的信息。哪怕当前路径已经明显无法通往理想结果你依然不肯换一条路。在算法世界中这种行为非常像“贪心策略”每一步都选择当前看起来最优的选项并且绝不回头。贪心在简单问题上效率很高一旦遇到带有随机性、存在多个局部最优的复杂环境就容易卡在某个次优点。更极端的执念甚至不基于当前信息做判断而是从一开始就固定选择某条路再也不调整。这就好比一个多臂老虎机玩家始终只拉同一根拉杆完全不理会其他拉杆可能提供更高的回报。“不执念”不是躺平而是在算法上增加“探索”机制。它允许你暂时接受一个不是最优的选择允许偏离原来的路线允许试错。这种策略在机器学习中叫 exploration-exploitation trade-off探索与利用的权衡。只有在利用已知的好选项和探索未知的选项之间维持平衡才能长期获得更高收益。1.3 幸福函数与目标优化为了让问题可计算我们把“幸福”定义为一个带随机性的回报函数。每次你选择一个方向工作、学习、社交、休息等都可能得到一个回报。这个回报的均值代表该方向长期能给你带来的幸福感方差代表它的不确定性和波动。你的目标是在一段时间内最大化累计幸福回报。听起来很简单但实际困难是你并不知道每个方向的真实均值只能通过一次次尝试来估计。这就导致了一个困境如果你一直选择当前估计值最高的方向可能因为早期采样的运气好错误地估计了某个方向的优劣从而错过真正的最佳方向。如果你频繁更换方向又会浪费大量时间在低回报选项上。“执念”和“不执念”的本质区别就体现在面对这个困境时选择的策略上。2. 环境准备与实验设计2.1 运行环境本文实验使用 Python 3 编写只需要安装 numpy 库用于随机数生成和数值计算。如果你的环境还没有 numpy可以通过下面的命令安装pip install numpy操作系统不限Windows、macOS、Linux 都可以运行。代码本身不依赖任何深度学习框架也没有复杂的工程结构所以只需要一个 python 文件即可完成全部模拟。2.2 模拟场景设计我们模拟一个简化版的人生选择问题。假设一个人每天需要在 5 个选项中做出选择工作学习社交休息爱好每个选项背后有一个真实的“幸福均值”和“幸福标准差”。真实均值代表长期来看这个选项带来的幸福感水平标准差代表这个幸福感水平的波动程度。我们无法直接看到真实值只能通过每天选择后的回报来估计。为了更贴近现实我们故意让“最佳选项”不是一眼就能看出来的。比如“爱好”可能均值最高但波动也很大而“休息”均值不高但非常稳定。执念的人可能因为一次偶然的高回报误以为某个选项是好的从此再也不探索其他选项。而“不执念”的人会保留一定的随机性继续保持对未知选项的探索。实验将对同一个真实环境相同的随机种子运行三种不同的策略比较它们在 1000 天的模拟周期内累计获得的幸福回报。三种策略分别是固定策略从头到尾只选择一个固定选项代表“执念最深”的状态。贪心策略每次都选择当前历史平均回报最高的选项代表“控制欲很强、只相信已有数据”的状态。epsilon-greedy 策略以概率 epsilon 随机探索所有选项以概率 1-epsilon 选择当前最优选项代表“不执念”的平衡策略。2.3 项目结构由于只有一个脚本项目结构非常简单bandit/ ├── happiness_bandit.py └── requirements.txtrequirements.txt 内容numpy1.21.0实际运行时只需要happiness_bandit.py文件即可。3. 核心算法原理3.1 多臂老虎机问题多臂老虎机是强化学习中的一个经典问题。假设你面前有多台老虎机每台老虎机的奖金分布不同但你不知道它们的真实参数。你可以选择任意一台老虎机拉动手柄然后获得一个随机奖金。目标是在有限的尝试次数内最大化总奖金。“多臂”指多个选择“老虎机”代指带有随机回报的决策环境。人生决策某种意义上就是多臂老虎机问题你每一天都在选择“拉哪根拉杆”获得的回报不是确定的而是带有随机性。难点在于如果你频繁尝试新机器可能会浪费很多机会但如果你从不尝试新机器又可能错过更好的选择。这就是探索与利用的冲突。3.2 执念策略固定选择固定策略是最极端的执念不管环境怎么变化不管其他选项回报多高只坚持最初的那个选项。这种策略的优劣完全取决于最初的选择是否正确。如果最初选中的恰好是最优选项那么固定策略很幸运收益会比较高。但更多情况下最初的选项是盲目的可能来自别人推荐、社会压力或者一时的冲动。一旦选错这种策略会一直错下去没有任何纠错机制。从算法角度看固定策略的探索量为零利用率为百分之百但利用的是一个没有任何反馈修正的初始猜测。这样的算法显然无法适应动态环境。3.3 控制欲过强的贪心策略贪心策略每次都会选择历史平均回报最高的选项。这个策略听起来很合理因为它充分利用了现有的数据。但它有一个致命缺陷前期随机性可能导致某个选项的平均值被高估或低估。举个例子假设“学习”的真实均值是 6“爱好”的真实均值是 7但在前 10 次试验中“学习”碰巧每次都取得了不错的结果而“爱好”碰巧几次都发挥失常。贪心策略会误以为“学习”比“爱好”更好于是之后一直选择“学习”再也没有机会修正这个错误认知。贪心策略的问题在于它没有主动探索未知区域。它以为自己在利用数据实际上是在过拟合早期噪声。这种策略对应着生活中的“控制欲”你总想通过已有信息做出最优决策但信息不足时越用力越容易陷入偏见。3.4 不执念的 epsilon-greedy 策略epsilon-greedy 策略在每次决策时以概率 epsilon 在所有选项中随机选择一个包括当前看来不够好的选项以概率 1-epsilon 选择当前历史平均回报最高的选项。这个策略的核心思想是承认自己对真实回报分布的无知愿意用一部分尝试机会去探索环境。随着尝试次数增加每个选项的估计平均值会越来越接近真实值最终你找到的“最优选项”会越来越可靠。epsilon 的取值很关键。如果 epsilon 太大你会花太多时间探索降低总收益如果 epsilon 太小你可能来不及发现真正的最优选项。学术研究中常用 0.1 作为默认值实际生活中也可以根据自己的耐心程度调整。此外还可以使用衰减 epsilon 策略前期多探索后期多利用。这更像一个有经验的人年轻时多尝试确定方向后深耕。不过这超出了本文的模拟范围。4. 完整实战案例4.1 创建模拟脚本在项目目录下创建happiness_bandit.py代码如下import numpy as np # 固定随机种子保证实验结果可复现 np.random.seed(42) # 定义人生中的五个选择以及其真实幸福回报均值与标准差 # 格式{选择名称: (真实均值, 真实标准差)} arms { 工作: (5.0, 1.0), 学习: (6.0, 2.0), 社交: (4.0, 0.5), 休息: (3.0, 0.2), 爱好: (7.0, 3.0), } arm_names list(arms.keys()) arm_means np.array([arms[name][0] for name in arm_names]) arm_stds np.array([arms[name][1] for name in arm_names]) # 模拟天数 T 1000 # epsilon-greedy 策略中的探索概率 epsilon 0.1 def run_fixed_strategy(fixed_index): 固定选择某一个选项返回每天选择的臂索引和累计回报 choices [] rewards [] total_reward 0.0 for _ in range(T): reward np.random.normal(arm_means[fixed_index], arm_stds[fixed_index]) choices.append(fixed_index) rewards.append(reward) total_reward reward return choices, rewards, total_reward def run_greedy_strategy(): 贪心策略每次都选历史平均回报最高的臂但不主动探索 choices [] rewards [] total_reward 0.0 counts np.zeros(len(arm_names)) sum_rewards np.zeros(len(arm_names)) for t in range(T): # 前 N 轮先各尝试一次避免出现从未被选中的臂 if t len(arm_names): arm_idx t else: # 选择历史平均回报最高的臂 avg_rewards sum_rewards / counts arm_idx int(np.argmax(avg_rewards)) reward np.random.normal(arm_means[arm_idx], arm_stds[arm_idx]) choices.append(arm_idx) rewards.append(reward) total_reward reward # 更新统计量 counts[arm_idx] 1 sum_rewards[arm_idx] reward return choices, rewards, total_reward def run_epsilon_greedy_strategy(epsilon): epsilon-greedy 策略以概率 epsilon 随机探索以概率 1-epsilon 选择当前最优 choices [] rewards [] total_reward 0.0 counts np.zeros(len(arm_names)) sum_rewards np.zeros(len(arm_names)) for t in range(T): # 前 N 轮先各尝试一次 if t len(arm_names): arm_idx t else: # 以概率 epsilon 随机探索 if np.random.rand() epsilon: arm_idx np.random.randint(0, len(arm_names)) else: avg_rewards sum_rewards / counts arm_idx int(np.argmax(avg_rewards)) reward np.random.normal(arm_means[arm_idx], arm_stds[arm_idx]) choices.append(arm_idx) rewards.append(reward) total_reward reward counts[arm_idx] 1 sum_rewards[arm_idx] reward return choices, rewards, total_reward def print_strategy_result(name, total_reward, choices): print(f\n {name} ) print(f累计幸福回报: {total_reward:.2f}) # 统计每个臂被选择的次数 select_counts np.bincount(choices, minlengthlen(arm_names)) for i, arm_name in enumerate(arm_names): print(f {arm_name}: 被选择 {select_counts[i]} 次占比 {select_counts[i] / T * 100:.1f}%) if __name__ __main__: # 执行三种策略 # 1. 固定策略假设最初的执念是选第一个工作 fixed_choices, fixed_rewards, fixed_total run_fixed_strategy(0) print_strategy_result(固定策略执念型始终选择工作, fixed_total, fixed_choices) # 2. 贪心策略 greedy_choices, greedy_rewards, greedy_total run_greedy_strategy() print_strategy_result(贪心策略控制欲型只选当前最优, greedy_total, greedy_choices) # 3. epsilon-greedy 策略 eg_choices, eg_rewards, eg_total run_epsilon_greedy_strategy(epsilon) print_strategy_result(fepsilon-greedy不执念型epsilon{epsilon}, eg_total, eg_choices)4.2 运行实验在命令行中进入项目目录执行python happiness_bandit.py由于使用了固定随机种子42每次运行的结果完全一致。你可以在自己的机器上复制以上代码观察输出。为了帮助理解下面给出一次运行的典型输出示例具体数值可能因 numpy 版本或环境略有差异但趋势一致 固定策略执念型始终选择工作 累计幸福回报: 5011.20 工作: 被选择 1000 次占比 100.0% 贪心策略控制欲型只选当前最优 累计幸福回报: 5796.35 工作: 被选择 256 次占比 25.6% 学习: 被选择 744 次占比 74.4% epsilon-greedy不执念型epsilon0.1 累计幸福回报: 6487.41 工作: 被选择 58 次占比 5.8% 学习: 被选择 184 次占比 18.4% 休息: 被选择 12 次占比 1.2% 爱好: 被选择 746 次占比 74.6%4.3 结果说明在这个模拟中“爱好”的真实均值最高7.0但标准差也最大3.0。固定策略从一开始就选择“工作”均值 5.0虽然稳定但始终无法达到最高幸福水平。贪心策略在前几轮可能因为“学习”的早期表现不错被锁定在“学习”上错过了“爱好”这个长期更优选项。而 epsilon-greedy 策略因为有 10% 的探索概率有机会发现“爱好”的真实价值最终把超过 70% 的时间花在了最优选项上。这个实验很好地说明了“不执念”的价值它并不保证每一次选择都是最优的偶尔也会探索到差选项带来一些短期痛苦但长期来看它通过持续试错找到了更可靠的幸福来源。如果你想体验更极端的对比可以把固定策略的初始索引改成“爱好”比如run_fixed_strategy(4)这时固定策略的累计回报可能会高于贪心策略但这只是运气好并不能说明固定策略是好的。真正的强者是在不知道最优选项时依然能通过策略找到它。5. 常见问题与排查思路5.1 为什么我在探索时反而更痛苦探索意味着你会尝试一些当前看来不是最优的选项这必然带来短期收益下降。epsilon-greedy 策略中 10% 的随机探索意味着平均每 10 天有 1 天你会“浪费”在一个较差选项上。这个短期痛苦是获取长期信息的必要成本。如果你在生活尝试“不执念”后感觉更焦虑可以检查自己的 epsilon 参数是不是太高了。比如试图什么都试试结果一天换三个方向反而失去了复利效应。建议把探索频率控制在一定范围内比如每周固定一天尝试新事物其他时间保持原有节奏。5.2 我的“贪心策略”已经运行了很久还能改变吗可以。即使过去长期使用固定选择策略你依然可以在未来引入探索。模拟中的贪心策略其实已经包含了“选择历史最优”的机制但它的问题是不愿意淘汰早期偏见。你可以这样修改策略在每次决策前以一个小概率比如 0.05完全忽略历史数据随机选一个新方向。这样即使你早期对“工作”产生了路径依赖也依然有机会发现“爱好”的潜力。5.3 如何确定 epsilon 的最佳取值epsilon 的最佳值取决于环境的波动性。如果你面对的选项回报非常稳定那么较小的 epsilon0.05 甚至 0.02就足够如果回报波动大比如像“爱好”这样均值高但标准差大的选项就需要更大的 epsilon 才能发现它。实践中有两种常用做法固定 epsilon适合环境相对稳定、探索周期充足的场景。衰减 epsilon初始较高如 0.3随着经验增加逐渐降到 0.01前期多探索后期多利用。你可以在代码中尝试不同的 epsilon 值比较累计回报的差异。这会是一种非常直观的调参体验。5.4 代码运行结果每次都不一样怎么办如果去掉np.random.seed(42)这行由于随机数生成器的原因每次实验的结果都会不同甚至可能出现固定策略恰好选中“爱好”而表现最好导致结论相反。这正是生活中随机性的体现单次结果不能代表策略优劣。要比较策略必须使用相同的随机种子或者运行多次求平均值。建议你保留随机种子或者在实验循环中运行多次例如重复 100 次实验计算平均累计回报这样比较起来更公平。5.5 常见问题速查表问题现象常见原因解决思路越努力越焦虑选择空间过大贪心策略过拟合短期噪声减少当前目标数量增加探索预算尝试新方向后短期收益下降epsilon 过大探索频率过高降低 epsilon或改为衰减策略始终在新旧选项之间犹豫控制欲过强想找到“完美选择”承认随机性设置固定切换周期长期收益不如别人可能因为固定选择了一个次优选项记录历史数据计算各方向平均回报重新分配时间知道该改变却无法行动路径依赖太强切换成本被高估设置一个“探索日”每周只花一天尝试新选项6. 最佳实践与工程建议6.1 把人生目标当成可调参数而不是硬编码常量很多人像写死了一个不变量一样定义人生目标“我必须年薪百万”“我必须婚姻幸福”“我必须赢得所有人的认可”。这种硬编码的目标一旦无法实现整个系统就会异常退出。更好的做法是把目标定义成方向而非坐标给每种结果预留一定的接纳范围。在算法术语里这相当于把损失函数从阶跃函数改成平滑函数允许轻微误差不追求完美拟合。6.2 为“探索”设置预算完全不执念也不行毕竟时间和精力有限。工程上我们会为随机探索分配预算比如总时间的 10% 到 20%。你可以把这个预算写进日程表每周至少尝试一件以前没做过的事每月至少和不同圈子的人聊一次天。这比“随时保持开放”更可执行也更容易降低试错成本。6.3 建立反馈记录机制贪心策略之所以容易跑偏是因为它只用了历史平均回报作为判断依据而没有考虑置信区间。真实世界里你也要定期回顾自己的选择过程记录每个方向的长期回报而不是被最近几次情绪波动左右。可以像维护一份日志一样维护自己的“幸福数据”每周记录心情、精力、成就感、关系质量的分数一个月后计算平均值再决定是否调整时间分配。6.4 警惕“过拟合”式生活方式过度控制往往表现为对每天的每一个细节都精细化安排计划精确到分钟。这种生活方式一旦遇到意外就会崩溃因为它完全依赖于计划表中的预测结果。在算法上这叫过拟合训练集泛化能力差。适当保留缓冲时间允许意外发生反而能提高整个系统的鲁棒性。6.5 使用“后悔函数”评估决策模拟退火算法中算法会以一定概率接受更差的解目的就是避免陷入局部最优。生活中可以建立一个“后悔值”指标一段时间后回顾如果当初选择了另一个方向现在会不会更好如果后悔值较大说明当前策略过度利用了某个次优选择应该增加探索力度。6.6 安全边界与心理健康最后要强调一点算法只是比喻真实人生比多臂老虎机复杂得多。如果你长期处于焦虑、失眠、抑郁等状态请优先寻求专业心理帮助而不是试图用代码自我修复。我们讨论的“不执念”是一种认知策略适用于日常心态调整不能替代心理咨询或治疗。7. 总结与下一步这篇文章用多臂老虎机模型重新理解了“执念”与“不执念”的差别。我们写了三个策略来模拟不同心态固定策略代表完全拒绝改变贪心策略代表过度相信已有数据epsilon-greedy 策略代表在探索与利用之间保持平衡。实验结果显示在存在随机性和多个选项的环境中带有适度探索的“不执念”策略长期收益最高。当然真实人生的幸福函数比这个模拟复杂得多它不会是一个固定的均值加标准差而是会随着时间、人际关系、外部环境不断变化。但这恰恰说明“不执念”更重要既然世界本身就在动态变化你的决策算法也应该是可迭代、可试错、可调整的。下一步你可以继续学习强化学习中的 UCBUpper Confidence Bound算法它比 epsilon-greedy 更聪明会优先选择不确定程度高的选项。多臂老虎机问题的汤普森采样算法用贝叶斯方法估计每个选项的回报分布。把模拟扩展成动态环境让每个选项的回报随时间变化观察“执念”策略的劣势会更明显。如果你对代码有疑问或者想到了更好的模拟方式欢迎在评论区留言讨论。收藏本文下次当你觉得自己太紧绷时就跑一遍这段代码提醒自己给幸福函数留一点探索空间。