这是第三个实验。第 16 讲,我们用手算和一小段代码,得到了景区门口两家烤肠摊的几个结果:比卖量(Cournot),各卖 300 根,价格 5 元;比价格(Bertrand),价格被一分钱一分钱地压到 2.01 元;产能一限,价格又回到 5 元。那一讲有一个没有说破的问题:摊主是怎么走到这些均衡的?
均衡只是说:“如果大家已经在那里,就没人想动。“它没有说:“不管从哪里出发,都到得了那里。“这个实验要做的,就是让摊主一轮一轮地调整,看他们走不走得到、走到哪里、走的方式有没有影响。你会发现,有的结果和你的直觉一致,有的不一致。
怎么用:和前两个实验一样,代码块是接着往下写的:后面的块会用到前面块里定义的东西。把它们依次拼成一个文件(比如 lab72.py),用 python lab72.py 运行;也可以一段一段地在 Python 里依次运行。只需要 Python 3 和 NumPy,全部运行约 6 秒。这个实验里没有随机数:每一步都是确定的,所以你跑出来的数字,会和下面的输出一模一样。
一、四个问题
先停一下:请先凭直觉,回答下面四个问题,写下来。
问题 1: 景区那条街上有十家烤肠摊。每天,每家摊主都看别人昨天卖了多少,然后把自己调整到"在这个条件下最好"的卖量。大家同时调整。时间长了,会走到 Cournot 均衡(每家 81.8 根)吗?
问题 2: 十家摊里,有两家合并成一家(成本不变)。合并后的这一家,利润会比合并前两家的利润之和更高吗?价格会涨吗?
问题 3: 两家烤肠摊比价格,轮流降价抢客。价格牌上最小只能写到"一分钱”,和最小只能写到"一块钱”,价格战的结局一样吗?
问题 4: 两家烤肠摊都把每天的产能扩到 500 根(第 16 讲的 Cournot 均衡是 300 根)。价格会稳定在 5 元吗?
我们会一个一个回来。
二、实验的设计
2.1 市场和摊主
市场和第 16 讲完全一样:游客的需求是 P = 11 − 0.01 Q(Q 是每天卖出的根数),每根成本 2 元,没有固定成本。
摊主是什么样的人?我们有意把他们设计得很"笨”:每一轮,他们看到别人现在卖多少(或者标什么价),就按第 16 讲 3.1 节的办法,算出"在这个条件下我最好的做法”,然后照做。他们不会想"如果我这样,对方会怎样反应",不会记仇,也不会考虑将来。这在经济学里叫最佳反应调整(best-reply dynamics)。
为什么要这么笨?因为实验 70 已经给了我们一个启发:一群没有多少智力的交易者,也能把一个市场带到均衡。那么,一群"只会对眼前做最好反应"的摊主,能不能把寡头市场带到均衡?答案要看他们调整的节奏,这就是这个实验的第一个主角。
2.2 三种节奏
- 同时调整:每一轮,所有摊主一起看上一轮别人的卖量,一起调整。
- 轮流调整:摊主一个接一个地调整,后面的人看到的,是前面的人刚刚调整完的卖量。(第 16 讲里,“甲按乙调整,再乙按甲调整”,就是轮流。)
- 带惯性的调整:每一轮只往"最佳卖量"的方向走一部分(比例是 λ,0 < λ ≤ 1);λ = 1 就是没有惯性。
2.3 价格竞争的设定
比价格时,两家的产品一模一样,游客只买便宜的那家,价格一样就各买一半。价格只能是某个"最小单位"(step)的整数倍:1 分钱、5 分钱,或者 1 块钱。两家轮流调整价格,每次都是对对方当前价格的最佳反应。产能有限时,便宜的那家先卖,卖完了,顾客才去另一家,而且先被便宜的那家拿走的,是愿付价最高的顾客(和第 16 讲 4.3 节一样,这叫"有效率的配给")。
三、第一步:把第 16 讲的数字算一遍
import numpy as np
# 景区门口的烤肠摊(和第 16 讲一样):游客的需求 P = 11 - 0.01 Q,每根成本 2 元,没有固定成本
A, B, MC = 11.0, 0.01, 2.0
def price(total):
return max(A - B * total, 0.0)
def profit(q, others, c=MC):
"""我卖 q 根、别的摊一共卖 others 根时,我的利润"""
return (price(q + others) - c) * q
def best_reply(others, c=MC):
"""令边际收益 = 边际成本,得到最佳卖量的公式;卖量不能是负的"""
return max((A - c - B * others) / (2 * B), 0.0)
# 核对 1:公式,和"把 0 到 900 的卖量全试一遍",答案一样吗?
grid = np.arange(0, 900.01, 0.5)
for others in (0, 150, 300, 450):
brute = grid[np.argmax([profit(q, others) for q in grid])]
print(f"别的摊卖 {others:>3} 根:公式 {best_reply(others):6.1f},全部试一遍 {brute:6.1f}")
# 核对 2:N 家一样的摊,均衡里每家卖 (A - c) / (B (N + 1))
print("\n N 每家卖 价格 每家利润")
for n in (1, 2, 3, 5, 10):
q = (A - MC) / (B * (n + 1))
print(f"{n:>3} {q:>8.1f} {price(n * q):>7.2f} {profit(q, (n - 1) * q):>10.2f}")
# 核对 3:两家轮流调整(第 16 讲那一行输出)。每一轮:甲按乙调整,然后乙按甲调整
q1, q2 = 100.0, 500.0
path = [(q1, q2)]
for _ in range(5):
q1 = best_reply(q2); q2 = best_reply(q1); path.append((q1, q2))
print("\n轮流调整:" + " -> ".join(f"({a:.0f}, {b:.0f})" for a, b in path))
输出:
别的摊卖 0 根:公式 450.0,全部试一遍 450.0
别的摊卖 150 根:公式 375.0,全部试一遍 375.0
别的摊卖 300 根:公式 300.0,全部试一遍 300.0
别的摊卖 450 根:公式 225.0,全部试一遍 225.0
N 每家卖 价格 每家利润
1 450.0 6.50 2025.00
2 300.0 5.00 900.00
3 225.0 4.25 506.25
5 150.0 3.50 225.00
10 81.8 2.82 66.94
轮流调整:(100, 500) -> (200, 350) -> (275, 312) -> (294, 303) -> (298, 301) -> (300, 300)
逐段看:
- 公式和"全部试一遍"一致:别人卖 0、150、300、450 根时,我的最佳卖量是 450、375、300、225,和第 16 讲一样。
- N 家一样的摊,均衡里每家卖 450 ÷ (N + 1):N = 2 是 300 根、价格 5 元;N = 3、5、10 的价格是 4.25、3.5、2.82,和第 16 讲 3.3 节的表一致。
- 轮流调整:从 (100, 500) 出发,一路走到 (300, 300),和第 16 讲那一行输出一样。
- 同时调整:路径不一样,(100, 500) → (200, 400) → (250, 350) → ……,但也走到了 (300, 300)。两家的时候,两种节奏都行。
四、第二步:N 家摊同时调整
第 16 讲只看了两家。现在,让摊数增加,每家从均衡附近出发(甲比均衡多卖 20 根,其他家刚好在均衡上),同时调整:
def iterate(q0, rounds, mode="simul", lam=1.0, costs=None):
"""N 家摊反复调整卖量。
mode="simul":大家同时看上一轮对方的卖量,一起调整(lam < 1 表示只调整一部分,叫"惯性")
mode="alt" :轮流来,每家调整时,看到的是别人最新的卖量
返回一个数组:第 r 行是第 r 轮之后每家的卖量"""
q = np.array(q0, dtype=float); n = len(q)
costs = np.full(n, MC) if costs is None else np.asarray(costs, dtype=float)
hist = [q.copy()]
for _ in range(rounds):
if mode == "simul":
new = np.array([best_reply(q.sum() - q[i], costs[i]) for i in range(n)])
q = (1 - lam) * q + lam * new
else:
for i in range(n):
q[i] = (1 - lam) * q[i] + lam * best_reply(q.sum() - q[i], costs[i])
hist.append(q.copy())
return np.array(hist)
# 先看两家:同时调整,和轮流调整,都能走到 (300, 300) 吗?
for mode in ("simul", "alt"):
h = iterate([100, 500], 12, mode)
print(f"{mode:>5}:" + " -> ".join(f"({a:.0f},{b:.0f})" for a, b in h[[0, 1, 2, 3, 6, 12]]))
# 再看 N 家,从均衡附近出发(每家比均衡多卖 20 根),同时调整 8 轮
print("\n同时调整,每家的卖量(均衡值 = 450 / (N + 1)):")
for n in (2, 3, 4, 5):
star = (A - MC) / (B * (n + 1))
start = np.full(n, star); start[0] += 20
h = iterate(start, 8, "simul")
print(f"N = {n}(均衡 {star:6.1f}):甲的卖量 " + " ".join(f"{x:6.1f}" for x in h[:9, 0]))
# N = 5 时,市场上整体发生了什么?看总卖量和价格
n = 5; star = (A - MC) / (B * (n + 1))
start = np.full(n, star); start[0] += 20
h = iterate(start, 12, "simul")
print("\nN = 5:总卖量和价格(均衡:总卖量 750,价格 3.50)")
for r in range(0, 13, 2):
print(f" 第 {r:>2} 轮:总卖量 {h[r].sum():7.1f},价格 {price(h[r].sum()):.2f},各家卖量 {np.round(h[r], 0)}")
输出:
simul:(100,500) -> (200,400) -> (250,350) -> (275,325) -> (297,303) -> (300,300)
alt:(100,500) -> (200,350) -> (275,312) -> (294,303) -> (300,300) -> (300,300)
同时调整,每家的卖量(均衡值 = 450 / (N + 1)):
N = 2(均衡 300.0):甲的卖量 320.0 300.0 305.0 300.0 301.2 300.0 300.3 300.0 300.1
N = 3(均衡 225.0):甲的卖量 245.0 225.0 235.0 220.0 232.5 218.7 231.9 218.4 231.7
N = 4(均衡 180.0):甲的卖量 200.0 180.0 195.0 165.0 206.3 142.5 237.2 94.7 308.2
N = 5(均衡 150.0):甲的卖量 170.0 150.0 170.0 120.0 215.0 22.5 406.3 0.0 450.0
N = 5:总卖量和价格(均衡:总卖量 750,价格 3.50)
第 0 轮:总卖量 770.0,价格 3.30,各家卖量 [170. 150. 150. 150. 150.]
第 2 轮:总卖量 830.0,价格 2.70,各家卖量 [170. 165. 165. 165. 165.]
第 4 轮:总卖量 1070.0,价格 0.30,各家卖量 [215. 214. 214. 214. 214.]
第 6 轮:总卖量 2030.0,价格 0.00,各家卖量 [406. 406. 406. 406. 406.]
第 8 轮:总卖量 2250.0,价格 0.00,各家卖量 [450. 450. 450. 450. 450.]
第 10 轮:总卖量 2250.0,价格 0.00,各家卖量 [450. 450. 450. 450. 450.]
第 12 轮:总卖量 2250.0,价格 0.00,各家卖量 [450. 450. 450. 450. 450.]
这和你的直觉一样吗?看每一行:
- N = 2:甲的卖量 320 → 300 → 305 → 300 → 301.2 → ……,来回摆动,幅度一次比一次小,走到 300。
- N = 3:245 → 225 → 235 → 220 → 232.5 → 218.7 → 231.9 → 218.4 → 231.7。摆动的幅度不再缩小,也不放大,永远在 218 和 232 附近来回。
- N = 4:200 → 180 → 195 → 165 → 206 → 142 → 237 → 95 → 308。摆动越来越大。
- N = 5:摆到后来,有的轮次,每家摊都卖 450 根(总卖量 2250,游客根本吃不下,价格是 0),下一轮,所有人看到价格是 0,都不卖了……最后,每家的卖量,在 0 和 450 之间来回跳。
均衡是存在的(N = 4 时每家 180,N = 5 时每家 150),可是这群"笨"摊主,同时调整,走不到它。问题 1 的答案:不会。十家摊同时调整,卖量会剧烈摆动,直到撞上"卖量不能是负的"这堵墙。
五、第三步:为什么?怎么救?
5.1 为什么
看均衡附近。别人的总卖量每多 1 根,我的最佳卖量少 0.5 根(最佳反应的斜率是 −0.5,见第 16 讲 3.1 节)。如果所有其他 N − 1 家都多卖了 1 根,我的最佳卖量就少 (N − 1) ÷ 2 根。而大家又都这样反应,所以,一轮之后,偏差大致被乘以 −(N − 1) ÷ 2:负号表示"反向",绝对值表示"放大还是缩小"。
- N = 2:乘以 −0.5,偏差缩小一半,反向,再缩小……,收敛。
- N = 3:乘以 −1,大小不变,反向,永远摆动。
- N ≥ 4:绝对值大于 1,越摆越大。
这就是 Theocharis(1960 年,Review of Economic Studies,27 卷 2 期,133–134 页;也有文献把年份标为 1959)发现的结果:需求是直线、成本不变时,Cournot 均衡在同时调整下,企业多于三家就不稳定。(这是一篇很短的文章;我只核对了它的出处,没有逐行读它的推导,所以这里的解释是我们自己用代码验证的。)
我们让代码把"乘数"算出来,并试两个药方:
# 为什么:均衡附近,"同时调整"每一轮把偏差乘以一个数。这个数,就是调整的"雅可比矩阵"的特征值
def one_round_matrix(n, mode):
"""在均衡附近,一轮调整把「偏差」变成多少:一个 n × n 的矩阵(对均衡处的微小偏差做一轮,逐列读出来)"""
star = np.full(n, (A - MC) / (B * (n + 1))); G = np.zeros((n, n))
for j in range(n):
start = star.copy(); start[j] += 1e-3
G[:, j] = (iterate(start, 1, mode)[1] - star) / 1e-3
return G
print("一轮调整之后,偏差被放大(>1)还是缩小(<1)?最大特征值的绝对值:")
print(" N 同时调整 轮流调整")
for n in (2, 3, 4, 5, 10, 20):
rho = lambda mode: np.abs(np.linalg.eigvals(one_round_matrix(n, mode))).max()
print(f"{n:>3} {rho('simul'):>11.3f} {rho('alt'):>10.3f} (同时调整:(N - 1) / 2 = {(n - 1) / 2:.1f})")
# 药方一:加"惯性",每一轮只调整一部分 lam。用二分法找:最大的、还能收敛的 lam
def converges(n, lam, rounds=4000):
star = (A - MC) / (B * (n + 1))
start = np.full(n, star); start[0] += 20
h = iterate(start, rounds, "simul", lam)
return abs(h[-1] - star).max() < 1e-6
print("\n药方一:惯性。最大的可收敛调整比例 lam(对照公式 4 / (N + 1)):")
for n in (4, 5, 10, 20):
lo, hi = 0.0, 1.0
for _ in range(25):
mid = (lo + hi) / 2
if converges(n, mid): lo = mid
else: hi = mid
print(f"N = {n:>2}:{lo:.4f}(公式 {4 / (n + 1):.4f})")
# 药方二:轮流调整。N = 10,每家从 100 根出发,看离均衡(81.8)最远的那家差多少
n = 10; star = (A - MC) / (B * (n + 1))
h = iterate(np.full(n, 100.0), 60, "alt")
print("\n药方二:轮流调整,N = 10,离均衡最远的那家差多少:")
print(" 第 0、1、2、5、10、20、40 轮:" + "、".join(f"{abs(h[r] - star).max():.2f}" for r in (0, 1, 2, 5, 10, 20, 40)))
print("轮流调整,要几轮才能让每家离均衡都不超过 0.5 根:")
for n in (2, 5, 10, 20, 40):
star = (A - MC) / (B * (n + 1)); h = iterate(np.full(n, 100.0), 4000, "alt")
r = int(np.argmax(abs(h - star).max(axis=1) < 0.5))
print(f" N = {n:>2}:{r} 轮")
输出:
一轮调整之后,偏差被放大(>1)还是缩小(<1)?最大特征值的绝对值:
N 同时调整 轮流调整
2 0.500 0.250 (同时调整:(N - 1) / 2 = 0.5)
3 1.000 0.354 (同时调整:(N - 1) / 2 = 1.0)
4 1.500 0.458 (同时调整:(N - 1) / 2 = 1.5)
5 2.000 0.544 (同时调整:(N - 1) / 2 = 2.0)
10 4.500 0.784 (同时调整:(N - 1) / 2 = 4.5)
20 9.500 0.924 (同时调整:(N - 1) / 2 = 9.5)
药方一:惯性。最大的可收敛调整比例 lam(对照公式 4 / (N + 1)):
N = 4:0.7985(公式 0.8000)
N = 5:0.6654(公式 0.6667)
N = 10:0.3630(公式 0.3636)
N = 20:0.1901(公式 0.1905)
药方二:轮流调整,N = 10,离均衡最远的那家差多少:
第 0、1、2、5、10、20、40 轮:18.18、81.82、31.92、10.02、3.19、0.28、0.00
轮流调整,要几轮才能让每家离均衡都不超过 0.5 根:
N = 2:5 轮
N = 5:9 轮
N = 10:18 轮
N = 20:62 轮
N = 40:198 轮
逐段看:
- 放大倍数:同时调整,N = 2、3、4、5、10、20,最大特征值的绝对值是 0.5、1.0、1.5、2.0、4.5、9.5,恰好是 (N − 1) ÷ 2。轮流调整,每一个都小于 1:0.25、0.35、0.46、0.54、0.78、0.92,所以一定收敛。(对任何 N 都小于 1,是有数学定理保证的:这个迭代,等价于用 Gauss–Seidel 方法解一个对称正定的线性方程组。这里我们只验证到 N = 20。)
- 药方一:惯性。如果每一轮只调整一部分(比例 λ),能收敛的最大 λ 是 4 ÷ (N + 1):N = 4 是 0.8、N = 10 是 0.364、N = 20 是 0.19。企业越多,每个摊主越要"慢"。
- 药方二:轮流调整。N = 10 时,轮流调整,二十来轮之内,每家都走到了 81.8 附近(20 轮时最远的一家只差 0.28 根)。代价是慢:N = 2 要 5 轮,N = 10 要 18 轮,N = 40 要 198 轮。企业越多,越慢,但一定到。
5.2 这说明了什么
到得了均衡,不只取决于均衡本身,还取决于"怎么走"。 同一个市场、同一群笨摊主,同时调整走不到,轮流调整走得到。这对现实的含义是:当一个市场里的企业很多、而且对彼此的行动反应得又快又过头(比如,价格每天按对手昨天的价格重新定),稳定的均衡也可能表现为剧烈的波动。
这不是说现实里的摊主真的这么调整。它说的是:“均衡存在"和"均衡会被走到"是两个不同的命题。第 18 讲 5.2 节,让两个人"对对方到目前为止的出手频率做最佳应对”,在点球博弈里,频率走到了均衡;那是零和博弈,收敛有保证。这个实验里的寡头市场不是零和博弈,摊主又只盯着上一轮,结果就不同了:用最佳反应的"互相适应"去找均衡,并不是在所有博弈里都找得到。
六、第四步:成本不同;两家合并
6.1 成本不同
现实里的摊主,成本不会一模一样。设三家摊的成本是 1.5、2.0、2.5(甲有便宜的货源)。成本不同时,Cournot 均衡的公式是 q_i = (A − (N + 1)c_i + 所有人的成本之和) ÷ (B (N + 1));如果某家算出来是负的,说明它根本进不了市场,把它去掉,再算一遍。
6.2 合并
第 16 讲 7 节讲了合并:企业合并,少了一个对手,价格会不会涨?Cournot 模型给出了一个出人意料的答案。
def cournot(costs):
"""成本各不相同的 Cournot 均衡。公式:q_i = (A - (n+1) c_i + 所有人的成本之和) / (B (n+1));
如果某家算出来是负的,它就不卖了,把它去掉再算一遍。"""
costs = np.asarray(costs, dtype=float)
active = np.ones(len(costs), dtype=bool)
while True:
n = active.sum()
q = np.where(active, (A - (n + 1) * costs + costs[active].sum()) / (B * (n + 1)), 0.0)
if (q >= 0).all(): break
active[np.argmax(np.where(q < 0, costs, -1))] = False # 去掉成本最高的、卖量为负的那家
p = price(q.sum())
return q, p, (p - costs) * q
# 三家摊:甲成本 1.5(自家有便宜的货源),乙 2.0,丙 2.5
costs = [1.5, 2.0, 2.5]
q, p, pi = cournot(costs)
h = iterate(np.full(3, 100.0), 300, "alt", costs=costs)
print("三家摊,成本 1.5 / 2.0 / 2.5")
print(f" 公式:卖量 {np.round(q, 1)},价格 {p:.3f},利润 {np.round(pi, 1)}")
print(f" 轮流调整 300 轮:卖量 {np.round(h[-1], 1)}(和公式一致)")
share = q / q.sum()
hhi = (share ** 2).sum()
elasticity = (1 / B) * p / q.sum()
lerner = (share * (p - np.array(costs)) / p).sum()
print(f" 份额 {np.round(share, 3)},HHI = {hhi:.4f},市场弹性 = {elasticity:.3f}")
print(f" 按份额加权的加价率 = {lerner:.4f};HHI ÷ 弹性 = {hhi / elasticity:.4f}(相等)")
# 成本差距太大时,贵的那家就退出了
print("\n丙的成本一路涨:")
for c3 in (2.5, 4.0, 6.0, 8.0):
q, p, pi = cournot([1.5, 2.0, c3])
print(f" 丙成本 {c3:.1f}:卖量 {np.round(q, 1)},价格 {p:.3f}" + ("(丙退出)" if q[2] == 0 else ""))
# 合并:十家一样的摊,其中 k 家合并成一家。合并后只是"少了 k - 1 个对手",成本不变
print("\n十家一样的摊(每家成本 2)。k 家合并后,合并的这家摊,利润够不够补回合并前各自的利润之和?")
n = 10
pi_each = cournot([MC] * n)[2][0]
print(f" 合并前每家利润 {pi_each:.2f},价格 {cournot([MC] * n)[1]:.3f}")
for k in range(2, 11):
q, p, pi = cournot([MC] * (n - k + 1))
gain = pi[0] - k * pi_each
print(f" k = {k:>2} 家合并:合并后价格 {p:.3f},合并的这家利润 {pi[0]:7.2f},合并前这 k 家的利润之和 {k * pi_each:7.2f},差 {gain:+7.2f}")
# 如果合并能让成本下降(效率),降多少才够?二分法找:k = 2 的合并,合并后成本 c,使得合并这家的利润 = 2 × 合并前
def merged_profit(k, c_new):
q, p, pi = cournot([c_new] + [MC] * (n - k)); return pi[0], p
print("\n两家合并,合并后成本降到多少,这次合并才有赚头?")
lo, hi = 0.0, MC
for _ in range(40):
mid = (lo + hi) / 2
if merged_profit(2, mid)[0] >= 2 * pi_each: lo = mid
else: hi = mid
c_need = hi; pi_m, p_m = merged_profit(2, c_need)
print(f" 成本要从 2.00 降到 {c_need:.3f}(降 {100 * (MC - c_need) / MC:.1f}%);这时价格 {p_m:.3f},合并前是 {cournot([MC] * n)[1]:.3f}")
# 再问一个更严的问题:成本要降多少,才能让这次合并之后,价格不比合并前高?
lo, hi = 0.0, MC
for _ in range(40):
mid = (lo + hi) / 2
if merged_profit(2, mid)[1] <= cournot([MC] * n)[1]: lo = mid
else: hi = mid
print(f"想让价格不涨,成本要降到 {lo:.3f}(降 {100 * (MC - lo) / MC:.1f}%),比「合并有赚头」要求的 {100 * (MC - c_need) / MC:.1f}% 多得多")
输出:
三家摊,成本 1.5 / 2.0 / 2.5
公式:卖量 [275. 225. 175.],价格 4.250,利润 [756.2 506.2 306.2]
轮流调整 300 轮:卖量 [275. 225. 175.](和公式一致)
份额 [0.407 0.333 0.259],HHI = 0.3443,市场弹性 = 0.630
按份额加权的加价率 = 0.5468;HHI ÷ 弹性 = 0.5468(相等)
丙的成本一路涨:
丙成本 2.5:卖量 [275. 225. 175.],价格 4.250
丙成本 4.0:卖量 [312.5 262.5 62.5],价格 4.625
丙成本 6.0:卖量 [333.3 283.3 0. ],价格 4.833(丙退出)
丙成本 8.0:卖量 [333.3 283.3 0. ],价格 4.833(丙退出)
十家一样的摊(每家成本 2)。k 家合并后,合并的这家摊,利润够不够补回合并前各自的利润之和?
合并前每家利润 66.94,价格 2.818
k = 2 家合并:合并后价格 2.900,合并的这家利润 81.00,合并前这 k 家的利润之和 133.88,差 -52.88
k = 3 家合并:合并后价格 3.000,合并的这家利润 100.00,合并前这 k 家的利润之和 200.83,差 -100.83
k = 4 家合并:合并后价格 3.125,合并的这家利润 126.56,合并前这 k 家的利润之和 267.77,差 -141.21
k = 5 家合并:合并后价格 3.286,合并的这家利润 165.31,合并前这 k 家的利润之和 334.71,差 -169.40
k = 6 家合并:合并后价格 3.500,合并的这家利润 225.00,合并前这 k 家的利润之和 401.65,差 -176.65
k = 7 家合并:合并后价格 3.800,合并的这家利润 324.00,合并前这 k 家的利润之和 468.60,差 -144.60
k = 8 家合并:合并后价格 4.250,合并的这家利润 506.25,合并前这 k 家的利润之和 535.54,差 -29.29
k = 9 家合并:合并后价格 5.000,合并的这家利润 900.00,合并前这 k 家的利润之和 602.48,差 +297.52
k = 10 家合并:合并后价格 6.500,合并的这家利润 2025.00,合并前这 k 家的利润之和 669.42,差 +1355.58
两家合并,合并后成本降到多少,这次合并才有赚头?
成本要从 2.00 降到 1.714(降 14.3%);这时价格 2.871,合并前是 2.818
想让价格不涨,成本要降到 1.182(降 40.9%),比「合并有赚头」要求的 14.3% 多得多
逐段看:
- 成本不同:三家摊(1.5 / 2.0 / 2.5)分别卖 275、225、175 根,成本低的卖得多、赚得多(利润 756、506、306)。份额按成本分,不平均。
- 第 16 讲的"HHI ÷ 弹性",对成本不同的企业依然成立:按份额加权的加价率是 0.5468,HHI ÷ 市场弹性也是 0.5468。(原因在于,每家企业的最优条件是 (价格 − 成本) ÷ 价格 = 份额 ÷ 弹性;把它们按份额加权加起来,就是这条等式。)
- 成本太高就退出:丙的成本涨到 4.0 时,只卖 62.5 根;涨到 6.0,丙不卖了,市场剩两家,价格 4.83。
- 合并(十家一样的摊):
- 合并两家:合并后价格从 2.818 涨到 2.900,但是合并的这一家,只赚 81.00,合并前这两家加起来赚 133.88。亏了 52.88。
- 合并 3、4、5、6、7、8 家:都是亏的。
- 要合并 9 家(90%)才开始赚钱;合并 8 家(80%)还是亏 29.29。
- 全部 10 家合并,等于垄断,赚 2025,比合并前 669 多得多。
- 为什么会亏:合并的这家,减产了,价格上涨;可是剩下没合并的八家摊,看到价格涨了,都增产了,它们搭了"便车":享受涨价,却不付减产的代价。合并的这家,丢了份额,利润反而比合并前的总和少。这个现象,是 Salant、Switzer 和 Reynolds 在 1983 年(Quarterly Journal of Economics,98 卷 2 期,185–199 页)发现的。在这个线性需求的例子里,门槛约是 80%(练习 4 会让你验证 N = 5 时,4 家合并刚好打平)。
- 合并要有成本节约才有利:两家合并,成本要从 2.00 降到 1.714(降 14.3%),这次合并才不亏。可是,这时价格依然比合并前高(2.871 对 2.818);要让价格不涨,成本得降到 1.182,降 40.9%。
问题 2 的答案:合并的这一家,利润比合并前两家的和低;价格会涨。
最后这一条,对应 Farrell 和 Shapiro 1990 年(American Economic Review,80 卷 1 期,107–126 页)的结论:在 Cournot 模型里,没有成本节约(协同效应)的合并,一定涨价;只有协同效应足够大,价格才可能下降。我们的数字,是这个结论的一个具体例子(线性需求、十家一样的摊、两家合并)。
这不是说,现实里的合并都是坏事,也不是说,企业的合并都是亏本买卖。 它说的是:在"同质产品、数量竞争"这个具体模型里,不涉及成本节约的合并,对合并企业自己可能是亏的,对消费者一定是涨价的。如果换成"价格竞争、产品有差异"的模型,合并更容易有利可图(这是文献里常见的对照;本实验没有计算,这门课也没有专门展开产品差异)。所以,监管者审合并,要问的是具体问题:产品是不是同质的?企业比的是什么?合并能省多少成本?这是第 16 讲 7.2 节和 Williamson(1968)“成本节约对涨价"的权衡。
七、第五步:价格战
现在比价格。每家摊轮流定价,每次都是对对方当前价格的最佳反应。如果有好几个价格一样好,选最接近自己成本的那个(赚不了钱,就别乱降价)。
demand = lambda p: np.maximum(1100.0 - 100.0 * p, 0.0) # 把 P = 11 - 0.01 Q 反过来写:Q = 1100 - 100 P
def bertrand_br(p_rival, c, step):
"""产品一模一样、产能不限。我的价格只能是 step 的整数倍。在这些价格里,选利润最大的;
如果有好几个一样好,选最接近我自己成本的那个(没有赚头,就别乱降价)。"""
prices = np.arange(0.0, 11.0 + step / 2, step)
d = demand(prices)
sold = np.where(prices < p_rival - 1e-9, d, np.where(prices > p_rival + 1e-9, 0.0, d / 2)) # 便宜的全拿,一样平分
pi = (prices - c) * sold
best = np.flatnonzero(pi >= pi.max() - 1e-9)
return prices[best[np.argmin(abs(prices[best] - c))]]
def price_war(p1, p2, c1=2.0, c2=2.0, step=0.01, max_moves=5000):
"""两家轮流定价(甲先),每次都是对对方当前价格的最佳反应,直到谁也不想动"""
path = [(p1, p2)]; still = 0
for t in range(max_moves):
if t % 2 == 0: new = bertrand_br(p2, c1, step); changed = abs(new - p1) > 1e-9; p1 = new
else: new = bertrand_br(p1, c2, step); changed = abs(new - p2) > 1e-9; p2 = new
path.append((p1, p2)); still = 0 if changed else still + 1
if still == 2: break
return np.array(path)
# 从垄断价 6.5 出发,成本一样
w = price_war(6.5, 6.5)
print(f"一分钱一档:从 (6.50, 6.50) 出发,共调整 {int((abs(np.diff(w, axis=0)).sum(axis=1) > 1e-9).sum())} 次,停在 ({w[-1][0]:.2f}, {w[-1][1]:.2f});每家利润 {(w[-1][0] - MC) * demand(w[-1][0]) / 2:.2f}")
print("前几步:" + " -> ".join(f"({a:.2f},{b:.2f})" for a, b in w[:6]))
# 价格能报到多细,会不会改变结局?
print("\n价格的最小单位 step 不同:")
for step in (0.01, 0.05, 0.25, 1.00):
w = price_war(6.5, 6.5, step=step)
print(f" step = {step:>4.2f}:停在 ({w[-1][0]:.2f}, {w[-1][1]:.2f}),每家利润 {(w[-1][0] - MC) * demand(w[-1][0]) / 2:7.2f}")
# 成本不一样:甲 2 元,乙 3 元(第 16 讲思考题 3)
w = price_war(6.5, 6.5, c1=2.0, c2=3.0)
d = demand(w[-1][0])
print(f"\n成本 2 vs 3:停在 ({w[-1][0]:.2f}, {w[-1][1]:.2f});甲独占,卖 {d:.0f} 根,利润 {(w[-1][0] - 2.0) * d:.2f};乙利润 0")
输出:
一分钱一档:从 (6.50, 6.50) 出发,共调整 450 次,停在 (2.01, 2.01);每家利润 4.50
前几步:(6.50,6.50) -> (6.49,6.50) -> (6.49,6.48) -> (6.47,6.48) -> (6.47,6.46) -> (6.45,6.46)
价格的最小单位 step 不同:
step = 0.01:停在 (2.01, 2.01),每家利润 4.50
step = 0.05:停在 (2.05, 2.05),每家利润 22.38
step = 0.25:停在 (2.25, 2.25),每家利润 109.38
step = 1.00:停在 (3.00, 3.00),每家利润 400.00
成本 2 vs 3:停在 (2.99, 3.00);甲独占,卖 801 根,利润 792.99;乙利润 0
逐段看:
- 成本一样:从垄断价 6.50 出发,两家轮流降价,一分钱一分钱地降,共调整 450 次,停在 2.01,每家利润 4.50。和第 16 讲 4.1 节的 299 次(从 5.00 出发)是同一条路,只是起点不同。
- 价格最小单位:最小单位 1 分钱,停在 2.01;5 分钱,停在 2.05;2 毛 5,停在 2.25;1 块钱,停在 3.00,每家还赚 400。规律是:价格停在"成本 + 一格”,因为到了那里,再降一格,价格就等于成本,利润是零,不如不降。(价格正好等于成本的 (2.00, 2.00),也是一个均衡:谁也不赚钱,但谁也没有理由动。我们的摊主,是从高价一路降下来的,会停在它上面一格。)
- 成本不一样(甲 2 元,乙 3 元):战争在 2.99 / 3.00 停下来。乙降不下去(降到 3 以下它就亏了),甲只要比 3 低一分钱,就能抢走所有游客:卖 801 根,利润 792.99;乙的利润是 0。这是第 16 讲思考题 3 的答案。
问题 3 的答案:不一样。Bertrand 悖论"价格被压到成本",在价格有最小单位时,变成"压到成本加一格"。如果最小单位是一块钱,价格战的结局,是 3 元,每家 400。这说明,Bertrand 悖论的"极端",有一部分来自价格可以无限细分的假设。 现实的价格总有最小单位,而且游客对 1 分钱的差别,往往没有那么敏感。
八、第六步:产能中等,价格不稳定
第 16 讲 4.3 节说:每家产能 300 根时,(5, 5) 是均衡。那么,产能如果是别的数呢?先看,对不同的产能 k,网格上有没有"谁也不想单独改价"的价格组合;再看没有的时候,价格怎么走。
# 产能有限(每家最多 k 根)。便宜的先卖,卖完了顾客才去另一家;愿付价最高的顾客,先被便宜的那家拿走
def sales(p_me, p_rival, k_me, k_rival):
d_me, d_rival = demand(p_me), demand(p_rival)
cheaper = np.minimum(k_me, d_me) # 我更便宜:顾客都来,但我最多卖 k_me
dearer = np.minimum(k_me, np.maximum(d_me - np.minimum(k_rival, d_rival), 0.0)) # 我更贵:对方先卖,剩下的才是我的
same = np.minimum(k_me, np.maximum(d_me / 2, d_me - k_rival)) # 一样价:平分,对方卖不完的归我
return np.where(p_me < p_rival - 1e-9, cheaper, np.where(p_me > p_rival + 1e-9, dearer, same))
def capacity_br(p_rival, k_me, k_rival, step):
prices = np.arange(0.0, 11.0 + step / 2, step)
pi = (prices - MC) * sales(prices, p_rival, k_me, k_rival)
best = np.flatnonzero(pi >= pi.max() - 1e-9)
return prices[best[-1]] # 一样好的,选最高的价格
def pure_equilibria(k, step=0.05):
"""网格上所有「谁也不想单独改价」的价格组合(两家产能一样,所以只要查一家的利润)"""
prices = np.arange(MC, 11.0 + step / 2, step)
best_vs = np.array([((prices - MC) * sales(prices, r, k, k)).max() for r in prices]) # 对方定 r,我最多能赚多少
out = []
for i, p1 in enumerate(prices):
for j, p2 in enumerate(prices):
u1 = (p1 - MC) * sales(p1, p2, k, k); u2 = (p2 - MC) * sales(p2, p1, k, k)
if u1 >= best_vs[j] - 1e-9 and u2 >= best_vs[i] - 1e-9: out.append((round(float(p1), 2), round(float(p2), 2)))
return out
print("产能各 k 根,有没有「谁也不想单独改价」的价格组合?(价格取到 5 分钱,只列出最低的一个)")
for k in (100, 200, 250, 300, 350, 500, 700, 800, 900, 1000):
eq = pure_equilibria(k)
print(f" k = {k:>4}:" + (f"有,价格 {eq[0][0]:.2f}(网格上共 {len(eq)} 个组合)" if eq else "没有"))
# 没有稳定的价格,会怎样?让两家轮流、各自对对方当前的价格做最佳反应,看价格怎么走
def edgeworth(k, start=(6.0, 6.0), moves=3000, step=0.01):
p = list(start); path = [tuple(p)]
for t in range(moves):
i = t % 2
p[i] = capacity_br(p[1 - i], k, k, step); path.append(tuple(p))
return np.array(path)
print("\n轮流最佳反应(价格一分钱一档,从 (6.00, 6.00) 出发,丢掉前 1000 次,看后面的):")
for k in (300, 500, 700):
w = edgeworth(k)[1000:]
avg_profit = np.mean([((a - MC) * sales(a, b, k, k) + (b - MC) * sales(b, a, k, k)) / 2 for a, b in w])
jumps = [t for t in range(1, len(w)) if w[t, 0] - w[t - 1, 0] > 0.5]
period = f",每 {jumps[1] - jumps[0]} 次调整循环一圈" if len(jumps) > 1 else ",不循环"
print(f" k = {k}:价格在 {w.min():.2f} 到 {w.max():.2f} 之间,平均价格 {w.mean():.2f},每家平均利润 {avg_profit:.1f}{period}")
输出:
产能各 k 根,有没有「谁也不想单独改价」的价格组合?(价格取到 5 分钱,只列出最低的一个)
k = 100:有,价格 9.00(网格上共 1 个组合)
k = 200:有,价格 7.00(网格上共 1 个组合)
k = 250:有,价格 6.00(网格上共 2 个组合)
k = 300:有,价格 5.00(网格上共 2 个组合)
k = 350:没有
k = 500:没有
k = 700:没有
k = 800:有,价格 2.10(网格上共 1 个组合)
k = 900:有,价格 2.00(网格上共 2 个组合)
k = 1000:有,价格 2.00(网格上共 2 个组合)
轮流最佳反应(价格一分钱一档,从 (6.00, 6.00) 出发,丢掉前 1000 次,看后面的):
k = 300:价格在 5.01 到 5.01 之间,平均价格 5.01,每家平均利润 901.5,不循环
k = 500:价格在 2.81 到 4.00 之间,平均价格 3.40,每家平均利润 525.5,每 120 次调整循环一圈
k = 700:价格在 2.15 到 3.00 之间,平均价格 2.58,每家平均利润 237.0,每 86 次调整循环一圈
逐段看:
- 产能小(k ≤ 300):有均衡,价格正好是"两家的产能刚好把游客卖光"的价格 11 − 0.02 k:k = 100 是 9 元,200 是 7 元,250 是 6 元,300 是 5 元,和第 16 讲一致。产能小,降价抢不到更多顾客,所以价格稳。
- 产能很大(k ≥ 800 左右):均衡价格,又回到成本附近(2.0 到 2.1 元),产能大到能满足全部需求,和 Bertrand 一样。
- 产能中等(k 在 350 到 700 之间):没有稳定的价格。这是 Edgeworth 在 1925 年指出的情形。
- 没有稳定的价格,会怎样? 让两家摊轮流最佳反应:
- k = 300:停在 5.01(比 5.00 多一分钱,是网格的缘故),不循环。
- k = 500:价格在 2.81 和 4.00 之间循环,每 120 次调整循环一圈,平均价格 3.40,每家平均利润 525.5。
- k = 700:价格在 2.15 到 3.00 之间循环,平均价格 2.58,利润 237。
循环是怎么来的? 看图中蓝色的锯齿:两家互相降价,每次降一分钱,因为降价就能抢走对方的顾客。降到 2.81,再降下去,不如放弃抢客:跳回"对方卖完以后,剩下的游客愿意付的最好价格"(4.00),只卖给剩下的游客。可是,价格一高,对方马上又来降一分钱抢你的顾客,战争重新开始。这就是Edgeworth 价格循环;Maskin 和 Tirole 在 1988 年(Econometrica,56 卷 3 期,571–599 页),用"轮流定价"的博弈,给了它一个博弈论的基础。
问题 4 的答案:不会稳定。每家产能 500 根时,价格不是 5 元,而是在 2.81 到 4.00 之间循环,平均 3.40,每家平均利润 525.5,比产能 300 时的 901.5 少了四成多。产能多了,不是好事(即使这些产能不花钱)。这和 Kreps 和 Scheinkman(1983 年,Bell Journal of Economics,14 卷 2 期,326–337 页)的直觉是一致的:两家同时把产能扩大,对双方都不利。至于一家单独扩产划不划算,要看扩产本身要花多少钱,这正是他们用"产能有成本"回答的问题;我们的实验里产能不花钱,没有模拟这一步。
这里有三个要提醒的地方:
- 我们模拟的,是一种最佳反应调整,不是对博弈"均衡"的求解。严格的 Kreps–Scheinkman 结论,需要的是整个两阶段博弈的均衡,中等产能下,价格阶段的均衡是混合策略(价格是随机的)。我们的实验只是给出了一个直观的、看得见的版本。
- 它依赖配给规则。我们用的是"有效率的配给"(愿付价最高的顾客,先被便宜的那家拿走)。Davidson 和 Deneckere(1986 年,RAND Journal of Economics,17 卷 3 期,404–415 页)指出:只有这一条规则,才能让 Kreps–Scheinkman 的 Cournot 结果成立;换成别的规则,两阶段博弈的结果,会比 Cournot 更竞争。(据二手转述,请读原文。)
- 现实里确实有价格循环。Eckert(2002 年,Canadian Journal of Economics,35 卷 1 期,52–77 页)研究了加拿大温莎市(Windsor, Ontario)的零售汽油价格;Noel(2007 年,Review of Economics and Statistics,89 卷 2 期,324–334 页)用加拿大多个城市的数据,估计了价格循环出现的频率,发现小企业多的市场,循环更常见。(我只核对了这两篇文章的摘要和出处。)汽油站和烤肠摊是类比,不是同一个模型。
九、第七步:合谋的门槛
最后,把第 19 讲的合谋门槛,用代码再算一遍,并问两个新问题:惩罚更狠,合谋会更容易吗?比价格,和比数量,哪个更难合谋?
N 家摊约好:每家卖垄断量的 1/N。某家偷偷多卖一次,当期多赚,以后被惩罚。δ 是耐心程度(下一期的 1 元,今天值 δ 元)。偷偷多卖划算与否,要比的是:今天多赚的,对比以后每期少赚的(折现之后)。打平的 δ,叫门槛 δ*:δ 大于门槛,合谋能维持。
def collusion(n):
"""N 家摊约好:每家卖垄断量的 1/N。返回:守约的利润、偷偷多卖一次的利润、永远回到 Cournot 的利润"""
q_m = (A - MC) / (2 * B) / n
q_dev = best_reply((n - 1) * q_m)
q_c = (A - MC) / (B * (n + 1))
return profit(q_m, (n - 1) * q_m), profit(q_dev, (n - 1) * q_m), profit(q_c, (n - 1) * q_c)
def delta_star(stay, dev, punish):
"""偷偷多卖一次,今天多得 dev - stay;之后每期少得 stay - punish。两边打平的耐心程度"""
return (dev - stay) / (dev - punish)
# 在"无限期"里(这里取 4000 期,之后的折现小到可以忽略)直接比一比两条路
def value(first, later, delta, T=4000):
return first + sum(later * delta ** t for t in range(1, T))
print("N 家摊合谋,偷偷多卖一次,被发现后永远回到 Cournot 的卖量:")
print(" N 守约 偷偷多卖 惩罚期的 门槛 δ* δ*±0.01 时,守约的总收益 − 偷偷多卖的")
for n in (2, 3, 5, 10):
stay, dev, pun = collusion(n); d = delta_star(stay, dev, pun)
gaps = [value(stay, stay, x) - value(dev, pun, x) for x in (d - 0.01, d + 0.01)]
print(f"{n:>3} {stay:>7.1f} {dev:>9.1f} {pun:>9.1f} {d:>9.3f} {gaps[0]:>+8.1f}, {gaps[1]:>+8.1f}")
print("\n换成更狠的惩罚,或者换成比价格的市场,门槛 δ* 怎么变?")
print(" N 数量竞争 数量竞争 价格竞争(偷偷的人在垄断价上降一分钱,")
print(" Cournot 惩罚 价格战惩罚 吃下全部游客)+ 价格战惩罚")
p_m = (A + MC) / 2
for n in (2, 3, 5, 10):
stay, dev, pun = collusion(n)
steal = (p_m - 0.01 - MC) * demand(p_m - 0.01)
print(f"{n:>3} {delta_star(stay, dev, pun):>10.3f} {delta_star(stay, dev, 0.0):>14.3f} {delta_star((p_m - MC) * demand(p_m) / n, steal, 0.0):>14.3f}(1 - 1/N = {1 - 1 / n:.3f})")
delta = 0.9
print(f"\nδ = {delta} 时,最多几家还能维持合谋:")
for name, f in (("数量竞争 + Cournot 惩罚", lambda n: delta_star(*collusion(n))),
("数量竞争 + 价格战惩罚", lambda n: delta_star(*collusion(n)[:2], 0.0)),
("价格竞争 + 价格战惩罚", lambda n: 1 - 1 / n)):
print(f" {name}:{max(n for n in range(2, 400) if f(n) <= delta)} 家")
输出:
N 家摊合谋,偷偷多卖一次,被发现后永远回到 Cournot 的卖量:
N 守约 偷偷多卖 惩罚期的 门槛 δ* δ*±0.01 时,守约的总收益 − 偷偷多卖的
2 1012.5 1139.1 900.0 0.529 -5.0, +5.2
3 675.0 900.0 506.2 0.571 -9.0, +9.4
5 405.0 729.0 225.0 0.643 -13.7, +14.5
10 202.5 612.6 66.9 0.752 -21.1, +22.9
换成更狠的惩罚,或者换成比价格的市场,门槛 δ* 怎么变?
N 数量竞争 数量竞争 价格竞争(偷偷的人在垄断价上降一分钱,
Cournot 惩罚 价格战惩罚 吃下全部游客)+ 价格战惩罚
2 0.529 0.111 0.500(1 - 1/N = 0.500)
3 0.571 0.250 0.667(1 - 1/N = 0.667)
5 0.643 0.444 0.800(1 - 1/N = 0.800)
10 0.752 0.669 0.900(1 - 1/N = 0.900)
δ = 0.9 时,最多几家还能维持合谋:
数量竞争 + Cournot 惩罚:33 家
数量竞争 + 价格战惩罚:37 家
价格竞争 + 价格战惩罚:10 家
逐段看:
- 第一张表(和第 19 讲一致):用 Cournot 做惩罚,N = 2、3、5、10 的门槛是 0.529、0.571、0.643、0.752。最后一列检验:在 δ* 的两边各取 0.01,守约和偷偷多卖的总收益,差一个符号(−5.0 变成 +5.2),说明门槛是对的。
- 企业越多,门槛越高:N = 10 要 0.752。
- 惩罚更狠,门槛更低:把惩罚换成"价格战,利润是 0",N = 2 的门槛从 0.529 掉到 0.111。严厉的惩罚,让背叛更不划算。(但要小心:在比数量的市场里,“价格战"不是一次性博弈的均衡,到时候未必有人愿意执行;惩罚要"可信”,见第 19 讲 4.3 节。所以,0.111 更像一个"如果惩罚足够狠又可信"的下限。)
- 比价格,更难合谋:如果大家比价格,偷偷的人在垄断价上降一分钱,就能吃下全部游客,今天多得的,比"比数量时多卖一点"大得多。门槛是 1 − 1/N:N = 2 是 0.5,N = 10 是 0.9。
- δ = 0.9 时,最多几家能维持合谋:数量竞争 + Cournot 惩罚,33 家;数量竞争 + 价格战惩罚,37 家;价格竞争,只有 10 家。
这回应了第 16 讲 4.4 节:企业"比什么",不只决定价格,还决定合谋难不难。
十、这个实验说明了什么,没说明什么
说明了:
- 均衡不一定"走得到"。 同样的市场、同样的笨摊主,同时调整,企业多于三家,就不收敛;轮流调整,就收敛;加一点惯性,也能收敛。企业越多,越要"慢"。
- Cournot 里,没有成本节约的合并,多数时候让合并企业自己亏,对消费者一定涨价。(十家摊里,要合并到 90% 才开始有利可图。)
- Bertrand 的极端结果,取决于价格能标多细,和产能。 价格有最小单位,停在"成本 + 一格";产能中等时,没有稳定价格,价格循环。
- 合谋的门槛,随企业数上升,随惩罚加重而下降,比价格比比数量更高。
没说明:
- 现实里的摊主,不是机械的"最佳反应"。他们会预测对手、会学习、会记仇,也会用我们没有建模的方式沟通。同时调整不收敛的结果,是对这一种调整规则的结果。
- 所有结果,来自一个特定的例子:线性需求、成本不变、产品完全一样、没有固定成本、没有进入。换一个设定,数字会变,有的定性结论也会变。
- 合并分析,只看了合并对价格和利润的作用,没有看进入(涨价会引来新摊)、产品差异和质量。
- 价格循环,是一种特定动力学的结果,不是对它是不是"现实的解释"的证明。
十一、和前面、后面的联系
- 实验 70:一群没有智力的交易者,在双向拍卖里,就能把价格带到均衡附近。这里,同样"笨"的摊主,在企业多的寡头市场,同时调整,却到不了。制度细节(谁先谁后、调整多快)很重要。
- 第 16 讲:我们把 3.3 节、4.1 节、4.3 节、5.1 节、7 节的数字,都用代码重新走了一遍;价格循环和合并的亏损,是那一讲没有展开的新东西。
- 第 18 讲:5.2 节里,“对对方的出手频率做最佳应对"在点球博弈里走到了均衡;这个实验给了一个反例:在寡头市场里,同时的最佳反应调整,可以不收敛。
- 第 19 讲:9.1 节的合谋门槛(0.529、0.571、0.643、0.752,以及"δ = 0.9 时最多 33 家”),在第七步里被重新算了一遍,并且多问了两个问题(惩罚的轻重、比价格还是比数量);9.3 节讨论的算法定价,见下面"局限"。
- 实验 70:一群没有智力的交易者,在双向拍卖里,就能把价格带到均衡附近。这里,同样"笨"的摊主,在企业多的寡头市场里,同时调整,却到不了。制度细节(谁先谁后、调整多快)很重要。
- 实验 73:囚徒困境循环赛,会让各种策略(包括"以牙还牙")互相对打,看谁在重复博弈里表现最好。
十二、练习
下面的练习,都可以在上面的代码上改几个数字做出来。提示里的数字,都是我跑过的。
练习 1(惯性)。 对 N = 6,同时调整,能收敛的最大 λ 是多少?公式给什么?
提示:公式 4 ÷ (N + 1) = 4 ÷ 7 = 0.571;把第 3 步代码里的 N 列表加上 6,二分法得到 0.5704。
练习 2(N = 3 的"中立")。 N = 3,同时调整,从"甲比均衡多卖 20 根"出发,400 轮之后,每家摊的卖量在哪两个值之间来回?为什么是这两个值?
提示:每家都在 218.33 和 231.67 之间来回,也就是 225 ± 6.67。原因:乘数是 −1 的方向,是"三家同步偏离均衡";初始偏差(20, 0, 0)在这个方向上的分量,是每家 20 ÷ 3 = 6.67;这一部分永远不衰减,而另一部分(乘数 0.5 的方向)会衰减掉。
练习 3(成本不同)。 三家摊的成本是 2、2、3。求 Cournot 均衡的卖量、价格、利润和 HHI(用小数)。
提示:
cournot([2, 2, 3]):卖量 250、250、150,价格 4.50,利润 625、625、225。份额 38.5%、38.5%、23.1%,HHI = 0.349。手算:q_i = (11 − 4 × c_i + 7) ÷ 0.04,c = 2 时 250,c = 3 时 150。
练习 4(合并的 80%)。 五家一样的摊。分别合并 2、3、4、5 家,合并的这家,利润和合并前这几家之和比,各是多少?三家里合并两家呢?
提示:五家,每家合并前赚 225。合并 2 家:324 对 450(亏);3 家:506.25 对 675(亏);4 家:900 对 900(刚好打平,4/5 = 80%);5 家:2025 对 1125(赚)。三家里合并两家:900 对 1012.5,亏 112.5。
练习 5(价格和产能)。 (a)价格最小单位是 5 毛钱,两家成本都是 2,价格战停在哪里,每家赚多少?(b)产能各 250 根,均衡价格是多少?产能各 400 根时,轮流最佳反应的价格,在什么范围,平均多少?
提示:(a)(2.50, 2.50),每家 (2.5 − 2) × 850 ÷ 2 = 212.5。(b)k = 250:11 − 0.02 × 250 = 6.00(代码里网格上还有 6.05,是网格的缘故)。k = 400:价格在 3.57 到 4.50 之间循环,平均 4.04,每家平均利润 704.5,比 500 时(525.5)高,比 300 时(901.5)低。
练习 6(合谋)。 四家摊。(a)用 Cournot 做惩罚,门槛 δ* 是多少?(b)用价格战做惩罚,是多少?
提示:N = 4:守约 506.25,偷偷多卖 791.02,Cournot 惩罚 324.00。(a)(791.02 − 506.25) ÷ (791.02 − 324.00) = 0.610(和第 19 讲一致)。(b)(791.02 − 506.25) ÷ 791.02 = 0.360。
十三、局限
- 线性需求、不变成本、一模一样的产品:几乎所有数字,都是这个例子的。不要把它们当成"一般规律"。
- 最佳反应调整是一个模型,不是现实的描述;同时调整是否收敛,取决于企业的反应方式。
- 产能的实验,用的是网格上的最佳反应,价格一分钱一档;循环的周期和范围,取决于网格。
- 没有进入、没有产品差异、没有不完全信息、没有学习算法。 最后这一条,第 19 讲 9.3 节已经讨论过:Calvano、Calzolari、Denicolò 和 Pastorello(2020 年,American Economic Review,110 卷 10 期,3267–3297 页)让会学习的定价算法(Q 学习)在重复的价格竞争里交手,算法学会了高于竞争水平的价格。那是一个仍有争议的研究方向。我们这里的"笨摊主",比它们简单得多:他们不会学习,只会对眼前做最佳反应。
参考
- Cournot(1838)、Bertrand(1883)、Edgeworth(1925,The Pure Theory of Monopoly,收在《政治经济学论文集》第 1 卷;具体页码未核对):本实验里的三个原始模型。
- Theocharis, R. D. (1960). On the stability of the Cournot solution on the oligopoly problem. Review of Economic Studies, 27(2), 133–134.
- Salant, S. W., Switzer, S., & Reynolds, R. J. (1983). Losses from horizontal merger: The effects of an exogenous change in industry structure on Cournot-Nash equilibrium. Quarterly Journal of Economics, 98(2), 185–199.
- Kreps, D. M., & Scheinkman, J. A. (1983). Quantity precommitment and Bertrand competition yield Cournot outcomes. Bell Journal of Economics, 14(2), 326–337.
- Davidson, C., & Deneckere, R. (1986). Long-run competition in capacity, short-run competition in price, and the Cournot model. RAND Journal of Economics, 17(3), 404–415.
- Maskin, E., & Tirole, J. (1988). A theory of dynamic oligopoly, II: Price competition, kinked demand curves, and Edgeworth cycles. Econometrica, 56(3), 571–599.
- Farrell, J., & Shapiro, C. (1990). Horizontal mergers: An equilibrium analysis. American Economic Review, 80(1), 107–126.
- Eckert, A. (2002). Retail price cycles and response asymmetry. Canadian Journal of Economics, 35(1), 52–77.
- Noel, M. D. (2007). Edgeworth price cycles, cost-based pricing, and sticky pricing in retail gasoline markets. Review of Economics and Statistics, 89(2), 324–334.
- Calvano, E., Calzolari, G., Denicolò, V., & Pastorello, S. (2020). Artificial intelligence, algorithmic pricing, and collusion. American Economic Review, 110(10), 3267–3297.
- Williamson, O. E. (1968). Economies as an antitrust defense: The welfare tradeoffs. American Economic Review, 58(1), 18–36.