【问题标题】:How do I make Simpy simulation to depict a markovian M/M/1 process?如何进行 Simpy 模拟来描绘马尔可夫 M/M/1 过程?
【发布时间】:2021-03-19 02:58:43
【问题描述】:

output printing the len of arrival and service times我正在尝试使用 simpy 实现具有指数间到达和指数服务时间的 M/M/1 马尔可夫过程。代码运行良好,但我没有得到预期的结果。代码运行后到达时间的列表项数也小于服务时间的列表项数。

# make a markovian queue
# make a server as a resource
# make customers at random times
# record the customer arrival time
# customer gets the resource
# record when the customer got the resource
# serve the customers for a random time using resource
# save this random time as service time
# customer yields the resource and next is served

import statistics
import simpy
import random


arrival_time = []
service_time = []
mean_service = 2.0
mean_arrival = 1.0
num_servers = 1

class Markovian(object):
    def __init__(self, env, num_servers):
        self.env = env
        self.servers  = simpy.Resource(env, num_servers)
        #self.action = env.process(self.run())
    def server(self,packet ):
        #timeout after random service time
        t = random.expovariate(1.0/mean_service)
        #service_time.append(t)
        yield self.env.timeout(t)
    
    def getting_service(env, packet, markovian):
        # new packet arrives in the system
        arrival_time = env.now
        with markovian.servers.request() as req:
            yield req
            yield env.process(markovian.server(packet))
        service_time.append(env.now - arrival_time)
    
    def run_markovian(env,num_servers):
        markovian = Markovian(env,num_servers)
        packet = 0
        #generate new packets
        while True:
            t = random.expovariate(1.0/mean_arrival)
            arrival_time.append(t)
            yield env.timeout(t)
            packet +=1
            env.process(Markovian.getting_service(env,packet,markovian))

    def get_average_service_time(service_time):
        average_service_time = statistics.mean(service_time)
        return average_service_time
    
def main():
    random.seed(42)

    env= simpy.Environment()
    env.process(Markovian.run_markovian(env,num_servers))
    env.run(until = 50)
    print(Markovian.get_average_service_time(service_time))
    print (arrival_time)
    print (service_time)
    

    
if __name__ == "__main__":
    main()

【问题讨论】:

  • “我没有得到预期的结果。”以什么方式?例如,如果您期望获得理论稳态均值(请参阅homepages.cae.wisc.edu/~ie642/content/Techniques/Warmup/… 以获取解释),那么您的期望很可能偏离了。
  • 不需要 Simpy。但我想好好学习如何使用它,因为我可以将它用于 M/M/K 服务器以及可以打开和关闭客户的服务器。此外,我没有得到预期的结果,正如您从这个屏幕截图中看到的那样,到达时间的长度大于服务时间的长度。
  • 您是否尝试通过搜索“simpy m/m/1 示例”将您的实现与在线提供的众多实现之一进行比较?

标签: queue simulation simpy markov-models


【解决方案1】:

您好,您的代码中基本上存在一个错误和两个排队论的误解:

错误 1) 服务器的定义在类中,这使得模型表现为 M/M/inf 而不是 M/M/1

回答:我把你的资源的定义放到class里面,从现在开始传递servers而不是num_servers。

误解 1:按照您定义的时间:

mean_service = 2.0 mean_arrival = 1.0

系统将生成更多的数据包并且能够提供服务。这就是列表大小如此不同的原因。

回答: 平均服务 = 1.0 mean_arrival = 2.0

误解2:

您在代码中所说的服务时间实际上是系统时间。

我还在您的代码中添加了一些打印内容,以便我们可以看到这样做的效果。随意评论他们。而且库Statistics也不需要,所以我也评论了。

希望这个回答对你有用。

# make a markovian queue
# make a server as a resource
# make customers at random times
# record the customer arrival time
# customer gets the resource
# record when the customer got the resource
# serve the customers for a random time using resource
# save this random time as service time
# customer yields the resource and next is served

#import statistics
import simpy
import random


arrivals_time = []
service_time = []
waiting_time = []

mean_service = 1.0
mean_arrival = 2.0
num_servers = 1

class Markovian(object):
    def __init__(self, env, servers):
        self.env = env
        #self.action = env.process(self.run())

    #def server(self,packet ):
        #timeout after random service time
     #   t = random.expovariate(1.0/mean_service)
        #service_time.append(t)
      #  yield self.env.timeout(t)
    
    def getting_service(env, packet, servers):
        # new packet arrives in the system

        begin_wait = env.now
        req = servers.request()
        yield req
        
        begin_service = env.now
        waiting_time.append(begin_service - begin_wait)

        print('%.1f Begin Service of packet %d' % (begin_service, packet))
        
        yield env.timeout(random.expovariate(1.0/mean_service))
        
        service_time.append(env.now - begin_service)

        yield servers.release(req)
        print('%.1f End Service of packet %d' % (env.now, packet))

    
    def run_markovian(env,servers):
        markovian = Markovian(env,servers)
        packet = 0
        #generate new packets
        while True:
            t = random.expovariate(1.0/mean_arrival)
            yield env.timeout(t)
            arrivals_time.append(t)
            packet +=1
            print('%.1f Arrival of packet %d' % (env.now, packet))

            env.process(Markovian.getting_service(env,packet,servers))


    def get_average_service_time(service_time):
        average_service_time = statistics.mean(service_time)
        return average_service_time
    
def main():
    random.seed(42)

    env= simpy.Environment()
    servers  = simpy.Resource(env, num_servers)

    env.process(Markovian.run_markovian(env,servers))
    env.run(until = 50)
    
    print(Markovian.get_average_service_time(service_time))
    print ("Time between consecutive arrivals \n", arrivals_time)
    print("Size: ", len(arrivals_time))
    print ("Service Times \n", service_time)
    print("Size: ", len(service_time))
    print ("Waiting Times \n", service_time)
    print (waiting_time)
    print("Size: ",len(waiting_time))


    
if __name__ == "__main__":
    main()

【讨论】:

    猜你喜欢
    • 2022-08-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 2019-09-14
    相关资源
    最近更新 更多