在Python类方法中传递参数

时间:2014-08-30 10:43:43

标签: python

我有两个人群Pop1的N1代理人和Pop2的N2代理人。 SIR感染动力学发生在Pop1和Pop2中。现在,在每个时间步,从Pop1中删除随机选择的代理并添加到Pop2,反之亦然。已删除的代理可能处于S或I或R状态,并在添加到另一个Pop时保留其状态。代码有点冗长所以我把它粘贴在pastebin http://pastebin.com/PdmJTUhs中。

在我的代码' oAgent'是从Pop1或Pop2中删除的随机选择的代理。现在,类方法set_state(self,oAgent)返回oAgent的状态(S = 0或I = 1或R = 2)

def set_state(self, oAgent):
    if SW_SIR.oAgent in self.sAgent:
        return (0)
    if SW_SIR.oAgent in self.iAgent:
        return (1)
    if SW_SIR.oAgent in self.rAgent:
        return (2)

在我的代码类中,Pop1_SW和Pop2_SW分别是Pop1和Pop2的类对象。 Pop1的oAgent状态是在Pop2中添加的代理的状态,反之亦然。现在Pop1_SW应该将state2(它是Pop1的oAgent状态)作为输入参数,Pop2_SW应该得到state1(这是Pop2的oAgent状态)。

所以我的问题是如何为已删除和添加的代理正确分配状态?问题是应该在类oAgent中定义哪些类,以及类的外部如何将其状态作为另一个类对象的输入?

我的代码适用于单个人口的SIR动态。我为两个Populations添加了三个方法set_state(),removedAgents()和addingAgents,这是造成错误的原因。

2 个答案:

答案 0 :(得分:1)

  1. set_state是一个非常糟糕的名字,它没有设置任何东西,get_state更好......
  2. 在你的所有返回参数中,()没有任何目的,对于python程序员来说,它甚至是最糟糕的:乍一看似乎你会返回一个元组,但事实并非如此。
  3. 我认为您应该做一个专门的功能“挑选代理人”,他们选择并删除代理并直接返回索引和状态。

    例如,您可以添加此方法:

    def pick_an_agent(self):
        """Randomly choose an agent, remove it from population and return it
        with it's state."""
    
        agent_id = random.choice(self.sAgent + self.iAgent + self.rAgent)  # Choose directly an existing agent, doesn't care about population size and id range.
        state = self.get_state(agent_id)
        self.removeAgent(agent_id)
        return (agent_id, state)
    

    此函数直接返回代理编号和状态。所以你做了

    agent_id, state = Pop1.pick_an_agent()
    Pop2.addingAgent(agent_id, state)
    

    您将遇到的另一个问题是您使用整数作为使用范围生成的代理的ID。因此,在你的第一个人口N = 20你有代理人的身份编号为0到19,而在你的第二个人口N = 10你有代理人身份编号为0到9.如果你将一个代理人从一个人群移动到另一个人群你就会发生身份冲突!

    因此,您需要使用唯一ID创建代理。为此你可以使用一个计数器并从中获取N元素(在init函数中替换代理=范围(N))

    所以你添加:

    ...
    import itertools
    ...
    
    class SW_SIR:
        agent_id_generator = itertools.count()  # Create a counter starting at 0. It's a class attribute, so all SW_SIR will use the same
    
        def __init__(self, beta, gamma, S, I, m):
            ...
            agents = list(itertools.islice(self.agent_id_generator, N))  # It's get the next N elements of the counter, so you get unique id between agent in using the class SW_SIR
    

答案 1 :(得分:1)

你真的需要存储随机代理吗?我假设你的逻辑是:

  1. 创建两个人口 P P ' ,其大小为 n
  2. 对于每个人口,将成员的随机状态设置为S,I或R中的一个。
  3. 从人口 P P ' 中挑选随机成员并进行交换。
  4. 重复步骤#3一段确定的时间。
  5. 在期限结束后分析S,I或R州的成员。
  6. 在所有这些中,您不需要将随机代理存储在任何地方。你只需要获取它然后交换成员。

    1. 使用 P P ' 填充类。

    2. "传染"你的成员随机获得S,I或R状态。

    3. 创建一个交换成员的方法。它不会返回任何内容,只需对列表进行洗牌,从一个列表弹出并附加到另一个列表。你只需在每个" tick"中调用此函数。你的时间间隔。此方法可能如下所示:

      def cross_pollinate(self):
         random.shuffle(self.pop_a)
         random.shuffle(self.pop_b)
         a = self.pop_a.pop()
         b = self.pop_b.pop()
         self.pop_a.append(b)
         self.pop_b.append(a)