通过病例流调来了解什么是广度优先搜索BFS
Posted 正经兔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过病例流调来了解什么是广度优先搜索BFS相关的知识,希望对你有一定的参考价值。
这两天新出的病例让大家人心惶惶。
然而狡猾的老正经兔,恰好以此借口推掉了去一个亲戚的喜酒。
现在我们把话筒移交给老正经兔——
大家好,我是做题家老正经兔,来科普一则入门初级知识。
前两天病友照常发给我一张很有他风格的图:
那么这个跟标题什么关系呢?
【众所周知】,病例的流调是这样一个过程:
1、发现一个病例,卫健防疫部门就会开展流调,找到该病例近期全部的密切接触者
2、然后将所有的这些密切接触者隔离起来进行观察。如果密切接触者中,有人也阳性了,那么再去寻找这个人的密切接触者……
3、重复以上步骤,直到没有新的阳性
这种每次都访遍当前对象所有的直接密接者的形式,就是广度优先搜索,英文叫breadth first search,简称BFS。
另一种则是length……哦不,depth first search深度优先搜索,简称DFS。如果是DFS,则是找到A的密接者B,随后找B的密接者C、C的密接者D、D的密接者E……一直一根筋找下去,直到没有新的人出现。这当然是不符合隔离做法的。
我们在找密接者的时候还会碰到重复的情况,比如上图,病例6和病例3是同事,有一些同事,既是病例6的密接者,也是病例3的密接者。比如同事张三,他已经作为病例3的密接者出现了,那么统计人员在记录6的密接者又看到张三时,就会标记“已掌握”,跳过他,不会把他劈成两半去隔离,也不会把他隔离2次。
这表示,搜索时需要记录已经掌握的密接者。
为了更好地理解,我们假设一个实例:
已知奋斗逼0、1、2、3、4、5、6一共7个人最近几天都在同一个公司从早到晚奋斗。他们的关系是这样的:
0的密接者:1、2
1的密接者:4
2的密接者:4
3的密接者:5
4的密接者:1、2、6
5的密接者:3
6的密接者:4
今天突然发现0是新病例在上星期的密接者,有可能被传染了。其他和0一起加班的奋斗逼也有可能被传染了。那么,这几个人中总共要隔离哪些人?
过程是这样的:
1)首先是0毫无疑问
密接关系待查:0
已掌握:0
2)和0接触的1、2也是,把1、2也记下
密接关系待查:1、2
已掌握:0、1、2
3)下面是1的密接者4,记下
密接关系待查:2、4
已掌握:0、1、2、4
4)2的密接者还是4,前面已经记录过了,跳过
密接关系待查:4
已掌握:0、1、2、4
5)4的密接者1、2都是出现过的,跳过;6是没出现的,记下
密接关系待查:6
已掌握:0、1、2、4、6
6)6的接密者还是4,出现过了,跳过
密接关系待查:无
已掌握:0、1、2、4、6
无待查的密接关系,所以结束
所以,要准备两个小本本,分别记录哪些人待查、哪些人已掌握,从前面的过程易知,分别用队列和集合实现。
我们再用数组relation来表示密接关系,relation[i]表示i的密接者有谁。那么在上面的例子中,relation就是这样的数组:
[[1,2],[4],[4],[5],[1,2,6],[5],[4]]
那么,代码实现就如下:
def bfs(x):
included={x} #已掌握
to_check=[x] #待查
while to_check!=[]:
tmp=to_check.pop(0)
for x in relation[tmp]:
if x in included:continue
included.add(x)
to_check.append(x)
return included
if __name__ == '__main__':
patient=0
relation=[[1,2],[4],[4],[5],[1,2,6],[5],[4]]
res=bfs(patient)
print (res)
运行结果:
以上是关于通过病例流调来了解什么是广度优先搜索BFS的主要内容,如果未能解决你的问题,请参考以下文章