为什么我的嵌套循环重复相同的数据 and/or 没有附加我想要的所有内容?

Why does my nested loop repeat the same data and/or doesn't append all the things I want it to?

所以我正在尝试模拟动物狩猎和休息。当动物休息时,它可以根据概率消化或保持不变。当动物正在狩猎时,它可以根据概率选择成功与否或保持不变。我希望外部嵌套循环是动物的数量,内部循环是寿命。当动物休息时,动物的肠道限制较低,如果达到该水平,它会自动开始捕食。这种动物在狩猎期间也有一个上肠水平,当它到达它时它会休息。此外,如果动物达到负面状态,它就会跳出循环并继续下一个动物。

我正在尝试 运行 嵌套循环,但我不明白哪里出了问题!请帮我!我注意到当我打印 alist 并查看状态时,会出现从 [0,4,i] 到 [1,2,i] 的奇怪跳跃,它只是跳过了 4-1 的腹部! 所以我想从一个初始状态开始,然后在满足条件时附加列表然后,我试图说如果腹部达到负数我想记录那个状态然后爆发并从下一个动物开始。

我还需要计算动物狩猎成功的次数,狩猎失败的次数,腹部消化的次数,以及动物保持不变的次数。我还没有走到这一步

提前致谢! 对不起,如果它令人困惑!我不太擅长 python 这是我的代码:

import random
initial_state=[0,4,0]#means it is resting, at full belly of 4 these two values also vary 
alist=[initial_state]
died=0
u,s=2,4 #u is the lower belly limit, s is the upper belly limit
a,b,d=1/8,1/3,1/2 #a is the probability for not catching food, b is the probability for getting food,d is the probability for digestion these values also vary 
for i in range (100000):
    digest=random.random()
    hunts=random.random()
    for i in range(1,501):#each animal has a 500 lifespan
        digest=random.random()
        hunts=random.random()
        if alist[i-1][1]==-1:
            died+=1
            break #the animal died
        if alist[i-1][0]==0:#If the animal is resting
            if digest<=d:
                belly=alist[i-1][1]-1
                if belly <= u:
                    alist.append([1,belly,i])
                else:
                    alist.append([0,belly,i])
            if digest>1-d:#the animal remains the same 
                belly=alist[i-1][1]
                alist.append([0,belly,i])
        if alist[i-1][0]==1:#if the animal is hunting
            if alist[i-1][1]>=1:
                if hunts<=a:
                    belly=alist[i-1][1]-1
                    alist.append([1,belly,i])
                if a<hunts<=a+b:
                    belly=alist[i-1][1]+1
                    if belly==s:#if the animal has a full belly it rests
                        alist.append([0,belly,i])
                    else:
                        alist.append([1,belly,i])
                if hunts>a+b:
                    belly=alist[i-1][1]
                    alist.append([alist[i-1][0],belly,i])
            elif alist[i-1][1]==0:#When the belly is empty while hunting
                if hunts<=a:
                    belly=alist[i-1][1]-1
                    alist.append([0,belly,i])
                if a<hunts<=a+b:
                    belly=alist[i-1][1]+1
                    alist.append([1,belly,i])
                if hunts>a+b:
                    belly=alist[i-1][1]
                    alist.append([alist[i-1][0],belly,i])

标题

我大量重构了您的代码。变化包括:

  • 重命名所有内容,以便我们可以更清楚地看到变量实际代表什么。
  • 去掉alist[i-1]因为我们一直在看之前的状态,-1索引就足够了。
  • 尽可能多地检查腹部和狩猎状态,以避免重复提及 alist
  • 不再存储 i 因为如果我们需要它我们可以使用 enumerate.
  • 修正了概率(你的check太多了,定义ab的时候a + b != 1分别是没抓到和抓到食物的概率。

测试了几次,我没有注意到你在评论中提到的腹部水平跳跃。


# Imports.
import random

# Constants.
ANIMALS = 3
ANIMAL_LIFESPAN = 30
BELLY_EMPTY = 2 # Will always trigger a hunt next cycle.
BELLY_FULL = 4  # Will always trigger a rest next cycle.
FOOD_CATCHING_PROBABILITY = 1/3
DIGESTION_PROBABILITY = 1/2
INITIAL_STATE = (False, BELLY_FULL) # The animal starts in resting position with a full belly.

# Run the simulation.
animals_states = {} # I use a dict here to save myself some `append`s.
death_counter = 0

for n in range(ANIMALS):
    states = animals_states[n] = [INITIAL_STATE]

    for _ in range(ANIMAL_LIFESPAN):
        # Grab previous states.
        is_hunting, belly = states[-1]

        if is_hunting:
            if random.random() <= FOOD_CATCHING_PROBABILITY:
                belly += 1
                hunt_next = False if belly == BELLY_FULL else True # Full belly is triggering a rest on the next cycle.
            else:
                belly -= 1
                hunt_next = True

        else: # If the animal is resting.
            if random.random() <= DIGESTION_PROBABILITY:
                belly -= 1
                hunt_next = True if belly <= BELLY_EMPTY else False # Empty belly is triggering a hunt on the next cycle.
            else: # The animal remains the same.
                hunt_next = False

        states.append((hunt_next, belly))

        # The animal starved.
        if belly == 0:
            death_counter += 1
            break



# For testing purpose.
for n, states in animals_states.items():
    print(f"\nAnimal {n} states:")
    for is_hunting, belly in states:
        print(is_hunting, belly)

输出:

Animal 0 states:
False 4
False 4
False 3
True 2
True 1
True 2
True 1
True 0

Animal 1 states:
False 4
False 4
False 4
False 3
False 3
True 2
True 1
True 2
True 1
True 0

Animal 2 states:
False 4
False 4
False 3
True 2
True 1
True 0
True 1
True 0