#事件對象
class Event:
def __init__(self,time,taxi_ident,action):
'''
:param time:發(fā)生這個事件的時間
:param taxi_ident:觸發(fā)這個事件的出租車對象id
:param action:這個事件所代表的行為
'''
self.time=time
self.taxi_ident=taxi_ident
self.action=action
def __str__(self):
return 'Time:{},Taxi_Ident:{},Action:{}'.format(self.time,self.taxi_ident,self.action)
def values(self):
return [self.time,self.taxi_ident,self.action]
#用于給外部排序比較的接口
def __eq__(self,other):
return self.time==other.time
def __lt__(self,other):
return self.time<other.time
#事件列表
class Event_List:
def __init__(self):
'''
我們利用一個普通列表來實現(xiàn)
'''
self._list=[]
def put(self,event):
self._list.append(event)
def get(self):
self._list.sort()
result=self._list[0]
del self._list[0]
return result
def list_size(self):
return len(self._list)
def is_empty(self):
return self._list==[]
#模擬出租車的協(xié)程
def taxi_coroutine(ident,trips,start_time):
"""
每次狀態(tài)改變便會yield一個事件
:param ident:出租車的id
:param trips:出租車接多少趟客
:param start_time:出租車從車庫出發(fā)時間
"""
time=yield Event(start_time,ident,'司機佩琪:離開車庫')
for i in range(trips):
time=yield Event(time,ident,'司機佩琪:客人上車')
time=yield Event(time,ident,'司機佩琪:客人下車')
yield Event(time,ident,'司機佩琪:返回車庫')
import random
#通過傳入事件類型給定到從傳入事件到下個事件之間的事件
def compuate_duration(event):
'''
:param event: 當前發(fā)生過的事件(根據(jù)這個事件計算到下個事件發(fā)生之間的耗時)
'''
if event.action in ['司機佩琪:客人上車','司機佩琪:離開車庫']:
return random.randint(1,10)
elif event.action in ['司機佩琪:客人下車']:
return random.randint(1,5)
elif event.action in ['司機佩琪:返回車庫']:
return 1
else:
raise ValueError('傳入參數(shù)的事件有誤')
#出租車運營模擬
class Simulator:
def __init__(self,taxi_corouting_dict):
self.events=Event_List() #所有事件
self.couroutines=taxi_corouting_dict #所有出租車協(xié)程
def run(self,end_time):
"""
模擬器從事件列表中獲取事件并處理
:param end_time: 事件模擬器的結束時間
"""
for ident,taxi_corouting in self.couroutines.items(): #啟動每一個出租車協(xié)程
first_event=taxi_corouting.send(None) #也可以替換為:next(taxi_corouting) 意為預激協(xié)程
self.events.put(first_event)
#運營模擬仿真主循環(huán)
current_time=0 #主循環(huán)當前時間
while current_time<end_time:
if self.events.is_empty():
print('模擬器:所有事件處理完畢')
break
current_event=self.events.get() #獲取發(fā)生最早的事件(time最小)
event_time,coroutine_ident,action=current_event.values() #解析事件
current_time=event_time #更新模擬器時間
print('模擬器:處理 出租車-{}{}{}'.format(coroutine_ident,coroutine_ident*' ',current_event)) #模擬器處理事件
current_taxi_coroutine=self.couroutines[coroutine_ident] #獲取觸發(fā)該事件的出租車協(xié)程
taxi_next_event_time=event_time+compuate_duration(current_event) #計算當前出租車協(xié)程的下個事件發(fā)生時間
try:
taxi_next_event=current_taxi_coroutine.send(taxi_next_event_time) #把計算得出的下一個事件發(fā)生的時間發(fā)送給協(xié)程,協(xié)程會返回下一個事件或者拋出StopInteration表示執(zhí)行結束
except StopIteration:
del self.couroutines[coroutine_ident] #刪除執(zhí)行完畢的出租車協(xié)程
else:
self.events.put(taxi_next_event) #將下一個事件放入事件容器
else: #如果所有事件沒執(zhí)行完畢就超時,則執(zhí)行else判斷下的代碼
print('模擬器:超時結束,還有 {} 個事件等待處理'.format(self.events.list_size()))
def main_01():
taxis={
i:taxi_coroutine(i,(i+1)*2,(i+2)*3)
for i in range(3)
}
taxi_simulate=Simulator(taxis)
taxi_simulate.run(100)
'''
執(zhí)行:
main_01() #end_time=100
輸出為:
模擬器:處理 出租車-0Time:6,Taxi_Ident:0,Action:司機佩琪:離開車庫
模擬器:處理 出租車-0Time:8,Taxi_Ident:0,Action:司機佩琪:客人上車
模擬器:處理 出租車-1 Time:9,Taxi_Ident:1,Action:司機佩琪:離開車庫
模擬器:處理 出租車-0Time:10,Taxi_Ident:0,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:12,Taxi_Ident:2,Action:司機佩琪:離開車庫
模擬器:處理 出租車-0Time:14,Taxi_Ident:0,Action:司機佩琪:客人上車
模擬器:處理 出租車-0Time:16,Taxi_Ident:0,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:18,Taxi_Ident:2,Action:司機佩琪:客人上車
模擬器:處理 出租車-0Time:18,Taxi_Ident:0,Action:司機佩琪:返回車庫
模擬器:處理 出租車-1 Time:19,Taxi_Ident:1,Action:司機佩琪:客人上車
模擬器:處理 出租車-2 Time:23,Taxi_Ident:2,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:27,Taxi_Ident:2,Action:司機佩琪:客人上車
模擬器:處理 出租車-1 Time:29,Taxi_Ident:1,Action:司機佩琪:客人下車
模擬器:處理 出租車-1 Time:30,Taxi_Ident:1,Action:司機佩琪:客人上車
模擬器:處理 出租車-1 Time:32,Taxi_Ident:1,Action:司機佩琪:客人下車
模擬器:處理 出租車-1 Time:35,Taxi_Ident:1,Action:司機佩琪:客人上車
模擬器:處理 出租車-2 Time:36,Taxi_Ident:2,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:40,Taxi_Ident:2,Action:司機佩琪:客人上車
模擬器:處理 出租車-1 Time:42,Taxi_Ident:1,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:44,Taxi_Ident:2,Action:司機佩琪:客人下車
模擬器:處理 出租車-1 Time:47,Taxi_Ident:1,Action:司機佩琪:客人上車
模擬器:處理 出租車-2 Time:48,Taxi_Ident:2,Action:司機佩琪:客人上車
模擬器:處理 出租車-1 Time:49,Taxi_Ident:1,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:51,Taxi_Ident:2,Action:司機佩琪:客人下車
模擬器:處理 出租車-1 Time:53,Taxi_Ident:1,Action:司機佩琪:返回車庫
模擬器:處理 出租車-2 Time:55,Taxi_Ident:2,Action:司機佩琪:客人上車
模擬器:處理 出租車-2 Time:65,Taxi_Ident:2,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:70,Taxi_Ident:2,Action:司機佩琪:客人上車
模擬器:處理 出租車-2 Time:80,Taxi_Ident:2,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:84,Taxi_Ident:2,Action:司機佩琪:返回車庫
模擬器:所有事件處理完畢
'''
def main_02():
taxis={
i:taxi_coroutine(i,(i+1)*2,(i+2)*3)
for i in range(3)
}
taxi_simulate=Simulator(taxis)
taxi_simulate.run(20)
'''
執(zhí)行:
main_02() #end_time=20
輸出為:
模擬器:處理 出租車-0Time:6,Taxi_Ident:0,Action:司機佩琪:離開車庫
模擬器:處理 出租車-1 Time:9,Taxi_Ident:1,Action:司機佩琪:離開車庫
模擬器:處理 出租車-2 Time:12,Taxi_Ident:2,Action:司機佩琪:離開車庫
模擬器:處理 出租車-0Time:13,Taxi_Ident:0,Action:司機佩琪:客人上車
模擬器:處理 出租車-0Time:16,Taxi_Ident:0,Action:司機佩琪:客人下車
模擬器:處理 出租車-2 Time:17,Taxi_Ident:2,Action:司機佩琪:客人上車
模擬器:處理 出租車-1 Time:19,Taxi_Ident:1,Action:司機佩琪:客人上車
模擬器:處理 出租車-0Time:19,Taxi_Ident:0,Action:司機佩琪:客人上車
模擬器:處理 出租車-2 Time:24,Taxi_Ident:2,Action:司機佩琪:客人下車
模擬器:超時結束,還有 3 個事件等待處理
'''
03-yield小應用:出租車運營模擬
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
- 文/潘曉璐 我一進店門穷吮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逻翁,“玉大人,你說我怎么就攤上這事捡鱼“嘶兀” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵驾诈,是天一觀的道長缠诅。 經常有香客問我,道長乍迄,這世上最難降的妖魔是什么管引? 我笑而不...
- 文/花漫 我一把揭開白布戏自。 她就那樣靜靜地躺著邦投,像睡著了一般。 火紅的嫁衣襯著肌膚如雪擅笔。 梳的紋絲不亂的頭發(fā)上志衣,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼假勿!你這毒婦竟也來了借嗽?” 一聲冷哼從身側響起,我...
- 正文 年R本政府宣布企量,位于F島的核電站,受9級特大地震影響亡电,放射性物質發(fā)生泄漏届巩。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一份乒、第九天 我趴在偏房一處隱蔽的房頂上張望恕汇。 院中可真熱鬧,春花似錦或辖、人聲如沸瘾英。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽缺谴。三九已至,卻和暖如春耳鸯,著一層夾襖步出監(jiān)牢的瞬間湿蛔,已是汗流浹背。 一陣腳步聲響...
推薦閱讀更多精彩內容
- 下面選了最近十年里乍赫,十位名人所做的畢業(yè)演講瓣蛀。那么多的故事與經歷,其實只想告訴你一件事: 面對迷茫和不確定的未來雷厂,我...