Jason Fantl A computer science blog

Simulated Economy (1)

发布于 Apr 7, 2023 更新于 Oct 7, 2024 Preview Image By _Jason Fantl _ 7 min read

Concept

Motivation

想象一下一个开放世界 RPG 游戏,你的行为会影响商品的价格,市场会对玩家的任何行为做出反应(烧毁麦田,食物价格上涨;杀死商人,城市之间的价格出现差异;出售你在冒险中收集的许多剑,导致剑市场崩溃)。 要实现这种自适应的模拟经济需要什么? 你可以采取一种非常简单的方法,定义一个规则,例如“商品的价格与游戏中该商品的数量成反比”。 但这不可避免地无法捕捉到我们所知的经济所拥有的复杂行为。 为了创造所需的涌现行为,我们必须从个体的层面进行思考。 在这个项目结束时,我们将拥有收敛到最佳价格的市场、多个耦合市场、通货膨胀、地域上不同的经济体,以及连接城市的商人,所有这些都适应环境的任何可能变化。 这项工作部分受到 Simulating Supply and DemandEmergent Economies for Role Playing Games 的启发,如果你想探索更多,它们都是很棒的资源。

我们希望复杂的经济从个体采取的简单行动中涌现出来,那么人们如何做出经济决策呢? 这是一个难以想象的深刻问题,所以我们需要从简单的地方开始。 以下是启动我们的经济模型的激励示例,但请记住,还有许多其他方法。

你正在查看附近一家新的超市,看到了你最喜欢的麦片,但你发现它的价格是 10 美元。“这太疯狂了!” 你想。 你知道就在路边,你常去的超市以 5 美元的价格出售同样的麦片,所以你不买麦片。 但第二天,在你常去的超市里,你发现麦片的价格现在也是 10 美元。“这太不幸了,但看起来麦片的价格上涨了,真糟糕。” 你仍然决定买麦片,因为你真的很喜欢它。

这个故事概述了一个非常简单的决策算法,虽然不完整,但它为我们提供了一个很好的起点。 在商品价格方面,人们似乎会跟踪两个数字:他们个人对商品的估值,以及他们期望该商品在市场上的价格。 在上面的故事中,我们的个体对麦片的个人估值超过 10 美元,我们知道这一点是因为他们最终以 10 美元的价格购买了麦片。 但仅凭这个价值不足以解释我们的故事,如果是这样,那么我们的个体本应立即从第一个市场购买麦片。 他们对麦片的预期市场价值远低于他们看到的价格,所以他们知道他们可能可以在其他地方以更便宜的价格购买它,这就是他们没有购买第一个麦片的原因。 这两个数字就是我们开始的地方。

Implementation

我们将从一个单一的市场开始。 每个参与者将跟踪他们个人对商品的估值以及他们期望该商品的价格。 从这里我们可以判断他们是买家还是卖家:买家是对商品的个人估值高于他们预期价格的人(例如,如果他们对商品的估值为 10 美元,并期望它在市场上花费 8 美元,那么他们就是该商品的买家),而卖家是对商品的估值低于他们期望的市场价格的人。

这个最初的模拟将尽可能简单,交易中没有钱,没有限量商品,没有交易成本,没有收益递减,除了交易报价之外什么都没有。 他们将尝试随机相互买卖。 但是,预期的市场价值如何随时间变化? 为了使价格趋同,我们将让买家在交易后降低其预期价格,而卖家则提高其价格。 本质上,买家会想“我以 10 美元的价格购买了这件商品,下次我会尝试以 9 美元的价格购买它”,而卖家会想“我以 10 美元的价格出售了这件商品,下次我会尝试以 11 美元的价格出售它”。 相反的情况发生在交易失败时,买家会想“如果我想要这件商品,下次我需要提供更多”。 也许在某个时候,当预期价格超过他们的个人估值时,买家甚至会变成卖家。

代码的核心如下所示,但我将链接到完整存储库(如果你想查看更精细的细节,其中包含注释的代码。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

```
| ```
// how quickly we should update our beliefs about the market
beliefVolatility := 0.1
// find all buyers and sellers
sellers := make([]*Actor, 0)
buyers := make([]*Actor, 0)
for actor := range actors {
	if actor.expectedMarketValue < actor.personalValue {
		buyers = append(buyers, actor)
	} else {
		sellers = append(sellers, actor)
	}
}
// try to buy and sell
matchedCount := intMin(len(buyers), len(sellers))
for i := 0; i < matchedCount; i++ {
	// buyers and sellers are randomly matched up
	buyer := buyers[i]
	seller := sellers[i]
	// attempt to transact
	willingSellPrice := seller.expectedMarketValue
	willingBuyPrice := buyer.expectedMarketValue
	if willingBuyPrice >= willingSellPrice {
		// transaction made, each should try to get an even better deal next time
		buyer.expectedMarketValue -= beliefVolatility
		seller.expectedMarketValue += beliefVolatility
	} else {
		// transaction failed, each should make a better offer next time
		buyer.expectedMarketValue += beliefVolatility
		seller.expectedMarketValue -= beliefVolatility
	}
}
// if you didn't get matched with anyone, offer a better deal next time
for i := matchedCount; i < len(buyers); i++ {
	// failed buyers should offer to buy at a higher price next time
	buyers[i].expectedMarketValue += beliefVolatility
}
for i := matchedCount; i < len(sellers); i++ {
	// failed sellers should offer to sell at a lower price next time
	sellers[i].expectedMarketValue -= beliefVolatility
}

```
  
---|---  
`

通过这种非常简单的决策过程,我们可以运行我们的第一个模拟。 我们将在这个市场中拥有 200 个参与者,每个参与者都从随机的个人估值和预期价值开始。 下面是预期价值(绿色和红色分别代表买家和卖家)和个人价值(粉色)的图表。 我在不同的时间点修改参与者的个人价值,以了解它如何影响市场。

[](https://jasonfantl.com/posts/Simulated-Economy-\(1\)/</assets/img/posts/SimulatedEconomy/1/supply_demand.gif>)

我们看到预期价值迅速收敛到看起来像是个人价值的平均值。 实际上,它收敛到中位数。 我们的市场施加了试图平衡买家和卖家数量的力量,惩罚那些没有配对的人。 我们可以采取的另一种观点是考虑供需曲线。

与其给出供需曲线,不如我们需要推导出它们。 鉴于我们知道人们的个人价值观,我们可以确定对于某个假设价格,有多少人将成为买家,有多少人将成为卖家。 将每个价格的买家数量绘制成图将为我们提供需求曲线,而类似地,将卖家的数量绘制成图将为我们提供供给曲线。 通过找到两条曲线相等的价格,我们找到了理论上的最佳价格。 下面又是 200 人在每一帧中进行交互,某些个人价值在某些时间点发生了变化。 我们在图表中添加了理论价格(蓝色),以及供需曲线。

[](https://jasonfantl.com/posts/Simulated-Economy-\(1\)/</assets/img/posts/SimulatedEconomy/1/equilibrium.gif>)

基本原理运作良好! 我们没有为商品设置全局价格,也没有设置谁应该买卖,但我们仍然得到了一个功能正常的经济体,它可以收敛到最佳市场价格并适应参与者个人价值的变化。

## [Next](https://jasonfantl.com/posts/Simulated-Economy-\(1\)/</posts/Simulated-Economy-\(2\)/>)

目前我们依赖于基于回合的方法,但经济并非以这些离散的回合运作,人们会在随机的时间买卖。 人们目前也没有交易任何东西,他们只是交换信息,而不是商品。 这两个问题都可以很容易地解决,但第二个问题会产生一个新的有趣的题目:稀缺性。

[Simulated Economy](https://jasonfantl.com/posts/Simulated-Economy-\(1\)/</categories/simulated-economy/>)