🏠 总目录📚 本教程 20 · 公平分配的算法
📑 本页目录(点开跳转)

20 · 公平分配的算法

48 分钟 | ⭐⭐ 最大化乘积,白送你 EF1 + PO


🎯 一句话

上一章说「EF1 一定存在」,这一章给出三个真能跑的算法:轮流拿(最快)、嫉妒图(最通用)、最大 Nash 福利(唯一同时保证 PO 的那个)。


🧩 一、Round-Robin:轮流拿最爱

最土的办法,也是最好用的。

  1. 随便定一个人的顺序 $i_1, i_2, \dots, i_n$
  2. 按顺序轮流叫号,轮到谁,谁就从剩下的物品里挑自己估值最高的一件
  3. 一圈叫完从头再来,直到物品分完

完整走一遍(顺序 1 → 2):

$g_1$ $g_2$ $g_3$ $g_4$ $g_5$
1 100 30 5 10 5
2 100 10 5 5 40
谁挑 挑走 之后 $A_1$ $A_2$
1 1 $g_1$(100 最高) $\{g_1\}$ $\varnothing$
1 2 $g_5$($g_1$ 没了,剩下最高是 40) $\{g_1\}$ $\{g_5\}$
2 1 $g_2$(30) $\{g_1,g_2\}$ $\{g_5\}$
2 2 $g_4$(5,与 $g_3$ 并列 —— ⭐ 这里我们取 $g_4$ $\{g_1,g_2\}$ $\{g_5,g_4\}$
3 1 $g_3$ $\{g_1,g_2,g_3\}$ $\{g_5,g_4\}$

验 EF1:1 号自己 $135$、对方那堆 $15$ → 连嫉妒都没有 ✓。2 号自己 $45$、对方那堆 $110$ → 嫉妒;去掉 $g_1$ 后剩 $15 \le 45$ ✓ EF1

⚠️ 并列怎么破,会改变最终数字 —— 但不改变结论。 第 2 轮 2 号在 $g_3$ 和 $g_4$ 之间并列(对他都是 5 分)。上面取了 $g_4$; 若改取 $g_3$,最后 1 号拿 $\{g_1,g_2,g_4\}$ = $100+30+10 = \mathbf{140}$、2 号仍是 $\mathbf{45}$。 ⭐ 两条分支都满足 EF1 —— 这正是定理的说法:Round-Robin 不管你怎么破并列,产出的一定是 EF1 分配。 💡 但要注意它们不是同一个分配,福利也不同(135+45 = 180 vs 140+45 = 185)。 「算法保证某个性质」和「算法有唯一输出」是两件事,这个区别在后面查 PO、比福利时会反复用到。

⭐ 为什么它一定 EF1(论证很短,值得看)

记 $g_t^i$ 是 $i$ 第 $t$ 次挑走的那件。核心观察只有一条:

$i$ 第 $t$ 次挑的时候,$j$ 第 $t$ 次要挑的东西还在桌上(如果 $i$ 排在 $j$ 前面)或已经被挑走(如果 $j$ 在前)。 于是对任意 $t < t'$ 都有 $v_i(g^i_t) \ge v_i(g^j_{t'})$ —— $i$ 自己第 $t$ 轮挑的,不会比 $j$ 更晚挑的那件差(不然 $i$ 当时就该挑那件)。

顺带的好处:每个人恰好拿到 $\lfloor m/n\rfloor$ 或 $\lceil m/n\rceil$ 件 —— 结果是均衡的。要求「每人恰好 $k$ 件」时只有它能用。运行时间 $O(mn)$(预排序后)。

⚠️ 但 Round-Robin 不保证 PO。 最小反例:两人两件,$v_1=(1,1)$、$v_2=(1,0)$。顺序 1→2 时 1 号先挑(并列取 $g_1$),2 号只能拿 $g_2$,效用是 $(1,0)$。可换成 1 拿 $g_2$、2 拿 $g_1$,效用是 $(1,1)$ —— 1 号一点没亏,2 号白赚,原分配被帕累托支配。


🧩 二、嫉妒图算法:给「没人眼红的人」发东西

Round-Robin 强制每人轮流拿一件。如果想更自由地一件一件发(比如物品陆续到货),得换个思路。

嫉妒图 $G_A$:点是人,从 $i$ 画一条边到 $j$ 当且仅当 $v_i(A_i) < v_i(A_j)$($i$ 眼红 $j$)。 分配是 EF ⟺ 嫉妒图一条边都没有。

现在一件一件发。发给谁是安全的?

⚠️ 但 source 可能不存在 —— 图里有的时候。两人的例子:$A_1=\{g_5\}$、$A_2=\{g_4\}$,用第一节那张表,$v_1(A_1)=5 < v_1(A_2)=10$(1 眼红 2),$v_2(A_2)=5 < v_2(A_1)=40$(2 眼红 1)—— 互相眼红,没有 source

破环的办法:沿着环轮换整堆物品。 环上每个人拿走他所眼红的那个人的整堆。

为什么轮换是安全的:物品一件没多、一件没少,每个人换到的是他本来就更眼馋的那堆,所以每个人的价值只增不减。价值只增不减 ⟹ 不会冒出新的嫉妒边 ⟹ 边数严格下降。所以破环不会无限进行。

算法

  1. 所有人从空手开始
  2. 只要还有没发的物品:找嫉妒图的一个 source,把任意一件物品发给他
  3. 发完检查是否成环,成环就沿环轮换整堆,重复到无环
  4. 回到第 2 步

完整走一遍(还是第一节那张 2 人表):

动作 $A_1$ $A_2$ 嫉妒图
1 都是 source,给 1 号 $g_5$ $\{g_5\}$ $\varnothing$ $v_2$: 自己 0 < 对方 40 → 2 → 1
2 source 是 2,给它 $g_4$ $\{g_5\}$ $\{g_4\}$ $v_1$: 5 < 10 → 1→2;$v_2$: 5 < 40 → 2→1,成环
3 沿环轮换两堆 $\{g_4\}$ $\{g_5\}$ $v_1$: 10 > 5 ✓;$v_2$: 40 > 5 ✓ 无边
4 都是 source,给 1 号 $g_3$ $\{g_4,g_3\}$ $\{g_5\}$ 无边
5 source 给 2 号 $g_2$ $\{g_4,g_3\}$ $\{g_5,g_2\}$ $v_1$: 15 < 35 → 1→2
6 source 是 1,给它 $g_1$ $\{g_4,g_3,g_1\}$ $\{g_5,g_2\}$ $v_2$: 50 < 110 → 2→1

发完了。最后检查 EF1:2 号眼红 1 号($110 > 50$),但去掉 $g_1$ 后只剩 $10 \le 50$ ✓ EF1

注意第 3 步:轮换之后 1 号从 5 涨到 10、2 号从 5 涨到 40,两条边同时消失 —— 这就是「破环只会让边变少」的实例。

性质


🧩 三、最大 Nash 福利:一个目标函数换来两个性质

前两个算法都只保证 EF1,都不保证 PO。这一个两样全有。

MNW(Maximum Nash Welfare):先最大化「拿到严格正效用的人数」,在这批人上最大化 $\prod_i v_i(A_i)$。 ⚠️ 前半句不能省 —— 有人拿 0 时乘积恒为 0,不先定人数的话所有这类分配都「并列最优」,没法区分好坏。

手算($n=2$,$m=4$):

$o_1$ $o_2$ $o_3$ $o_4$
1 6 2 3 1
2 4 1 2 3

枚举几个分配的乘积:

$X_1$ $X_2$ $v_1$ $v_2$ 乘积
$\{o_1,o_2\}$ $\{o_3,o_4\}$ 8 5 40
$\{o_1,o_3\}$ $\{o_2,o_4\}$ 9 4 36
$\{o_1\}$ $\{o_2,o_3,o_4\}$ 6 6 36
$\{o_1,o_2,o_3\}$ $\{o_4\}$ 11 3 33
$\{o_1,o_2,o_4\}$ $\{o_3\}$ 9 2 18

最大是 40。验一下:1 号自己 8、对方那堆 $3+1=4$ → 不嫉妒;2 号自己 5、对方那堆 $4+1=5$ → 不嫉妒。这个解甚至是完全 EF 的。

⚠️ 对照 USW:$X_1=\{o_1,o_2,o_3\}$、$X_2=\{o_4\}$ 的 USW 是 $11+3=14$,比 MNW 解的 $8+5=13$ 高,可 2 号只拿到 3。求和把差距拉大,乘积把差距压平。

⭐⭐ 定理(Caragiannis 等 2019):任何 MNW 分配都同时是 EF1 和 PO 的。

PO 部分一行:帕累托改进会让某人的值严格变大、其他人不变小 ⟹ 乘积严格变大 ⟹ 与「已经最大」矛盾。

EF1 部分的直觉(这才是漂亮的地方):假设 $i$ 眼红 $j$,而且去掉 $j$ 那堆里的任何一件都还眼红。那就从 $j$ 手里挑出这一件:

$$g^{*} = \arg\min_{g\in A_j,\ v_i(g)>0} \frac{v_j(g)}{v_i(g)}$$

也就是 「对 $j$ 最不值钱、对 $i$ 最值钱」的那一件。把 $g^*$ 从 $j$ 挪给 $i$:$i$ 的值涨的比例,比 $j$ 的值跌的比例更大 —— 于是乘积严格变大,和 MNW 矛盾。∎ ($i$ 「去掉任何一件仍眼红」这个假设,正好保证了那个比例算得过来。)

💀 代价:计算 MNW 是 NP 难的(连常数近似都很难)。实践中用整数规划求解 —— 真实上线的分配网站 spliddit.org 就是这么干的,遗产、房租、家务分摊都能算。


🧩 四、顺手把 MMS 也解决一半

上一章留了个尾巴:MMS 分配 $n\ge3$ 时可能不存在,怎么办?贪心版 Round-Robin 给出 $\frac12$-MMS:

  1. 记 $\beta_i = v_i(P)/|I|$($P$ 是剩余物品、$I$ 是剩余的人)
  2. 只要存在某个人 $i$ 和某件物品 $g$ 满足 $v_i(g) \ge \beta_i/2$:把 $g$ 单独给 $i$,把 $i$ 移出局,重算所有 $\beta$
  3. 剩下的人和物品跑普通 Round-Robin

两种人两种论证:第 2 步出局的人,一件就拿到了 $\beta_i/2 \ge \mathrm{MMS}_i/2$;留到第 3 步的人,桌上已经没有大件(每件都小于 $\beta_i/2$),而 Round-Robin 保证 EF1,EF1 减去一件小东西还剩一半 —— 同样 $\ge \mathrm{MMS}_i/2$。∎

关键的一步是上一章那条引理:$\frac{v_i(P)}{|I|} \ge \mathrm{MMS}_i(|I|,P) \ge \mathrm{MMS}_i(n,M)$ —— 人越少、物品越多,MMS 门槛只会更高不会更低,所以拿走一个人和一件物品之后的估算依然是安全下界。


🧩 五、三个算法怎么选

Round-Robin 嫉妒图 MNW
保证 EF1、PROP1、均衡 EF1、PROP1 EF1 + PO
复杂度 $O(mn)$ $O(mn^3)$ NP 难
估值要求 必须可加 只需单调 可加
什么时候用它 默认选它;要求每人 $k$ 件时只能用它 物品陆续到货、估值不可加 人少、要效率保证、能上求解器

⭐ 一句话决策:能接受「只保 EF1」就用 Round-Robin,非要 PO 就上 MNW 并做好算不动的准备。


🔗 这一章连到哪里

去哪 为什么
19-怎么算公平.md EF1 / PROP1 / MMS 的定义和「为什么必须放松」都在那儿。本章只负责把它们算出来
21-有钱与随机分配.md 嫉妒图在下一章会长出边权:权重变成「嫉妒了多少」,于是能算出「补多少钱才不嫉妒」
../模型上线之后/15-长期效应与代理指标.html USW 和 Nash 福利是两种截然不同的「总目标」。那边讲的正是「优化了一个加总指标却毁掉分布」这类事故

✅ 检查点

  1. Round-Robin 里,「$i$ 排在 $j$ 前面」这种情况得到的结论比 EF1 更强,强在哪?
  2. 情况 2 的证明为什么要专门划掉 $j$ 第一轮挑的那件?划第二轮的行不行?
  3. $v_1=(1,1)$、$v_2=(1,0)$ 这个反例说明了 Round-Robin 的什么缺陷?帕累托改进具体是怎么换的?
  4. 嫉妒图里为什么给 source 发东西是安全的,给被眼红的人发就不安全?
  5. 沿环轮换整堆之后,为什么保证不会冒出新的嫉妒边?
  6. 手算例子第 3 步轮换后两个人的值分别变成了多少?边数怎么变的?
  7. 嫉妒图算法比 Round-Robin 宽在哪、窄在哪?
  8. MNW 的定义为什么要先最大化「拿到正效用的人数」?
  9. MNW ⟹ EF1 的论证里,那个被挪走的 $g^*$ 是按什么标准挑的?为什么是这个标准?
  10. 贪心 Round-Robin 里第 2 步出局的人和第 3 步留下的人,分别靠什么论证拿到 $\frac12$-MMS?
👀 答案
  1. 强在它是完全 EF(不只是 EF1):$i$ 每一轮都先挑,所以 $v_i(g^i_t)\ge v_i(g^j_t)$ 逐轮成立,求和直接得 $v_i(A_i)\ge v_i(A_j)$。
  2. 因为 $j$ 第一轮挑的那件是唯一一件「$i$ 还没挑过任何东西就被拿走」的物品,没有 $i$ 的物品能与它配对。划掉它之后,$j$ 的第 $t$ 件正好能和 $i$ 的第 $t-1$ 件配对($v_i(g^i_{t-1})\ge v_i(g^j_t)$)。划第二轮的话第一轮那件配不上对,不等式链断掉。
  3. 说明 Round-Robin 不保证 PO。1 号先挑(两件并列,取 $g_1$),2 号只剩 $g_2$,效用 $(1,0)$;换成 1 拿 $g_2$、2 拿 $g_1$ 就是 $(1,1)$ —— 1 号一点不亏、2 号白赚,原分配被帕累托支配。
  4. source 是没有入边的点:谁都不眼红他。给他加一件之后,别人对他的嫉妒「去掉这一件」就回到了原来的无嫉妒状态,EF1 天然保住。给被眼红的人加东西则会把已有的嫉妒继续放大,可能一件都减不回来。
  5. 因为轮换只是交换整堆,物品没增没减,而环上每个人换到的正是他本来就更眼馋的那堆 —— 每个人的值只增不减。值只增不减就不可能产生新的嫉妒关系,所以边只会变少。
  6. 轮换前 $A_1=\{g_5\}$($v_1=5$)、$A_2=\{g_4\}$($v_2=5$)互相眼红共 2 条边;轮换后 $A_1=\{g_4\}$ 值 10、$A_2=\{g_5\}$ 值 40,两条边同时消失,剩 0 条。
  7. 在估值只需单调($v(S\cup\{g\})\ge v(S)$)而不必可加,且可以一件一件随到随发;在做不了均衡分配 —— 要求每人恰好 $k$ 件时,算法可能一直指着已经拿满的 source,卡死。复杂度也从 $O(mn)$ 涨到 $O(mn^3)$。
  8. 因为只要有一个人拿 0,乘积就是 0,所有这类分配会「并列最优」,目标函数分不出好坏。先把「有正效用的人数」拉满,才能保证不会为了省事让人颗粒无收。
  9. $g^*=\arg\min_{g\in A_j,\,v_i(g)>0} \frac{v_j(g)}{v_i(g)}$ —— 对 $j$ 最不值钱、对 $i$ 最值钱的那一件。挪走它时 $j$ 的相对损失最小、$i$ 的相对收益最大,于是乘积严格变大,与 MNW 最优矛盾。
  10. 第 2 步出局的人:他拿的那一件本身就 $\ge \beta_i/2 = \frac{v_i(P)}{2|I|} \ge \frac{\mathrm{MMS}_i}{2}$。第 3 步留下的人:此时桌上每一件都小于 $\beta_i/2$,而 Round-Robin 保证 EF1,把「少的那一件」减掉后仍有一半的量 —— 同样 $\ge \mathrm{MMS}_i/2$。两处都用到引理 $\frac{v_i(P)}{|I|}\ge \mathrm{MMS}_i(n,M)$。

🛑 可以停在这里

走神救援

上一章证明了 EF1 一定存在,这一章给算法。

Round-Robin:定个顺序轮流叫号,轮到谁谁就从剩下的挑自己估值最高的一件。手算的 2 人 5 物例子跑出 $A_1=\{g_1,g_2,g_3\}$(值 135)、$A_2=\{g_5,g_4\}$(值 45);2 号眼红对方的 110,但去掉 $g_1$ 只剩 15,EF1 ✓。它 EF1 的论证只有两句:$i$ 排在 $j$ 前面时逐轮都有 $v_i(g^i_t)\ge v_i(g^j_t)$,求和直接得到完全 EF;$j$ 排在前面时把 $j$ 第一轮那件划掉,剩下的逐个对应 $i$ 的前一轮,求和得 EF1。优点:$O(mn)$、结果均衡(每人 $\lfloor m/n\rfloor$ 或 $\lceil m/n\rceil$ 件),要求「每人恰好 $k$ 件」时只有它能用。⚠️ 缺点:不保证 PO,最小反例是 $v_1=(1,1)$、$v_2=(1,0)$ —— 换一下就能让 2 号白赚。

嫉妒图算法:点是人,$i\to j$ 表示 $i$ 眼红 $j$;EF ⟺ 图无边。一件一件发,只发给 source(没有入边的人),因为「去掉刚发的这一件就回到原状」,EF1 天然保住。没有 source 说明有,就沿环轮换整堆 —— 物品没变、每个人换到的是他本来更眼馋的那堆,值只增不减,所以边只会变少,破环必然终止。手算里第 3 步轮换后两人从 5、5 变成 10、40,两条边同时消失。复杂度 $O(mn^3)$;⭐ 它只要求估值单调、不必可加,但做不了均衡分配

⭐⭐ MNW(最大 Nash 福利):先最大化拿到正效用的人数,再最大化 $\prod_i v_i(A_i)$(前半句不能省,否则有人拿 0 时全部并列)。手算的 4 物例子里最优是 $X_1=\{o_1,o_2\}$、$X_2=\{o_3,o_4\}$,乘积 $8\times5=40$ —— 而 USW 更高的那个方案会把 2 号压到 3。定理(Caragiannis 等 2019):MNW ⟹ EF1 且 PO。 PO 一行(帕累托改进会让乘积变大);EF1 的关键是挑出 $g^*=\arg\min v_j(g)/v_i(g)$(对 $j$ 最不值钱、对 $i$ 最值钱的那件)挪给 $i$,乘积严格变大导出矛盾。💀 代价是计算 NP 难,实务上整数规划求解(spliddit.org 就是这么做的)。

最后顺手补上 MMS:贪心 Round-Robin 给 $\frac12$-MMS —— 先把「有一件就值 $\beta_i/2$ 以上」的人用一件物品打发走并重算 $\beta$,剩下的人跑普通 Round-Robin。两拨人分别靠「那一件够大」和「桌上已无大件 + EF1」拿到一半的 MMS。选型一句话:能接受只保 EF1 就用 Round-Robin,非要 PO 就上 MNW 并做好算不动的准备。

下一节 👉 21-有钱与随机分配.md

打卡记录保存在你的浏览器里,首页能看到总进度