简体   繁体   English

在Python类方法中传递参数

[英]Passing arguments in Python Class method

I have two populations Pop1 of N1 agents and Pop2 of N2 agents. 我有两个人口N1代理人Pop1和N2代理人Pop2。 SIR Infection dynamics is taking place within Pop1 and Pop2. SIR感染动态发生在Pop1和Pop2中。 Now at each time step, a randomly chosen agent is removed from Pop1 and added to Pop2 and vice versa. 现在,在每个时间步骤中,都会从Pop1中删除随机选择的代理,并将其添加到Pop2中,反之亦然。 Removed agent could be in S or I or R state and it preserves its state when added to another Pop. 删除的代理可能处于S或I或R状态,并且在添加到另一个Pop时会保留其状态。 The code is bit lengthy so I i pasted it in pastebin http://pastebin.com/PdmJTUhs . 代码有点长,所以我将其粘贴到pastebin http://pastebin.com/PdmJTUhs中

In my code 'oAgent' is the randomly chosen agent which is being removed from Pop1 or Pop2. 在我的代码中,“ oAgent”是从Pop1或Pop2中删除的随机选择的代理。 Now the state (S=0 or I=1 or R=2) of oAgent is returned by class method set_state(self, oAgent) 现在,通过类方法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)

In my code class Pop1_SW and Pop2_SW are class objects for Pop1 and Pop2 respectively. 在我的代码类Pop1_SW和Pop2_SW分别是Pop1和Pop2的类对象。 The state of oAgent of Pop1 is the state of the agent which is being added in Pop2, and vice versa. Pop1的oAgent状态是正在Pop2中添加的代理的状态,反之亦然。 Now Pop1_SW should get state2(which is state of oAgent of Pop1) as an input parameter, and Pop2_SW should get state1(which is state of oAgent of Pop2). 现在Pop1_SW应该获取state2(它是Pop1的oAgent的状态)作为输入参数,而Pop2_SW应该获取state1(它是Pop2的oAgent的状态)。

So my question is how can I assign properly the state for the removed and added agents ? 所以我的问题是如何为已删除和已添加代理正确分配状态? Problem is where inside the class oAgent should be defined and how outside the class its state should be the input for another class object ? 问题是应该在类oAgent的内部定义什么地方,以及在其外部的状态应如何作为另一个类对象的输入?

My code runs fine for a SIR dynamics for a single Population. 对于单个“人口”的SIR动态,我的代码运行良好。 I have added three methods set_state(), removingAgents() and addingAgents for two Populations, which are the cause of error. 我为两个填充添加了三个方法set_state(),removeingAgents()和addingAgents,这是导致错误的原因。

  1. set_state is a really bad name, it does'nt set anything, get_state better... set_state是一个非常糟糕的名字,它什么也没设置,get_state更好...
  2. in all your return parameter the () have no purpose, for a python programmer it's even worst: at first glance it's seems you will return a tuple but it's not. 在所有的return参数中,()毫无用处,对于python程序员来说,这甚至更糟:乍一看,似乎您将返回一个元组,但事实并非如此。

I think you should probably do a dedicate function "pick an agent" who choose and remove an agent and return you directly the index and the state. 我认为您可能应该执行一个专用功能“选择一个代理”,该功能选择并删除一个代理,然后直接向您返回索引和状态。

For exemple you add this method: 例如,您添加以下方法:

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)

This function return directly the agent number and the state. 此函数直接返回座席号和状态。 So you do 所以你也是

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

The other problem you will have is the fact you use an integer as id for your agent generated using range. 您将遇到的另一个问题是,您使用整数作为使用范围生成的代理的ID。 So in you first population N=20 you have agent with id 0 to 19, and in you second population N=10 you have agent with id 0 to 9. If you move an agent from one population to the other you have id collision ! 因此,在您的第一个种群N = 20中,您的ID为0到19,在第二个种群N = 10中,您的ID为0到9。

So you need to create your agent with unique id. 因此,您需要创建具有唯一ID的代理。 For this you can use a counter and get N element from it (replace the agents = range(N) in your init function) 为此,您可以使用计数器并从中获取N元素(在init函数中替换agent = range(N))

So you add: 因此,您添加:

...
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

Do you really need the random agent stored? 您是否真的需要存储随机代理? I assume your logic is: 我认为您的逻辑是:

  1. Create two populations P and P ' of size n . 创建大小为n的两个总体PP '
  2. For each population, set at random state of member to one of S, I or R. 对于每个种群,将成员的随机状态设置为S,I或R中的一个。
  3. Pick random member from population P and P ' and swap them. 从总体PP '中选择随机成员并交换它们。
  4. Repeat step #3 for a determined time period. 在确定的时间段内重复步骤3。
  5. Analyze members for S, I or R state after period is finished. 周期结束后,分析成员的S,I或R状态。

In all of that, you don't need to store the random agent anywhere. 总之,您无需将随机代理存储在任何地方。 You just need to fetch it and then swap the members around. 您只需要获取它,然后交换成员即可。

  1. Initialize the class with populations P and P ' . 用种群PP '初始化班级。

  2. "Infect" your members with state of S, I or R at random. 随机以S,I或R状态“感染”您的成员。

  3. Create a method that swaps members. 创建一个交换成员的方法。 It doesn't return anything, simply shuffles the lists, pops from one and appends to the other. 它不返回任何内容,只是随机排列列表,从一个列表弹出,然后追加到另一个列表。 You simply call this function at each "tick" of your time interval. 您只需在时间间隔的每个“滴答”中调用此函数。 This method could look like: 此方法可能类似于:

     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) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM