隨機程序模擬(一)

程式碼

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

# -*- coding: utf-8 -*-import simpyimport numpy# 物件處理服務紀錄 historyService = {} # 服務站/機具數量/服務時間長度class ServiceStation(object): def __init__(self, env, num_machines, service_time): self.env = env self.machine = simpy.Resource(env, num_machines) self.service_time = service_time def __process__(self, weight): return weight * self.service_time def service(self, nameItem): # 該物件處理服務紀錄 record = historyService[nameItem] # 機具處理時間 yield self.env.timeout(self.__process__(record['weight'])) # 隨機產生處理結果 record['result'] = numpy.random.randint(50, 99) # 模擬處理物件class SimItems: def __init__(self, env, params): self.env = env self.params = params # 物件請求機具處理 def ProcessItem(self, nameItem, serviceStation): # 該物件處理服務紀錄 record = historyService[nameItem] # 物件到達時間 record['arrival'] = self.env.now # 物件請求機具資源成功 with serviceStation.machine.request() as request: yield request # 物件開始處理時間 record['start'] = self.env.now # 觸發機具服務 yield env.process(serviceStation.service(nameItem)) # 物件處理結束時間 record['end'] = self.env.now def __NewItem__(self, nameItem): if nameItem not in historyService: historyService[nameItem] = { 'weight': numpy.random.randint(5) + 1, 'arrival': 0.0, 'start': 0.0, 'end': 0.0, 'result': 0 } def Setup(self): # 備妥機具 serviceStation = ServiceStation( self.env, self.params['NUM_MACHINES'], self.params['PROCESS_TIME']) # 期初待處理物件 id_Item = 0 for id_Item in range(0, self.params['NUM_INITIAL_ITEMS']): name_Item = '%03d' % (id_Item) self.__NewItem__(name_Item) # 觸發機具處理新物件 env.process(self.ProcessItem(name_Item, serviceStation)) while True: # 物件等候處理所需之間隔時間 yield env.timeout( numpy.random.randint( self.params['NEW_ITEM_INTERVAL'] - 2, self.params['NEW_ITEM_INTERVAL'] + 2)) # 待處理之新物件 id_Item += 1 name_Item = '%03d' % id_Item self.__NewItem__(name_Item) # 觸發機具處理新物件 env.process(self.ProcessItem(name_Item, serviceStation)) def ShowHistory(self): # 列舉所有處理物件 for name_item in sorted(historyService.keys()): # 該物件處理服務紀錄 record = historyService[name_item] print u'物件-%s\t權重=%2d' % (name_item, record['weight']), print u'\t到達=%4.0f\t開始=%4.0f' % ( record['arrival'], record['start'] ), if record['result'] == 0: print u'\t服務終了' else: print u'\t結束=%4.0f\t已處理=%3d%%' % ( record['end'], record['result']) def ShowCSV(self): print "Item,Weight,Arrival,Start,End,Result" # 列舉所有處理物件 for name_item in sorted(historyService.keys()): # 該物件處理服務紀錄 record = historyService[name_item] print u'物件-%s,%d,' % (name_item, record['weight']), print u'%.0f,%.0f,' % ( record['arrival'], record['start'] ), print u'%.0f,%.2f' % ( record['end'], record['result']*0.01) # 主程式if __name__ == '__main__': # 重設亂數因子 numpy.random.seed(numpy.random.randint(50) + 1) # 設置模擬程序參數 params = { 'NUM_INITIAL_ITEMS': numpy.random.randint(8) + 1, 'NUM_MACHINES': numpy.random.randint(4) + 1, 'PROCESS_TIME': numpy.random.randint(10) + 1, 'NEW_ITEM_INTERVAL': numpy.random.randint(10) + 4, 'SIMULATION_TIME': 500 } # 模擬環境 env = simpy.Environment() # 模擬程序物件 simItems = SimItems(env, params) # 設置模擬程序 env.process(simItems.Setup()) # 啟動模擬 env.run(until=params['SIMULATION_TIME']) # 輸出模擬結果 simItems.ShowHistory()