【问题标题】:Can I use simpy to do agent-based simulation?我可以使用 simpy 进行基于代理的模拟吗?
【发布时间】:2021-07-14 15:15:27
【问题描述】:

我知道 simpy 是一个基于过程的离散事件模拟框架。我有几个代理可能同时做不同的事情。我仍然可以使用 simpy 来模拟我的代理吗?例如,一辆汽车到达停车场。那么驱动程序就存在了。走到一个购物中心的入口处,进入。一些购物者可能会同时离开。也可以有几辆汽车同时到达停车场。当一个事件触发时,该事件使用env.timeout(time) 时间来执行。但是,这会增加环境的模拟时钟。因此,对于所有代理?有没有办法模拟这种情况?你能给我推荐一个模拟框架/库来模拟这种场景吗?

根据@Michael 的回答进行编辑:我确实使用env.process 启动了代理(两种代理)。这些进程中的 While 循环函数产生 env.timeout 用于代理创建,并且还使用 env.process(foo(A,B,C)) 创建新进程。在这些进程中,我有几个yield env.process。在它们里面又有一些yield env.process。我在后面的函数中使用yield,因为代理必须等待事件完成。所有代理都在使用一些共享资源和存储或等待一些代理到达。不同类型的代理之间也存在一些关联。因此,我使用外部字典来存储有关代理、资源和商店的所有信息。我得到了一些有趣的结果,让我想到我是否使用正确的库或代码结构来实现我想做的事情。阅读@Michael的回答后,我相信我走在正确的轨道上。我可以启动多个代理创建进程,它们可以同时工作。

【问题讨论】:

    标签: python simulation agent-based-modeling simpy event-simulation


    【解决方案1】:

    是的

    env.timeout 不会提前时钟。 当一个代理调用 env.timeout 时,该代理会一直等到时钟到达那个时间,它不会阻止其他代理做事。当第一个代理等待 env.timeout 完成时,其他代理仍然可以执行操作。

    请注意,每个代理都需要使用 env.process 异步启动,而不是使用 yield

    这是一个不太简单的例子

    """
    agents calling each other in a agent base sim
    
    Programmer Michael R. Gibbs
    """
    
    import simpy
    import random
    
    class Agent():
        """
        Agents do a background activity, and from time to time make a call to a friend agent
        Agents wait to finish doing stuff, then call back the calling friend agent
        """
    
        def __init__(self, env, agent_id):
            """
            set up agent
    
            Need to set the friend later since that agent may not have been created yet
            """
    
            self.env = env
            self.agent_id = agent_id
            self.friend = None          # set this before starting sim
            self.friend_called = None
    
            # kick off background activity, and activty that makes calls from time to time
            env.process(self.agent_stuff())
            env.process(self.make_call())
        
        def receive_call(self, agent):
            """
            agent is busy, will call back later
            """
    
            # save caller for later callback
            self.friend_called = agent
            print(f"{self.env.now} agent {self.agent_id} just got a call from agent {agent.agent_id}")
    
        def receive_callback(self, agent):
            """
            getting a call from the agent this agent called ealier
            """
            print(f"{self.env.now} agent {self.agent_id} just got a callback from agent {agent.agent_id}")
    
        def make_call(self):
            """
            loop making calls from time to time
            """
            while True:
                yield self.env.timeout(random.randint(4,9))
                self.friend.receive_call(self)
                print(f"{self.env.now} agent {self.agent_id} just made a call to agent {self.friend.agent_id}")
    
        def agent_stuff(self):
            """
            agent process doing agent stuff
            """
            while True:
                t = random.randint(1,5)
                print(f"{self.env.now} agent {self.agent_id} will do his thing in {t}")
                yield env.timeout(t)
                print(f"{self.env.now} agent {self.agent_id} is doing his thing")
    
                if self.friend_called is not None:
                    # oh look, someone called, call them back
                    self.friend_called.receive_callback(self)
                    print(f"{self.env.now} agent {self.agent_id} just made a call to agent {self.friend.agent_id}")
                    self.friend_called = None
    
    env = simpy.Environment()
    
    # create agents, which also starts their processes
    agent1 = Agent(env,1)
    agent2 = Agent(env,2)
    
    # set the friend
    agent1.friend = agent2
    agent2.friend = agent1
    
    env.run(100)
    

    【讨论】:

    • 很好的回答迈克尔。谢谢。我的情况比我上面解释的要复杂。所以,我想确定一下。由于stackoverflow不允许我写超过几百个字符,所以我编辑了这个问题。
    • 升级了代理代码示例,以便代理相互调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多