Python多条件if语句异常:传染病模拟状态统计出错
传染病传播模拟代码问题排查
我是Python初学者,正在实现一个传染病传播模拟程序,用二维数组infected存储个体状态。程序模拟T天内的传播过程:个体感染infTime天后进入免疫状态,免疫immTime天后恢复为易感状态。同时需要统计当前易感(numSus)、感染(numInf)、免疫(numImm)的个体数量,但标记为# Messing up in this loop的elif语句出现异常:执行次数远超预期,导致统计变量数值错误;若调换该语句的条件,它又完全不执行,感染个体数量始终处于极低水平。请求排查代码问题的原因。
问题代码
# Loop through T days, checking for infected individuals and connecting them to beta num of nodes, possibly infecting infTime = 5 # Time spent infected before becoming immune immTime = 20 # Time spent immune before becoming susceptible again numSus = N - count day = 0 while day < T: for a in range(len(infected)): nextnode = random.randint(0, N-1) if((infected[a][0] == 1) and (infected[a][3] < infTime)): num = infected[a][1] for b in range(num-1): if((a != nextnode) and (infected[nextnode][0] == 0)): infected[a][3] += 1 chance = round((random.uniform(0, 1)), 2) if(infected[nextnode][2] > chance): infected[nextnode][0] = 1 G.add_edge(a, nextnode) count += 1 numInf += 1 numSus -= 1 elif((a != nextnode) and (infected[nextnode][0] == 1)): G.add_edge(a, nextnode) elif((infected[a][0] == 1) and (infected[a][3] == infTime)): # Messing up in this loop infected[a][3] = 0 infected[a][4] = 1 numImm += 1 numInf -= 1 G.add_edge(a, nextnode) elif((infected[a][0] == 0) and (1 < infected[a][4] < immTime)): infected[a][4] += 1 elif((infected[a][0] == 0) and (infected[a][4] == immTime)): infected[a][4] = 0 numImm -= 1 numSus =+ 1 day += 1 print("Number of infected on day ", day, ": ", count)
问题原因分析
- 感染天数更新逻辑错误:第一个
if分支的内部循环中,每次尝试感染其他节点都会执行infected[a][3] += 1,导致感染个体的天数一天内被多次累加,远快于"每天加1"的预期。这会让infected[a][3]迅速达到infTime,触发标记的elif语句频繁执行,统计变量反复增减。 - 状态切换时机错误:标记的elif语句在每天遍历个体时都会检查,而感染转免疫的逻辑应该是每天结束后统一处理,而非在传播过程中随时触发。当前逻辑会导致同一个体在一天内多次切换状态,统计数值彻底混乱。
- 易感状态恢复赋值错误:最后一个elif中的
numSus =+ 1是将变量赋值为1,而非累加1,正确写法应为numSus += 1,否则每次恢复易感状态都会把numSus重置为1,完全错误。 - 随机节点选择位置错误:
nextnode = random.randint(0, N-1)放在外层循环开头,意味着每个感染个体一天只会尝试接触同一个随机节点,而非每次传播尝试都选新节点,直接降低了传播效率,导致感染数量偏低。 - 状态判断顺序问题:若调换标记的elif语句位置(比如放到第一个if之前),由于感染天数被错误累加,
infected[a][3]可能直接跳过等于infTime的状态,直接超过阈值,导致该分支永远无法触发。
修复方向建议
- 把感染天数、免疫天数的更新逻辑单独抽离,放在每天传播流程结束后统一执行,避免传播过程中频繁修改状态。
- 调整
infected[a][3] += 1的位置:感染个体的天数应每天加1,而非每次尝试感染都加1,需移到遍历个体的外层循环中。 - 修正
numSus =+ 1为numSus += 1。 - 将
nextnode = random.randint(0, N-1)移到内部传播尝试循环(for b in range(num-1))中,每次尝试接触新的随机节点。 - 调整状态判断顺序,确保各分支互斥逻辑正确:先处理感染转免疫,再处理免疫转易感,最后执行传播逻辑。
内容的提问来源于stack exchange,提问作者frouthuh
相关产品推荐
相关产品推荐

