理论
核心思想就是争执大衣原则:只分配有争议的部分,无争议的部分可以直接获得。
在塔木德分配算法中,有两个分界点,第一分界点E*
为第一个人债权的一半乘参与分配的人数,E* = e1*(n/2)
,第二分界点E**
为总分配金额减第一分界点,E** = total - e1*(n/2)
- 第一分界点前 所有人平分
- 第二分界点后 增加的部分所有人平分(也就是所有人损失相同)
- 两分界点之间 转化为
1
人与n-1
人的分配问题。根据争执大衣原则,先分给第一个人所拥有债权的一半,剩下的财产在n-1
人中继续分配。
代码
根据分配原则使用递归实现,使用可变参数动态调整参与分配的人数,最后可视化显示分配情况。
import matplotlib.pyplot as plt
def talmud(E, *args):
n = len(args)
if E <= args[0] * (n / 2):
return [E / n] * n
if E >= sum(args) - args[0] * (n / 2):
loss = (sum(args) - E) / n
return [args[i] - loss for i in range(n)]
return [args[0] / 2] + talmud(E - args[0] / 2, *args[1:])
def talmud_distribution_diagram(*args):
total = sum(args) # 总财产
n = len(args) # n人争产问题
E_list = [i for i in range(total + 1)] # 待分配财产列表
x_list = [list() for _ in range(n)] # n人分配列表
for E in range(total + 1):
x = talmud(E, *args)
for i in range(n):
x_list[i].append(x[i])
plt.title("Talmud distribution", fontsize=20)
plt.xlabel("Total property", fontsize=14)
plt.ylabel("Property assigned", fontsize=14)
plt.grid(linestyle='-.')
for i in range(n):
plt.plot(E_list, x_list[i], ls='-', lw=2, label=str(i + 1))
# 设置刻度标记的大小
plt.tick_params(axis='both', labelsize=10)
plt.legend()
plt.show()
if __name__ == '__main__':
talmud_distribution_diagram(100, 200, 300, 400)