正在请求simpy python中的第一个可用资源

正在请求simpy python中的第一个可用资源,python,python-2.7,simulation,simpy,Python,Python 2.7,Simulation,Simpy,我想创建一个模拟模型,模拟一个有3个计数器的银行。我希望有一个客户队列,如果任何一个柜台可用,它将为柜台服务一段时间。每个柜台都有自己的simpy资源(我无法使用一个容量为3的资源),我需要知道哪个柜台为客户服务。我在实现这一点上遇到了困难 我发现这篇文章似乎是关于同样的问题,但仍然不知道确切的实现 我假设我需要一个yield simpy.AnyOf(env,list_of_resources)来请求第一个可用的计数器,但我不知道如何正确设置,而且如果同时有多个资源可用,我想用某种方法检查一下,

我想创建一个模拟模型,模拟一个有3个计数器的银行。我希望有一个客户队列,如果任何一个柜台可用,它将为柜台服务一段时间。每个柜台都有自己的simpy资源(我无法使用一个容量为3的资源),我需要知道哪个柜台为客户服务。我在实现这一点上遇到了困难

我发现这篇文章似乎是关于同样的问题,但仍然不知道确切的实现

我假设我需要一个yield simpy.AnyOf(env,list_of_resources)来请求第一个可用的计数器,但我不知道如何正确设置,而且如果同时有多个资源可用,我想用某种方法检查一下,以便我可以选择哪个计数器更适合客户

我正在运行python版本2.7,simpy版本3.0.4

编辑添加代码,显示我正在尝试做什么以及它现在如何不工作

import simpy
import random

LENGTH_SIM = 200.0

class Customer(object):
    def __init__(self, arrive_time, num):
        self.arrive_time = arrive_time
        self.start_service_time = -1.0
        self.finish_service_time = -1.0
        self.served_by = -1.0
        self.num = num
    def print_attributes(self):
        format_string = "#%3d  Arrive: %6.1f  Start Service: %6.1f  "\
        + " End Service: %6.1f" + "   Served By: %3d"
        print format_string %(self.num, self.arrive_time,
                              self.start_service_time,
                                self.finish_service_time, self.served_by)

class Counter(object):
    def __init__(self, number):
        self.number = number
        self.name = "Counter " + str(number)
        self.start_times = []
        self.end_times = []

class Bank(object):
    def __init__(self, env, num_counters):
        self.counters = [Counter(x+1) for x in range(num_counters)]
        self.num_counters = num_counters
        self.counters_resources = [simpy.Resource(env, capacity=1)
                                   for x in range(num_counters)]


def generate_customers(env, customers):
    count = 1
    while 1:
        wait_time = random.randint(8, 12)
        yield env.timeout(wait_time)
        customers.append(Customer(env.now, count))
        print "Generated Customer: ", count
        count += 1

def select_counter(env, bank):
    '''choose a counter for the customer'''
    for x in range(len(bank.counters)):
        if bank.counters_resources[len(bank.counters) - 1 - x].count == 0:
            print "Counter Selected: ", len(bank.counters) - 1 - x
            print bank.counters[len(bank.counters) - 1 - x].number
            print bank.counters_resources[len(bank.counters) - 1 - x].users
            return len(bank.counters) - 1 - x
    return -2.0

def gen_service_time():
    return random.random() * 20.0 + 21.0

def handle_customer(env, bank, customer, customers, num_process):
    '''handles customer'''
    print "Process ", num_process, " started at:", env.now
    counter = select_counter(env, bank)
    print "Process ", num_process, " after counter select:", env.now
    if counter != -2.0:
        with bank.counters_resources[counter].request() as req:
            yield req
            print "Process ", num_process, "Time", env.now, "In if"
            bank.counters[counter].start_times.append(env.now)
            service_time = gen_service_time()
            customer.start_service_time = env.now
            customer.finish_service_time = env.now + service_time
            bank.counters[counter].end_times.append(env.now + service_time)
            customer.served_by = counter + 1
            yield env.timeout(service_time)
    else:
        reqs = []
        for x in range(len(bank.counters)):
            reqs.append(bank.counters_resources[x].request())
        counter_used = yield simpy.events.AnyOf(env, reqs)
        for x in range(len(reqs)):
            if counter_used.keys()[0] != reqs[x]:
                print "True"
                bank.counters_resources[x].release(reqs[x])
        print "Process ", num_process, "Time", env.now, "In else"
        bank.counters[0].start_times.append(env.now)
        service_time = gen_service_time()
        customer.start_service_time = env.now
        customer.finish_service_time = env.now + service_time
        bank.counters[0].end_times.append(env.now + service_time)
        customer.served_by = 1
        yield env.timeout(service_time)
        for x in range(len(reqs)):
##            if counter_used.keys()[0] == reqs[x]:
            if 1:
                bank.counters_resources[x].release(reqs[x])




def run_bank(env, bank, customers):
    while 1:
        min_time = -1.0
        min_customer = -1.0
        for x in xrange(len(customers)):
            if customers[x].arrive_time < min_time or min_time == -1.0:
                if customers[x].arrive_time > env.now:
                    min_time = customers[x].arrive_time
                    min_customer = x
                else:
                    continue
        if min_time == -1.0:
            yield env.timeout(LENGTH_SIM - env.now)
        yield env.timeout(min_time - env.now)
        print "Calling Process: ", min_customer, "At time:", env.now
        env.process(handle_customer(env,bank,customers[min_customer],customers,
                                    min_customer + 1))

def run_sim():
    env = simpy.Environment()
    customers = []
    env.process(generate_customers(env, customers))
    env.run(until=LENGTH_SIM)
    env2 = simpy.Environment()
    bank = Bank(env2, 3)
    env2.process(run_bank(env2, bank, customers))
    env2.run(until = LENGTH_SIM)
    for x in range(len(customers)):
        customers[x].print_attributes()

if __name__ == '__main__':
    run_sim()
导入simpy
随机输入
长度=200.0
类别客户(对象):
定义初始值(self,到达时间,num):
self.arrival\u time=到达时间
self.start\u service\u time=-1.0
self.finish\u service\u time=-1.0
self.served_by=-1.0
self.num=num
def打印_属性(自身):
format_string=“#%3d到达:%6.1f启动服务:%6.1f”\
+“结束服务:%6.1f”+“由%3d提供服务”
打印格式\u字符串%(self.num、self.arrival\u时间、,
自启动\服务\时间,
自助完成服务时间,自助服务人)
类计数器(对象):
定义初始化(自身,编号):
self.number=number
self.name=“Counter”+str(编号)
self.start_times=[]
self.end_times=[]
类别库(对象):
定义初始化计数器(自身、环境、数量计数器):
self.counters=[范围内x的计数器(x+1)(num_计数器)]
self.num\u计数器=num\u计数器
self.counters\u resources=[simpy.Resource(环境,容量=1)
对于范围内的x(计数器数量)]
def生成_客户(环境、客户):
计数=1
而1:
wait_time=random.randint(8,12)
产量环境超时(等待时间)
customers.append(Customer(env.now,count))
打印“生成的客户:”,计数
计数+=1
def选择_计数器(环境、银行):
''为客户选择一个柜台''
对于范围内的x(长度(银行柜台)):
如果bank.counters\u资源[len(bank.counters)-1-x].count==0:
打印“所选计数器:”,len(银行计数器)-1-x
打印bank.counters[len(bank.counters)-1-x]。编号
打印bank.counters\u资源[len(bank.counters)-1-x]。用户
返回长度(银行柜台)-1-x
返回-2.0
def gen_服务时间():
返回random.random()*20.0+21.0
def处理客户(环境、银行、客户、客户、数量流程):
“处理客户”
打印“进程”,num_进程,开始于:,env.now
计数器=选择计数器(环境、银行)
在计数器选择:,env.now之后打印“进程”,num_进程
如果计数器!=-2.0:
使用bank.counters\u资源[counter].request()作为请求:
产量需求
打印“进程”,num_进程,“时间”,env.now,“如果”
bank.counters[counter].start\u times.append(env.now)
服务时间=发电服务时间()
customer.start\u service\u time=env.now
customer.finish\u service\u time=env.now+service\u time
bank.counters[counter].end\u times.append(env.now+service\u time)
customer.served_by=柜台+1
产量环境超时(服务时间)
其他:
需求=[]
对于范围内的x(长度(银行柜台)):
请求追加(银行计数器资源[x].request())
使用的计数器=产生简单事件任意(环境、需求)
对于范围内的x(透镜(要求)):
如果使用计数器_。键()[0]!=需求[x]:
打印“真”
bank.counters\u资源[x].发布(需求[x])
打印“进程”,num_进程,“时间”,env.now,“以其他方式”
bank.counters[0]。开始\u次。追加(env.now)
服务时间=发电服务时间()
customer.start\u service\u time=env.now
customer.finish\u service\u time=env.now+service\u time
bank.counters[0]。结束时间。追加(env.now+服务时间)
customer.served_by=1
产量环境超时(服务时间)
对于范围内的x(透镜(要求)):
##如果使用了计数器,则.keys()[0]==reqs[x]:
如果1:
bank.counters\u资源[x].发布(需求[x])
def运行银行(环境、银行、客户):
而1:
最小时间=-1.0
最小客户=-1.0
对于x范围内的x(len(客户)):
如果客户[x]。到达时间环境现在:
最小时间=客户[x]。到达时间
最小客户=x
其他:
持续
如果最小时间==-1.0:
屈服环境超时(长度\u SIM-env.now)
产生环境超时(最小时间-环境现在)
打印“呼叫流程:”,min_客户,“时间:”,env.now
环境流程(处理客户(环境、银行、客户[最小客户]、客户、,
最小(客户+1))
def run_sim():
env=simpy.Environment()
客户=[]
环境流程(生成_客户(环境,客户))
环境运行(直到=长度)
env2=simpy.Environment()
银行=银行(环境2,3)
环境2.流程(运行银行(环境2、银行、客户))
env2.运行(直到=长度\u SIM)
对于范围内的x(len(客户)):
客户[x]。打印属性()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
运行_sim()

如果你真的不能使用一个容量为3的普通资源,他可能会
import simpy


class Counter:
    usages = 0


def customer(env, counters):
    counter = yield counters.get()
    yield env.timeout(1)
    counter.usages += 1
    yield counters.put(counter)


env = simpy.Environment()
counters = simpy.Store(env, capacity=3)
counters.items = [Counter() for i in range(counters.capacity)]
for i in range(10):
    env.process(customer(env, counters))
env.run()
for counter in counters.items:
    print(counter.usages)
import simpy
import random

LENGTH_SIM = 100.0

class Customer(object):
    def __init__(self, arrive_time, num):
        self.arrive_time = arrive_time
        self.start_service_time = -1.0
        self.finish_service_time = -1.0
        self.served_by = -1.0
        self.num = num
    def print_attributes(self):
        format_string = "#%3d  Arrive: %6.1f  Start Service: %6.1f  "\
        + " End Service: %6.1f" + "   Served By: %3d"
        print format_string %(self.num, self.arrive_time,
                              self.start_service_time,
                                self.finish_service_time, self.served_by)

class Counter(object):
    def __init__(self, number):
        self.number = number
        self.name = "Counter " + str(number)
        self.start_times = []
        self.end_times = []

class Bank(object):
    def __init__(self, env, num_counters):
        self.counters = [Counter(x+1) for x in range(num_counters)]
        self.num_counters = num_counters
        self.counters_resources = [simpy.Resource(env, capacity=1)
                                   for x in range(num_counters)]


def generate_customers(env, customers):
    count = 1
    while 1:
##        wait_time = random.randint(8, 12)
        wait_time = 2
        yield env.timeout(wait_time)
        customers.append(Customer(env.now, count))
        print "Generated Customer: ", count
        count += 1

def select_counter(env, bank):
    '''choose a counter for the customer'''
    for x in range(len(bank.counters)):
        if bank.counters_resources[len(bank.counters) - 1 - x].count == 0 and\
        bank.counters_resources[len(bank.counters) - 1 - x].queue == []:
            print "Counter Selected: ", len(bank.counters) - 1 - x
            return len(bank.counters) - 1 - x
    return -2.0

def gen_service_time():
##    return random.random() * 20.0 + 19.0
    return random.randint(4, 8)

def wait_til_available(env, bank, temp_list):
    while 1:
        yield env.timeout(0.0001)
        for x in range(len(bank.counters)):
            if bank.counters_resources[x].count == 0:
                req = bank.counters_resources[x].request()
                temp_list[0] = x
                temp_list[1] = req
                return 

def handle_customer(env, bank, customer, customers, num_process):
    '''handles customer'''
    print "Process ", num_process, " started at:", env.now
    counter = select_counter(env, bank)
    if counter != -2.0:
        with bank.counters_resources[counter].request() as req:
            yield req
            bank.counters[counter].start_times.append(env.now)
            service_time = gen_service_time()
            customer.start_service_time = env.now
            customer.finish_service_time = env.now + service_time
            bank.counters[counter].end_times.append(env.now + service_time)
            customer.served_by = counter + 1
            yield env.timeout(service_time)
    else:
        reqs = []
        got_counter = 0
        for x in range(len(bank.counters)):
            reqs.append(bank.counters_resources[x].request())
        good_req = yield simpy.events.AnyOf(env, reqs)
        req = good_req.keys()[0]
        for x in range(len(bank.counters)):
            if req != reqs[x]:
                bank.counters_resources[x].release(reqs[x])
                reqs[x].cancel(None, None, None)
            else:
                got_counter = x
        bank.counters[got_counter].start_times.append(env.now)
        service_time = gen_service_time()
        customer.start_service_time = env.now
        customer.finish_service_time = env.now + service_time
        bank.counters[got_counter].end_times.append(env.now + service_time)
        customer.served_by = got_counter + 1
        yield env.timeout(service_time)
        print "Process ", num_process, " finished at:", env.now
        bank.counters_resources[got_counter].release(req)




def run_bank(env, bank, customers):
    while 1:
        min_time = -1.0
        min_customer = -1.0
        for x in xrange(len(customers)):
            if customers[x].arrive_time < min_time or min_time == -1.0:
                if customers[x].arrive_time > env.now:
                    min_time = customers[x].arrive_time
                    min_customer = x
                else:
                    continue
        if min_time == -1.0:
            yield env.timeout(LENGTH_SIM - env.now)
        yield env.timeout(min_time - env.now)
        print "Calling Process: ", min_customer+1, "At time:", env.now
        env.process(handle_customer(env,bank,customers[min_customer],customers,
                                    min_customer + 1))

def run_sim():
    env = simpy.Environment()
    customers = []
    env.process(generate_customers(env, customers))
    env.run(until=LENGTH_SIM)
    env2 = simpy.Environment()
    bank = Bank(env2, 3)
    env2.process(run_bank(env2, bank, customers))
    env2.run(until = LENGTH_SIM)
    for x in range(len(customers)):
        customers[x].print_attributes()

if __name__ == '__main__':
    run_sim()