您好,登錄后才能下訂單哦!
這篇文章主要介紹Python如何實(shí)現(xiàn)病毒仿真器,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
1. 仿真效果
仿真開始,一開始只有5個(gè)發(fā)病者,傳播率為0.8,潛伏期為14天
由于人口的流動(dòng),以及醫(yī)院床位的隔離,一開始病毒擴(kuò)撒不是很速度
隨著醫(yī)院床位滿了,隔離失敗,加上人口的流動(dòng),病患數(shù)開始幾何式的增加
2. 什么是仿真器
仿真器(emulator)以某一系統(tǒng)復(fù)現(xiàn)另一系統(tǒng)的功能。與計(jì)算機(jī)模擬系統(tǒng)(Computer Simulation)的區(qū)別在于,仿真器致力于模仿系統(tǒng)的外在表現(xiàn)、行為,而不是模擬系統(tǒng)的抽象模型。
3. python如何實(shí)現(xiàn)仿真器
現(xiàn)在來(lái)談?wù)劮抡嫫鲗?shí)現(xiàn)的原理。仿真器使用Python和PyQt5實(shí)現(xiàn)。PyQt5是封裝了Qt library的跨平臺(tái)GUI開發(fā)庫(kù),基于Python語(yǔ)言。
這里主要涉及到仿真器效果繪制,以及如何模擬多個(gè)參數(shù)。先來(lái)說(shuō)一下繪制市民的狀態(tài)。繪制的工作通過(guò)drawing.py文件的Drawing類來(lái)完成。該類是QWidget的子類,這也就意味著Drawing類本身是PyQt5的一個(gè)組件。與按鈕、標(biāo)簽類似。只是并不需要往Drawing上放置任何子組件。只要在Drawing上繪制各種圖形即可。
在PyQt5中,任何一個(gè)QWidget的子類,都可以實(shí)現(xiàn)一個(gè)paintEvent方法,當(dāng)組件每次刷新時(shí),就會(huì)調(diào)用paintEvent方法重新繪制組件的內(nèi)容。Drawing類中paintEvent方法的代碼如下:
# 每次Drawing刷新,都會(huì)調(diào)用該方法 def paintEvent(self,event): qp = QPainter() qp.begin(self) self.drawing(qp) # 繪制城市的各種狀態(tài)的市民 qp.end()
在繪制圖像前,需要?jiǎng)?chuàng)建QPainter對(duì)象,然后調(diào)用QPainter對(duì)象的begin方法,結(jié)束繪制后,需要調(diào)用QPainter對(duì)象的end方法。上面代碼中的drawing方法用于完成具體的繪制工作。
仿真器設(shè)置一個(gè)人員池,來(lái)進(jìn)行人員的流動(dòng)性
class Persons(metaclass=Singleton): def __init__(self): self.persons = [] # 保存所有的人員 self.latency_persons = [] # 保存處于潛伏期的人員 city = City(Params.city_center_x,Params.city_center_y) for value in range(0, Params.city_person_count): x = Params.person_position_scale * next_gaussian() + city.center_x y = Params.person_position_scale * next_gaussian() + city.center_y if x > Params.city_width: x = Params.city_width if y > Params.city_height: y = Params.city_height self.persons.append(Person(city,x,y)) # 獲取特定人群的數(shù)量 def get_person_size(self,state): if state == -1: return len(self.persons) count = 0 for person in self.persons: if person.state == state: count += 1 return count
仿真代碼
from PyQt5.QtWidgets import * from socket import * class Transmission: def __init__(self,ui): self.ui = ui self.host = 'localhost' self.port = 5678 self.addr = (self.host,self.port) def send_command(self,command,value=None): tcp_client_socket = socket(AF_INET,SOCK_STREAM) tcp_client_socket.connect(self.addr) if value == None: value = 0 data = command + ':' + str(value) tcp_client_socket.send(('%s\r\n' % data).encode(encoding='utf-8')) data = tcp_client_socket.recv(1024) result = data.decode('utf-8').strip() tcp_client_socket.close() return result def setup(self): self.ui.horizontalSliderBedCount.valueChanged.connect(self.bed_count_value_change) self.ui.pushButtonUpdateBedCount.clicked.connect(self.update_bed_count) self.ui.horizontalSliderFlowIntention.valueChanged.connect(self.flow_intention_value_change) self.ui.pushButtonFlowIntention.clicked.connect(self.update_flow_intention) self.ui.horizontalSliderBroadRate.valueChanged.connect(self.broad_rate_value_change) self.ui.pushButtonBroadRate.clicked.connect(self.update_broad_rate) self.ui.horizontalSliderLatency.valueChanged.connect(self.latency_value_change) self.ui.pushButtonLatency.clicked.connect(self.update_latency) self.ui.pushButtonClose.clicked.connect(self.close_virus_simulation) def bed_count_value_change(self): self.ui.labelBedIncrement.setText( f'<html><head/><body><p><span style=\" font-size:24pt; color:#0000ff;\">{self.ui.horizontalSliderBedCount.value()}</span></p></body></html>') def update_bed_count(self): print(self.ui.horizontalSliderBedCount.value()) result = self.send_command('add_bed_count', self.ui.horizontalSliderBedCount.value()) if result == 'ok': QMessageBox.information(self.ui.centralwidget, '消息', f'成功添加了{(lán)self.ui.horizontalSliderBedCount.value()}張床位', QMessageBox.Ok) def flow_intention_value_change(self): self.ui.labelFlowIntention.setText( f'<html><head/><body><p><span style=\" font-size:24pt; color:#fc02ff;\">{self.ui.horizontalSliderFlowIntention.value() / 100}</span></p></body></html>') def update_flow_intention(self): result = self.send_command('set_flow_intention', self.ui.horizontalSliderFlowIntention.value()) if result == 'ok': QMessageBox.information(self.ui.centralwidget, '消息', f'成功設(shè)置流動(dòng)意向?yàn)閧self.ui.horizontalSliderFlowIntention.value() / 100}', QMessageBox.Ok) def broad_rate_value_change(self): self.ui.labelBroadRate.setText( f'<html><head/><body><p><span style=\" font-size:24pt; color:#fc0107;\">{self.ui.horizontalSliderBroadRate.value() / 100}</span></p></body></html>') def update_broad_rate(self): result = self.send_command('set_broad_rate', self.ui.horizontalSliderBroadRate.value()) if result == 'ok': QMessageBox.information(self.ui.centralwidget, '消息', f'成功設(shè)置傳播率為{self.ui.horizontalSliderBroadRate.value() / 100}', QMessageBox.Ok) def latency_value_change(self): self.ui.labelLatency.setText( f'<html><head/><body><p><span style=\" font-size:24pt; color:#ffff0a;\">{self.ui.horizontalSliderLatency.value()}</span></p></body></html>') def update_latency(self): result = self.send_command('set_latency', self.ui.horizontalSliderLatency.value()) if result == 'ok': QMessageBox.information(self.ui.centralwidget, '消息', f'成功設(shè)置傳播率為{self.ui.horizontalSliderLatency.value()}', QMessageBox.Ok) def close_virus_simulation(self): reply = QMessageBox.information(self.ui.centralwidget, "請(qǐng)問(wèn)", "是否真的要關(guān)閉病毒擴(kuò)散仿真器?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: result = self.send_command('close') if result == 'ok': QMessageBox.information(self.ui.centralwidget, '消息', '已經(jīng)成功關(guān)閉病毒擴(kuò)散仿真器', QMessageBox.Ok)
設(shè)置變量
class Params: success = False # 初始感染人數(shù) original_infected_count = 50 # 病毒傳播率 broad_rate = 0.8 # 病毒潛伏期,14天 virus_latency = 140 # 醫(yī)院收治響應(yīng)時(shí)間 hospital_receive_time = 10 # 醫(yī)院床位 hospital_bed_count = 100 # 安全距離 safe_distance = 2 # 平均流動(dòng)意向[-3,3] 值越大,流動(dòng)意向越強(qiáng) average_flow_intention = 3 # 城市總?cè)丝跀?shù)量 city_person_count = 5000 # 病死率 fatality_rate = 0.02 # 死亡時(shí)間 dead_time = 30 # 死亡時(shí)間方差 dead_variance = 30 # 城市寬度 city_width = 1100 # 城市高度 city_height = 800 # 醫(yī)院寬度(需要計(jì)算獲得) hospial_width = 0 # 城市中心x坐標(biāo) city_center_x = 550 # 城市中心y坐標(biāo) city_center_y = 400 # 用于計(jì)算城市中每個(gè)人隨機(jī)位置的scale(用于正態(tài)分布) person_position_scale = 200 current_time = 1 # 當(dāng)前時(shí)間
我們可以根據(jù)這些修改仿真頁(yè)面
以上是“Python如何實(shí)現(xiàn)病毒仿真器”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。