什么是传染病动力学?numpy和matplotlib用python实现传染病模型SI模型SIS模型SIR模型SEIR模型 什么是传染病动力学?最近,在报道疫情的众多新闻中,相信大家也看到过一些来预测新型冠状病毒会导致感染肺炎的人数。你一定好奇,这个人数要怎么预测呢?预测人数又有什么用呢? 事实上,从学科方向来说,这类研究属于传染病动力学,就是用数学模型去描述传染病在人群中传播的规律,从而预测患病人数,进而指导政府制定措施和政策去控制传染病的传播。
0 w1 C! r/ i7 g* i这类研究最早可追溯到18世纪Daniel Bernoulli对天花的研究,而我们今天所要介绍的SIR模型是1927年Kermack与McKendrick在为了研究伦敦黑死病而提出的,是传染病动力学中最基础的模型。 介绍了传染病模型的背景信息,不知道现在你对传染病模型更有兴趣,还是执着地对python更有兴趣呢?不论哪种,这篇文章会满足你所有的好奇心。 numpy和matplotlib首先,安装一下这节课我们需要使用的两个python包,numpy和matplotlib。: V X1 K* `+ E% ^3 _7 O# E
numpy-是python进行科学和矩阵运算最常用的包。 用numpy建立一维数组,存储和计算每天传染病人数的数据。 - F! t/ ], f7 t. w0 ^
import numpy as np import matplotlib.pyplot as plt 用matplotlib绘制传染病人数随天数变化的曲线,给出模型预测人数变化的直观认识。 好啦,下面开始用python实现传染病模型吧。 用python实现传染病模型为了让大家能够更好地理解,我们先不直接说SIR模型,我们从最简单的开始。 SI模型首先想象这样一个场景,一个城市有 个人,假设没有人出生和死亡,忽然有一天有 个人感染了病毒成为了患者,如果每天每个患者能够有效传染 个人,那么第二天患病人数是多少呢?最简单的答案是: ,也就是说每天都会新增 个患者。那这样以来,在无限远的将来会有无穷多的人被感染,显然这是不合理的,那错在哪里?仔细思考,你一定发现了,已经患病的人就不能再被传染了,所以我们有必要把人群分为两类,易感者(S-susceptiable)和感染者(I-infective)(你猜的没错,这就是SIR中S和I的含义,R的含义之后介绍再讲)。为了之后方便计算我们记易感者和感染者在人群中的比例为 ,那么 。我们重新考虑上面的问题,顺便来个示意图: Image Name这样的话,每天新增的患者数为 ,也就是总传染人数乘以易感者所占的人群比例。9 ?" I) g. k1 Z( n) \
那么每天的感染者比例的增加量就是 。我们假设城市有一千万(N=10的7次方)人,每个患者每天接触感染每天0.8人(lamda=0.8),初始感染人数为45人(i0 = 45/N),我们来模拟70天(T=70)的情况。 # population
6 c. J U( a& @N = 1e7
" \) L, G/ e1 w; L; x7 K# simuation Time / Day3 s, p; F6 a) J/ F
T = 70
0 C1 [, i8 `6 W0 V- q# susceptiable ratio L z7 w4 G: L' w# ~0 p- }3 [
s = np.zeros([T])9 Y9 i8 ~1 Z5 |5 O! |
# infective ratio
7 T' I$ f% @8 I' B. \! f3 ]i = np.zeros([T])( E1 f! f8 M9 E# N% K9 Q
# contact rate+ B6 u3 A# N& u; f( f0 Z! j5 S3 S
lamda = 0.8/ p! [; N& n- Q3 T: F
, u" P0 h6 c9 c7 F# P# initial infective people- s' B$ [/ B6 s! C3 Z
i[0] = 45.0 / N$ [; b# l+ x% R2 x
* N$ q- {: F+ ^* T3 h: [- R1 v
for t in range(T-1):8 {9 [$ H6 G- z
i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t])0 a ]$ A! d; Z4 |- \6 b% t
+ `6 t. y% e* l0 Y- G
0 Z6 T9 Q- C" m; x0 P4 ^" j. a U, Z
9 y3 A) n3 h8 j2 O; i. @$ W8 l相信其他语句大家都明白,新知识是这两行:+ f7 G, f* t8 m1 Y6 w
4 a2 n% p/ T& [' ]" x. ], r9 ?$ v) ~ w/ a9 A* E+ O$ Y
s = np.zeros([T])
# I, Z- y/ U5 l6 e- li = np.zeros([T])# F+ b# A% g1 K/ k& d4 o1 P
. C w2 z3 O+ O6 d! c这两句话的意思是一样的,就是利用numpy(已被我们重新命名为np)的函数(zeros())来建立一个所有元素都是零的数组,而给的参数决定了这个数组的维度。比如:
6 U5 `" S4 ]+ d" J" L; Z) I. R: t6 e5 E6 i" d
a = np.zeros([2,3])
& E! p, b: P' S6 J: j; I6 na3 Q+ V( I4 u: N# W' E( s1 F
7 Z+ p( g) G* {* @' barray([[0., 0., 0.],
9 G) Y" }1 e8 G& U7 L [0., 0., 0.]])
! u% E9 D: ^- S7 {' l" h& t# x$ o% b b( w& b
& r8 X6 ~- \% ]! H$ h0 `( b; {2 s5 s2 Zarray([0., 0., 0., 0., 0.])
6 R6 ?" q, ~+ l$ R6 v0 y: o% X- T
, }5 Z# z+ R' J5 y' |; r0 L2 E3 H& [类似的还有产生元素全部是1的数组的函数np.ones():8 [) p: V" l; ~0 \+ g+ S
0 j) e. f# _# a
a = np.ones([5]) j9 F4 e' L( I" n2 W& i+ G. p
a
! z- X3 |1 P" G3 [; ?9 M
; e4 w l& p5 O( H1 v) xarray([1., 1., 1., 1., 1.])
, |$ B" P$ _ P0 {5 D, G' S/ O6 e8 H( l
* [! |) `2 z/ e7 }# W
a = np.ones([2,3])+ W( |; J1 p8 f7 i
a0 p( s; Y3 n7 C3 K& y# \
- ]/ ^8 V- [7 |7 N i+ b: I4 n! y0 m( `' q3 B- t
array([[1., 1., 1.],
1 _4 Q4 G: Z+ ^$ g5 t# z [1., 1., 1.]])
! Q7 u/ x1 L0 k4 l1 g* W2 n0 F( f: N; V* [, w6 m9 R: N
: A- p2 m2 r$ J8 d# ]5 J6 x3 w
plt.plot(i)! ~( F* B/ ~% p% t c, A
$ h. t# u4 Y6 G! C5 P4 j
/ `4 U) G7 ?: } h/ h6 V2 b
[<matplotlib.lines.Line2D at 0x7f0c2768d6d8>]2 I; P/ F+ v+ v
3 p7 N Q2 Z: t& |1 }5 T) E2 [- ?8 \) u# x
![]()
# e L( a/ B7 c% p' q
$ O) @( _& B* m* H. ?4 ? `
8 U- f" O0 w) H; k2 C) E. W1 p实现SI模型的核心代码是第三个cell的第11,12行:2 o9 I3 a+ W0 V- B* E1 O/ {) U
& a' E8 O) a5 s" V* r2 R& Q; l
for t in range(T-1):8 v' @; e& i. |; j% `/ O, S2 I
i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t])
6 M u0 |, p% Q8 ~
& i" j) J4 J" U& |; J' _8 i1 L2 A8 d就是我们建立的数学模型,利用python的for循环语句累加迭代的方式把每天的增加量叠加到感染者比例上。 运行代码完成计算,我们利用matplotlib的pyplot来画出感染者的随天数的变化曲线:
: W, M8 u$ ~% g6 k) Bfig, ax = plt.subplots(figsize=(8,4))- `, O M4 I$ _5 q. E- ?
ax.plot(i, c='r', lw=2)+ z- c8 W8 o p4 M" |+ F1 ~
ax.set_xlabel('Day',fontsize=20)
3 h4 i% b+ P5 i4 ?# y% l' A- e- fax.set_ylabel('Infective Ratio', fontsize=20)
0 X0 d4 [5 M+ b% max.grid(1)
4 b- A! a+ a/ ~; d3 L, o, a. gplt.xticks(fontsize=20), Q$ _; E' g: W( U
plt.yticks(fontsize=20);
$ h# o3 J& p& g9 V6 f0 W" H9 j$ T* j- _# y: T& z
, ]' ?- c- R9 ~8 }9 i5 j![]()
! S% Z |/ F8 ?1 e+ q8 u
3 Y7 B) O8 B% x( Q3 v( y从这个结果看到,大约在25天左右,全部人群都会变成感染者,感染率 。
. i! F4 @# J9 V" B; }- \在程序中我们假设每天每个患者传染0.8个人,你可以改变lamda的值,观察全部人群感染的天数的变化。
: X$ t& \2 Z1 Z认真思考你会知道,lamda的现实意义就是该城市的卫生水平,衡量的是消毒,隔离这些措施执行得怎么样。回到传染病模型,按照SI模型计算的结果,我们全人类都会患病,这好可怕!原因是我们忽略了一个很重要的因素,那就是我们有奋斗在一线的医护人员,我们会被治愈!所以SI模型只适合研究具有高传染风险又不能被治愈的病(比如HIV)。 但是对于其他病,我们是可以靠医疗和自身免疫系统康复的,那么紧接着的一个问题就是,被治愈后还会再被传染上嘛?根据这个问题的回答不同,我们有了两个不同的模型,SIR 和 SIS。现在可以揭晓,SIR的R的含义了,就是移出者(Removed),现实含义就是指被治愈后不会再被感染的人。而SIS表示治愈后仍然还是易感者。下面我们用python来分别实现这两个模型。 SIS模型为了实现这个模型,我们需要引入新的一个参数,治愈率 。好啦,先上我们的新示意图: Image Name和SI模型做比较,区别就是计算感染者的增加数时要减去被治愈的人数。; X- N3 o% ?# c! G8 R; y# G- e
所以这时候每天的增加的感染者为: ,
4 y& {* \( V. w) D4 r' j增加的感染率为: 。
( E0 u! U- F: l3 G/ U& _; W模型完成啦,修改python代码:
3 T+ f* M# B4 p9 K1 D1 P; _# susceptiable ratio
8 q6 j T l+ _# v# Z' fs = np.zeros([T])
* O# l* s! r/ Q1 b) M# infective ratio: H4 O3 i# ^4 q: X
i = np.zeros([T])
# F7 F3 N7 ~1 y
9 p, h! r* {. `# contact rate6 x6 D, |/ m6 `! g
lamda = 1.02 G/ F5 T. h6 Z# Y
# recover rate9 G. }: e. Z* M8 Q8 e8 @3 H
gamma = 0.5 ) F3 p K5 D8 k, E
" Y1 N {& Z$ \2 L3 j" Y r; k& Y
# initial infective people; t& C, N+ Z) E, q
i[0] = 45.0 / N
7 \+ O( o9 a! Q% @4 k) H
5 b$ `! x) B& V3 Q" c. h3 Mfor t in range(T-1):$ U. z# w; S& R9 m# X( F" s. Y H
i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t]) - gamma*i[t]/ P, o# P+ z! w: P
7 R) ~0 J& L5 a
& z" p# e+ U& o! P2 t: \& C4 _- v2 E
3 V( m! w; `, x J4 e* _8 |; F3 u运行代码,我们画出曲线(代码和SI模型的画图完全一样):3 ?% D0 F* z9 ^! d& u: d
: H4 C. u' H8 O, Y/ v4 Sfig, ax = plt.subplots(figsize=(8,4))
& G. E. W6 W' }4 A) W' Y& }ax.plot(i, c='r', lw=2)$ a, @# X0 e# ~
ax.set_xlabel('Day',fontsize=20) Q% t2 i' [% P
ax.set_ylabel('Infective Ratio', fontsize=20)3 F! e& q6 Q/ z" \, |9 K
ax.grid(1)
* [/ j5 B: u: y2 R5 g( a; splt.xticks(fontsize=20)
2 M& M# S0 ]: h4 Kplt.yticks(fontsize=20);6 @- k( Y! ^8 c# `) V2 _& H
2 N2 |# _; f7 \3 P% M
![]()
+ e1 b$ j/ B ^& B
8 J7 L# c% b0 h0 n3 t, d* `+ P7 O" l4 x
行代码,我们画出曲线(代码和SI模型的画图完全一样)9 I; h4 X/ Y. W
可以看到,达到最大感染率的时间退后10天左右,最后感染和治愈达到动态平衡,人群中有始终有一半的人感染着。所以,SIS模型适合研究具有传染性和反复性的流行病,比如常见流感。同样的,感兴趣的话,改变lamda和gamma的值,观察曲线的变化。和lamda不同的是,gamma的现实意义就是对这种疾病的治疗水平。 SIR模型加入了移出者,被治愈的病人不会再被传染,先上我们的新示意图: Image NameSIR 模型
( d: w1 A0 p" V, z+ B! z注意到这里,人群被分成了三类,不再只有I和S,所以相比于之前的模型,我们需要找到新的约束关系。现在我们需要分别计算三种人每天的增加量了: 7 K8 o( _: Z4 ?9 X9 a* @/ O
- 易感者:每天都在被传染,所以一直在减少,减少量为被传染的人数:
- 感染者:增加了被感染的人,减少了治愈的人:
- 移出者:增加了治愈的人:
+ G& d2 S6 [- l# ?. F1 b" s
建模完成,修改python代码,并且假设人群普遍易感,新型疾病,初始没有移出者。 % y( S7 t2 }0 R. ~& [' r
# population/ J1 f B& Q; K
N = 1e7 + 10 + 53 y7 q$ e2 F9 X% U$ c& e6 f( h2 k
# simuation Time / Day4 w0 R5 W/ v0 f0 B. N- J; s
T = 170' o9 r: m$ [8 V: e* |3 ~
# susceptiable ratio! f* g [/ i; G4 W, O& m
s = np.zeros([T])1 j9 K$ j6 M P4 K" \, s& T+ m
# infective ratio
; Q" B: ~6 l. Yi = np.zeros([T])7 e- M8 {) ?' |% o' } e1 H# X
# remove ratio5 L$ `, \! ^, p! M* }
r = np.zeros([T])
& y+ Y# e1 i2 ?/ Z( ~8 w3 [
) o2 Q3 [% a' v+ @" c: N% t) q# contact rate& U8 p5 ~* b0 {3 |
lamda = 0.2586% N% u& ?4 L3 ?) T; h
# recover rate7 t2 y- g; ]4 a5 x E7 r
gamma = 0.0821
: z }/ p. H; s! \
5 h4 t7 {3 {- v8 a, z9 R# initial infective people
( @+ _0 M2 Z; t! ki[0] = 10.0 / N& z' p1 i5 y X
s[0] = 1e7 / N j1 Y$ }2 L* R8 N6 v, Y+ ^
for t in range(T-1):
1 X+ f& Q+ H' V- T i[t + 1] = i[t] + i[t] * lamda * s[t] - gamma*i[t]# {+ M, A% K- f
s[t + 1] = s[t] - lamda * s[t] * i[t]
: F$ ?; D# J) z* A+ m0 Q" r$ _ r[t + 1] = r[t] + gamma*i[t]
/ N1 x+ e& q; e% u, [% x/ N
/ |! _% k5 G, M) nfig, ax = plt.subplots(figsize=(10,6)); W: b, C q) D1 C. k
ax.plot(s, c='b', lw=2, label='S')
8 t& H( S3 c0 w T6 K7 W6 U c0 o$ j4 qax.plot(i, c='r', lw=2, label='I')
. ~' {9 Y; _9 q& t8 V# Dax.plot(r, c='g', lw=2, label='R')- u' a% n, w- k+ O' B; c
ax.set_xlabel('Day',fontsize=20)
6 X" e5 M, ?) {9 s& Cax.set_ylabel('Infective Ratio', fontsize=20)
9 t8 e/ j! o! c/ E c) o, Z( L% Pax.grid(1)2 v5 K/ {+ T; q: v) o0 f
plt.xticks(fontsize=20)
# f/ X* ]! i3 F9 \9 z( E% {plt.yticks(fontsize=20)4 v% V$ [: x) `5 z3 D/ I) {0 ?6 t1 @8 B
plt.legend();5 G4 z, {$ v E3 {
9 E: S4 d+ v) n+ s- n g1 z) R* w, v I3 `6 `' }! ]
![]()
( `) T5 E+ W4 R9 Q
T6 l) N: p7 s4 r5 n感染人数峰值发生在一个月左右,最大感染人数不到人群的20%, 但是最终人群的80%都会得此病(就是最终的移出者的比例)。SIR模型适合研究没有潜伏期的急性传染病,治疗后能够痊愈并具有抗病性。 到这里,虽然不准确,我们也可以先用SIR模型来分析一下此次疫情,武汉新型冠状病毒的传染病动力学! 模型有了,其实就是确定参数的问题。一开始就有人做了这个工作: Image Name于教授给的参数是参考了非典的, ,初始易感人数为一千万, 初始感染10人,初始移出者5人,那么我们的城市总人数 , 带入我们的模型得到结果:重现于教授的模型
; L: ?4 O- ?' H6 {) R: `4 B9 D高峰和尾声日期的推测基本相符。 4 C' j% b7 T! @
# susceptiable ratio3 ^6 p$ h j' g0 x& i3 V+ k
s = np.zeros([T])) ?+ N; V2 n; ^! E4 w
# infective ratio3 d# Y" t, m. _: E2 K+ R
i = np.zeros([T])
4 ~# O: A+ Y9 j# W3 L! w# removed ratio% D5 s$ J* r: i! S3 g
r = np.zeros([T])
$ U5 h/ w- x( X7 Z/ s+ a. V q2 v' F& G
# birth ratio, s, M( Q; c1 o/ ~
b = 20.0 / N
0 T! l: z/ e& N# death ratio" M7 t \# _+ r3 }! x
d = 10.0 / N; t; x; K/ q% X4 J$ F3 `/ `' u
0 `) \2 o7 d2 f/ e" L7 y; O# contact rate- \/ N/ A/ }: m. r4 F
y = 1.5
5 ]0 W3 s: `8 D# recover rate7 I: X6 Z$ Z; o. E
u = 0.8 # 1 / infective_period
( \: { |+ [/ |# }
& s. _! b- X/ k& e0 h! |- C# sigma = y / u$ b# N# I4 ]# M! J: ~& `8 f" O
) X$ o7 s+ H/ g# initial infective people
/ [: j4 h. F& h# j2 t: C: zi[0] = 45.0 / N- {6 x8 d, L Z
s[0] = 1 - i[0]
# h* y6 m. r2 o& G/ dfor t in range(T-1):5 X" C4 F n+ f9 l0 O9 z" |, x3 [
i[t+1] = i[t] + i[t] * y * s[t] - u*i[t] - d*i[t]
' y6 } Z" U0 M s[t+1] = s[t] - y * s[t] * i[t] + b - d*s[t]
6 C7 d, i- i4 B( \ r[t+1] = r[t] + u*i[t] - d*r[t]
" w2 V' _8 z8 y4 {) k/ m) N, y! e3 o, z+ o& K3 f$ Z* S1 H j4 C
plt.plot(i). n+ s3 M5 E0 x5 y) Q
plt.plot(s)- k4 Z- Q3 d/ R) e7 p
plt.plot(r)% z2 m# q- S! @ Y
plt.plot(np.diff(i),ls='--')& K4 @8 W% D; F6 b1 a/ V
+ G4 Y j& ~( j8 x2 t
3 z+ i8 a {. ?[<matplotlib.lines.Line2D at 0x7f77796e8518>]- n p5 t6 p- `& [% s
& C& {' Z1 {9 i; W- o: D
![]()
8 a+ ]! `1 B' V; ^! k0 ]4 b9 z
SEIR模型但是,SIR模型和实际情况的出入会比较大,因为忽略了太多因素了,比如说潜伏期,比如说政策调控,药物,出生死亡等等。下面我们可以和前面一样,把潜伏期考虑进去,新增一个人群,叫潜伏者E(exposed): Image NameSEIR模型
% i% F0 W' C8 N, c% G同样的我们需要计算各人群每天的增加量: S:每天减少:
- \3 U, o( o5 ?2 ^, X; I1 VE:每天增加传染,减少发病: ( X, w( h- ~/ Q* F4 `3 {2 }3 [
I:每天增加发病,减少治愈: " f# {" J( e6 n
R:每天增加治愈:
' H* q1 G; X6 |* h) s: q建模完成,修改我们的python程序,这里的 可以理解为潜伏期的倒数。给的4天。新型冠状病毒给目前临床的潜伏期是3-14天。% N. S* B: b3 E
# population
" L6 ]9 {3 p0 b$ MN = 1e7 + 10 + 5
% W K; j* P0 l" a9 p$ G0 p* U( c# simuation Time / Day
5 ]- R0 n$ @5 T. @6 uT = 170
8 e, @# A: ~5 b# y6 i# susceptiable ratio; j" _1 z b$ @
s = np.zeros([T])7 A: }7 I) i# L7 r# o8 g& F
# exposed ratio9 Z9 E/ f: m4 @
e = np.zeros([T])* X* t7 p, V# X8 a+ o* f+ a
# infective ratio
3 J- L2 ~( V& D! z7 E) J7 _9 Ui = np.zeros([T])8 [+ Z9 K$ ^8 z: G2 u; F
# remove ratio
! N8 u4 [! M. }+ H# I( ?r = np.zeros([T])
8 W( s" e1 [1 R
$ d/ Q+ O4 C+ e9 t# contact rate
9 J, n9 ~- r" @, B5 W% L. alamda = 0.5
9 N2 y$ A$ z1 E q; C6 T# recover rate% P) ?. O3 l- L7 y1 P
gamma = 0.0821
- `8 p' m$ G- y/ Y# exposed period
/ U. f( c$ y! ^- b9 g* msigma = 1 / 4+ m! c/ y! z0 K6 E; D* Y
6 a9 w6 x* }' ~+ {* P. I# initial infective people
m0 C2 o0 R' H- s# Gi[0] = 10.0 / N' f# e& R) M. c# j5 G# ?9 V
s[0] = 1e7 / N8 X+ D! b1 b' Q( q
e[0] = 40.0 / N
! P; g" J0 ]+ ifor t in range(T-1):
# c# p, M/ S" W% X s[t + 1] = s[t] - lamda * s[t] * i[t]9 ?/ s+ `: @3 v) b( I& S% l
e[t + 1] = e[t] + lamda * s[t] * i[t] - sigma * e[t]4 H: N0 a* F. L2 r+ u0 L/ z& `3 _1 Q
i[t + 1] = i[t] + sigma * e[t] - gamma * i[t]( k" C9 k4 D% |% b
r[t + 1] = r[t] + gamma * i[t]
' ?, M1 V9 o1 e1 B, |& ?& B& F! K9 Q$ T9 \6 H& g% l, o
. \! ~( _. u3 hfig, ax = plt.subplots(figsize=(10,6))
2 }8 k) \ S1 J1 s: p! Hax.plot(s, c='b', lw=2, label='S')8 q- Z1 ?/ g. U* N# A* e: E3 F7 V( h
ax.plot(e, c='orange', lw=2, label='E')$ m x9 K0 h! H8 `6 y( {# D
ax.plot(i, c='r', lw=2, label='I')
3 V: v& `% h! ]9 P: k, rax.plot(r, c='g', lw=2, label='R')/ o- n6 P$ L" ]* A0 x+ ]/ A, M( r
ax.set_xlabel('Day',fontsize=20)1 q5 n$ }& { L& P) t- Z
ax.set_ylabel('Infective Ratio', fontsize=20)
* o) s- Q2 D( t8 m lax.grid(1)
- {/ t; `" Q# A* s7 Qplt.xticks(fontsize=20)* \, _' }: | _7 b- l1 d( y
plt.yticks(fontsize=20)# \3 w( v. {; m" s6 |3 g# z
plt.legend();& E$ s+ y7 g, C+ V
( t4 P9 Y, C# T8 y- ^; {$ \
) h$ G/ ]" h% m$ A6 U+ `3 f4 t 8 \2 c' c' C2 M/ v4 e" X( _
: a1 k1 p' b+ ^1 |; w, f9 m" m. H按照模型的结果,此次疫情可能真的要持续到 三四月份。这个接触率 真的非常影响表现,模型给的是个常数,但是由于政府措施的原因,这应该是个变化的值。( S: H0 _; q; B
还有治愈率 也是。没有完美的模型,但是随着考虑因素的增多,就会越来越接近实际情况,从而指导政府的疫情方针政策的制定。
9 `2 C4 e" g' z
6 q" H" N: L. d+ f h3 m" E$ v
7 Y) v7 L9 v$ _: v
, Q) d( k" \* @: r
, Q1 n" H* H1 r: K7 x |