Python 用整数随机填充numpy数组,以便将整数分组到更大的连续块中

Python 用整数随机填充numpy数组,以便将整数分组到更大的连续块中,python,arrays,numpy,agent-based-modeling,Python,Arrays,Numpy,Agent Based Modeling,我正在尝试用Python创建一个基于代理的模型。对于环境,我一直在使用MxN大小的numpy数组。每个像素代表一块土地。我想为每一块土地分配一个所有者,以便创建的较大地块是相邻的。理想情况下,我希望能够指定较大块的数量 我在尝试生成一张随机地图时遇到了令人惊讶的困难。我已经能够拼凑出一个非常粗糙的解决方案,但它仍然有一些主要的缺陷。在接受这一命运之前,我想我应该先征求其他人的意见。忍不住尝试一下,所以这里尝试使用scipy.ndimage.grey\u扩展,它看起来相当快。grey_膨胀使用以下

我正在尝试用Python创建一个基于代理的模型。对于环境,我一直在使用MxN大小的numpy数组。每个像素代表一块土地。我想为每一块土地分配一个所有者,以便创建的较大地块是相邻的。理想情况下,我希望能够指定较大块的数量


我在尝试生成一张随机地图时遇到了令人惊讶的困难。我已经能够拼凑出一个非常粗糙的解决方案,但它仍然有一些主要的缺陷。在接受这一命运之前,我想我应该先征求其他人的意见。

忍不住尝试一下,所以这里尝试使用scipy.ndimage.grey\u扩展,它看起来相当快。grey_膨胀使用以下代码中的结构元素-增长核来扩展区域。我没有任何经验知道他们对过程有多大的控制权,但你可以利用他们:

import numpy as np
from scipy import ndimage

growth_kernels = """
010 000 010 111
111 111 010 111
010 000 010 111
"""

growth_kernels = """
555555555 543212345
444444444 543212345
333333333 543212345
222222222 543212345
111101111 543202345
222222222 543212345
333333333 543212345
444444444 543212345
555555555 543212345
"""

def patches(shape, N, maxiter=100):
    # load kernels
    kernels = np.array([[[int(d) for d in s] for s in l.strip().split()]
                        for l in growth_kernels.split('\n')
                        if l.strip()], np.int)
    nlev = np.max(kernels) + 1
    # special case for binary kernels
    if nlev == 2:
        kernels = 2 - kernels
        nlev = 3
    kernels = -kernels.swapaxes(0, 1) * N
    key, kex = kernels.shape[1:]
    kernels[:, key//2, kex//2] = 0
    # seed patches leave a gap between 0 and the first patch
    out = np.zeros(shape, int)
    out.ravel()[np.random.choice(out.size, N)] = np.arange((nlev-1)*N+1, nlev*N+1)
    # shuffle labels after each iteration, so larger numbers do not get
    # a systematic advantage
    shuffle = np.arange((nlev+1)*N+1)
    # also map negative labels to zero
    shuffle[nlev*N+1:] = 0
    shuffle_helper = shuffle[1:nlev*N+1].reshape(nlev, -1)
    for j in range(maxiter):
        # pick one of the kernels
        k = np.random.randint(0, kernels.shape[0])
        # grow patches
        out = ndimage.grey_dilation(
            out, kernels.shape[1:], structure=kernels[k], mode='constant')
        # shuffle
        shuffle_helper[...] = np.random.permutation(
            shuffle[(nlev-1)*N+1:nlev*N+1])
        out = shuffle[out]
        if np.all(out):
            break
    return out % N

res = patches((30, 80), 26)
print(len(np.unique(res)))
for line in res:
    print(''.join(chr(j+65) for j in line))
样本输出:

WWWWWKKKKKKKKKKKKMMMLLLLLLLLLLJJJJJJJJJCCCCCCCCCCCCCCCCCSSSSSSSSSAAAAAAAAAAAAAAA
WWWWWKKKKKKKKKKKKMMMLLLLLLLLLLJJJJJJJJJCCCCCCCCCCCCCSSSSSSSSSSSSSAAAAAAAAAAAAAAA
WWWWWKKKKKKKKKKKKMMMLLLLLLLLLLJJJJJJJJJJJJJCCCCCCCCCSSSSSSSSSSSSSAAAAAAAAAAAAAAA
WWWWWKKKKKKKKKKKKMMMLLLLLLLLLLLLLLJJJJJJJJJCCCCCCCCCSSSSSRRRRRRRRRAAAAAAAAAAAAAA
WWWFFFFKKKKKKKKKKMMMLLLLLLLLLLLLLLJJJJJJJJJCCCCCCCCCSSSSSRRRRRRRRRAAAAAAAAAAAAAA
WWWFFFFKKKKKMMMMMMMMMLLLLLLLLLLLLLJJJJJJJJJCCCCCCCCCSSSSSRRRRRRRRRAAAAAAAAAAAAAA
WWWFFFFKKKKKMMMMMMMMMLLLLLLLLLLLLLJJJJJJJJJJJJJCSSSSSSSSSRRZZZZZZZZZZZGGGGGGGGGG
WWWFFFFFFFFFMMMMMMMMTTTTTTLLLLLLLLJJJJJJJJJJJJJCSSSSSSSSSRRZZZZZZZZZZZGGGGGGGGGG
WWWFFFFFFFFFMMMMMMMMTTTTTTLLLLLLLLJJJJJJJJJJJJJHSSSSSSSSSRRZZZZZZZZZZZGGGGGGGGGG
FFFFFFNNNNNNMMMMMMMMTTTTTTLLLLLLLLJJJJJJJJJJJJJHSSSSSSSSSRRZZZZZZZZZZZGGGGGGGGGG
FFFFFFNNNNNNMMMMMMMMTTTTTTLLLLLLLLJJJJJHHHHHHHHHSRRRRRRRRRRZZZZZZZZZZZGGGGGGGGGG
FFFFFFNNNNNNMMMMMMMMTTTTTTLLLLLLLLLHHHHHHHHHHHHHSRRRRRRRRRRZZZZZZZZZZZGGGGGGGGGO
FFFFFFNNNNNNMMMMMMMMTTTTTTTTTTTTHHHHHHHHHHHHHHHHDRRRRZZZZZZZZZZZZZZZZZGGGGGGGGGO
NNNNNNNNNNNNMMMMMMMMTTTTTTTTTTTTHHHHHHHHDDDDDDDDDDRRRZZZZZZZZZZZZZZZZZGGGGGGGGGO
NNNNNNNNNNNNNNNTTTTTTTTTTTTTTTTTHHHHHHHHDDDDDDDDDDUUUZZZZZZZZZZZZZZZZZGGGGGGGGGO
EEEEENNNNNNNNNNTTTTTTTTTTTTTTTTTHHHHHHHHDDDDDDDDDDUUUUUUUUUUUUUUUUZZZZGOOOOOOOOO
EEEEENNNNNNNNNNNTTTTTTTTTTTTTTTHHHHHHHHHDDDDDDDDDUUUUUUUUUUUUUUUUUZZZZGOOOOOOOOO
EEEEENNNNNNNNNNNTTTTTTTTTTTTTTTHHHHHHHHHDDDDDDDDDUUUUUUUUUUUUUUUUUZZZZGOOOOOOOOO
EEEEEEEEEEEENNNNTTTTTTTTTTTTTTTHHHHHHHHHDDDDDDDDDUUUUUUUUUUUUUUUUUXXXXGOOOOOOOOO
EEEEEEEEEEEENNNNTTTTTTTTTTTTTTTHHDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUXXXXXOOOOOOOOO
EEEEEEEEEEEENNNNVVVVVVVVVVVTTTTHHDDDDDDDDDDDDDDDDPPPPPBBUUUUUUUUUUXXXXXOOOOOOOOO
EEEEEEEEEEEEVVVVVVVVVVVVVVVTTTTQQDDDDDDDDDDDDDDDDPPPPPBBUUUUUUUUUUXXXXXXXXXXXXXX
EEEEEEEEEEEEVVVVVVVVVVVVVVVTTTTQQQQQQQQQQQQQQPPPPPPPPPBBUUUUUUUUUUXXXXXXXXXXXXXX
EEEEEEEEEEEEVVVVVVVVVVVVVVVTTTTQQQQQQQQQQQQQQQQQPPPPPPBBUUUUUUUUUUXXXXXXXXXXXXXX
EEEEEEEEEEVVVVVVVVVVVVVVVVVVVHHQQQQQQQQQQQQQQQQQPPPPPPBBUUUUUIIIIIIIIXXXXXXXXXXX
EEEEEEEEEEVVVVVVVVVVVVVVVVVVVQQQQQQQQQQQQQQQQQQQPPPPPPBBBBBIIIIIIIIYYYYYXXXXXXXX
EEEEEEEEEEVVVVVVVVVVVVVVVVVVVQQQQQQQQQQQQQQQQQQQPPPPPPBBBBBIIIIIIIIYYYYYXXXXXXXX
EEEEEEEEEEVVVVVVVVVVVVVVVVVVVQQQQQQQQQQQQQQQQQQQPPPPPPBBBBBIIIIIIIIYYYYYXXXXXXXX
EEEEEEEEEEVVVVVVVVVVVVVVVVVVVQQQQQQQQQQQQQQQQQQQPPPPPPBBBBBIIIIIIIIYYYYYXXXXXXXX
EEEEEEEEEEVVVVVVVVVVVVVVVVVVVQQQQQQQQQQQQQQQQQQQPPBBBBBBIIIIIIIIIIIYYYYYXXXXXXXX

这里的问题是以代码为中心的,但是一个想法是随机地在一个0填充的矩阵中植入一个“所有者”编号,然后迭代地将每个编号增长到0填充的区域,直到他们遇到感谢和抱歉!我不确定在哪里发布,因为我遇到的问题是这个模型的编码部分。这就是我现在的工作方式。我选择一个随机坐标对,随机搜索半径r然后增长到距离r的所有0个单元格。问题是,我最终得到的是形状怪异的大片土地。不过,这可能是我用随机方法能得到的最好的结果。这非常有效。伟大的发现!我将使用一些参数,但我的初步反应是,它适合我的需要!我已经玩了一点内核,但是我离理解它还很远。有什么快速的方法可以让边缘变得更方、角度更小吗?@chrishm,我自己也不太了解它们。看看更新后的答案,这就是我如何通过反复试验或多或少地得到它的方法。这就是你的想法?非常感谢。那也是我得到的。我不确定我是否遗漏了什么。不管怎样,这是一个很好的解决方案,几乎完美地满足了我的需求。很抱歉再次光临。我一直有一些有趣的行为,我得到了负面的价值观。该值始终为N-1。我假设它发生在return语句中,但我还没有确定它。有什么想法吗?