用整数随机填充 numpy 数组,以便将整数分组为更大的连续块
Randomly populate numpy array with integers such that integers are grouped into larger contiguous blocks
我正在尝试在 Python 中创建基于代理的模型。对于环境,我一直在使用 MxN 大小的 numpy 数组。每个像素代表一块土地。我想为每块土地分配一个所有者,以便创建的较大块是连续的。理想情况下,我希望能够指定较大块的数量。
This is what I'm envisioning
我在尝试生成随机地图时出奇地困难。我已经能够拼凑出一个非常粗糙的解决方案,但它仍然存在一些重大缺陷。我想我会在接受这种命运之前征求其他人的意见。
忍不住试一试,所以这里尝试使用 scipy.ndimage.grey_dilation
,速度似乎相当快。 grey_dilation
在下面的代码中使用 "structure elements" -- "growth kernels" 扩展领土。我没有任何关于他们对流程的控制权的经验,但你可以玩它们:
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
我正在尝试在 Python 中创建基于代理的模型。对于环境,我一直在使用 MxN 大小的 numpy 数组。每个像素代表一块土地。我想为每块土地分配一个所有者,以便创建的较大块是连续的。理想情况下,我希望能够指定较大块的数量。
This is what I'm envisioning
我在尝试生成随机地图时出奇地困难。我已经能够拼凑出一个非常粗糙的解决方案,但它仍然存在一些重大缺陷。我想我会在接受这种命运之前征求其他人的意见。
忍不住试一试,所以这里尝试使用 scipy.ndimage.grey_dilation
,速度似乎相当快。 grey_dilation
在下面的代码中使用 "structure elements" -- "growth kernels" 扩展领土。我没有任何关于他们对流程的控制权的经验,但你可以玩它们:
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