首页 > 解决方案 > 在不使用循环的情况下在 python 中尝试扩散受限聚合模拟

问题描述

大约一年前,我尝试(并成功)在 python 中进行了第一次真正的模拟,这是模拟扩散受限聚合(有时称为布朗树)。原理如下:

有 N 个随机移动的粒子和 1 个吸积(不移动)的粒子。每当一个粒子接触到吸积的粒子时,它就会停止(它吸积)。

一年前,我使用了很多循环来做到这一点,现在我知道如果我一直使用数组,代码会运行得更快,所以我重新编写了代码。我现在使用一个 1000x1000 数组,称为grid包含 1 和 0。如果某个位置有一个粒子,那么在grid. 还有一个accreted使用相同原理称为第二个阵列,但包含吸积粒子。

我的问题是我似乎想不出一种比较方法,grid并且accreted不使用循环来知道哪些 x 和 y 位置grid需要停止移动(所以进入accreted)。问题出现在accrete我的代码中的函数中。我需要找到一种方法来组合一个变量tmp_xtmp_y这将是一个元组,其中包含满足两个条件之一的所有 x 和 y 位置。换句话说,我需要比较两个网格以找出其中的 1s (.nonzero) 中grid有一个相邻的 1 in accreted。如果您能看一下我的代码,我将不胜感激,谢谢。

import numpy as np

width = 1000
grid = np.zeros((width, width), 'bool')
accreted = np.zeros((width, width), 'bool')
accreted[(round(width/2), round(width/2))] = 1
# a 1 in grid = particle
# a 1 in accreted = accreted particle

def spawn(qty):
    grid[(np.random.randint(0, width, qty), np.random.randint(0, width, qty))] = 1
    return

def move():
    x, y = grid.nonzero()
    grid[(x, y)] = 0 #remove the particles
    #move the particles
    x += np.random.randint(-1, 2, x.size) 
    y += np.random.randint(-1, 2, y.size)
    #just so the particles don't escape the screen
    x[x<0]+=1
    x[x>width-1]-=1
    y[y<0]+=1
    y[y>width-1]-=1
    grid[(x, y)] = 1 #place them in their new position
    return

def accrete():
#>>>THE PROBLEM IS HERE
    tmp_x = np.logical_or((grid.nonzero()[0]+1 == accreted.nonzero()[0]), (grid.nonzero()[0]-1 == accreted.nonzero()[0])) #logic error: we need to know the x and y position of the
    #places where this condition is fullfilled
    tmp_y = np.logical_or((grid.nonzero()[1]+1 == accreted.nonzero()[1]), (grid.nonzero()[1]-1 == accreted.nonzero()[1])) 
    #we need the x and y position
    index_x, = np.nonzero(tmp_x)
    index_y, = np.nonzero(tmp_y)
    grid[(index_x, index_y)] = 'a' #just so .nonzero doesn't see it and it is not 0
    accreted[(index_x, index_y)] = 1

spawn(1000)
with open('DLA', mode='w') as dla:
    for i in range(10):
        dla.write('grid\n' + str(width) + '\n')
        dla.write('accreted\n' + str(accreted) + '\n')
        move()
        accrete()

标签: pythonnumpy

解决方案


推荐阅读