【发布时间】:2021-07-28 21:06:24
【问题描述】:
我试图了解如何收集用于计算资源使用的数据,例如排队等候的平均客户数量。我查看了以下链接中的文档,但这对我来说太多了。我正在寻找一个如何使用它以及如何计算基于时间的平均线长度的示例。我感谢任何指导。
https://simpy.readthedocs.io/en/latest/topical_guides/monitoring.html#monitoring-your-processes
【问题讨论】:
我试图了解如何收集用于计算资源使用的数据,例如排队等候的平均客户数量。我查看了以下链接中的文档,但这对我来说太多了。我正在寻找一个如何使用它以及如何计算基于时间的平均线长度的示例。我感谢任何指导。
https://simpy.readthedocs.io/en/latest/topical_guides/monitoring.html#monitoring-your-processes
【问题讨论】:
资源没有利用率日志。您需要自己收集。 Monkey patching 是一种使用代码包装资源请求以收集统计信息的方法,而无需更改调用资源请求的方式。一种更简单的方法是只制作一个记录器,然后在需要的地方添加一个日志调用。这就是我在示例中的做法。缺点是您必须记住在需要时添加日志记录代码。
简单资源具有以下属性用于收集统计信息:容量、计数(拥有资源的用户数、用户(拥有资源的用户列表)、队列(待处理的资源请求列表)
"""
A quick example on how to get average line length
using a custom logger class
programmer: Michael R. Gibbs
"""
import simpy
import numpy as np
import pandas as pd
class LineLogger():
"""
logs the size of a resource line
"""
def __init__(self, env):
self.env = env
# the log
self.samples_df = pd.DataFrame(columns=['time','len'])
def log(self, time, len):
"""
log a time and length of the resoure request queue
time: time the messure is taken
len: length of the queue
"""
self.samples_df = self.samples_df.append({'time':time,'len':len},ignore_index=True)
def get_ave_line(self):
"""
finds the time weighted average of the queue length
"""
# use the next row to figure out how long the queue was at that length
self.samples_df['time_span'] = self.samples_df['time'].shift(-1) - self.samples_df['time']
# drop the last row because it would have a infinate time span
trimed_samples_df = self.samples_df[0:-1]
ave = np.average(trimed_samples_df['len'], weights=trimed_samples_df['time_span'])
return ave
def task(env, res, line_logger):
"""
A simple task that grabs a resouce for a bit of time
"""
with res.request() as req: # Generate a request event
# requester enters queue for resouce
line_logger.log(env.now,len(res.queue))
yield req
# requester got a resource and leaves requeuest queue
# if the resource was available when the request was made, then time in queue will be 0
line_logger.log(env.now,len(res.queue))
# keep resource to build a queue
yield env.timeout(3.5)
def gen_tasks(env, res, line_logger):
"""
generates 5 tasks to seize a resource
building a queue over time
"""
for i in range(5):
env.process(task(env,res,line_logger))
# put some time between requests
yield env.timeout(1)
if __name__ == '__main__':
env = simpy.Environment()
res = simpy.Resource(env, capacity=1)
line_logger = LineLogger(env)
env.process(gen_tasks(env,res,line_logger))
env.run(100)
print("finish sim")
print("average queue length is: ",line_logger.get_ave_line())
print()
print("log data")
print(line_logger.samples_df)
print()
print("done")
【讨论】: