2017-04-10 8 views
0

저는 Python으로 에이전트 기반 모델을 만들려고합니다. 환경에 대한, 나는 MxN 크기의 배열을 사용하고있다. 각 픽셀은 토지 패치를 나타냅니다. 나는 창조 된 더 큰 블록이 연속적 이도록 토지의 각 패치를 소유자에게 할당하고 싶다. 이상적으로, 나는 더 큰 블록의 수를 지정할 수 있기를 원한다.정수가 더 큰 인접한 블록으로 그룹화되도록 numpy 배열에 정수를 무작위로 채 웁니다.

This is what I'm envisioning

것은 나는 무작위로 맵을 생성하려고 놀라 울 정도로 힘든 시간을 보내고 있습니다. 나는 정말 조잡한 해결책을 함께 해킹 할 수 있었지만 여전히 몇 가지 큰 결함이있다. 나는이 운명을 받아들이 기 전에 다른 사람들에게 아이디어를 구합니다.

+0

하지만 아이디어는 0 개의 채워진 행렬에 단일 '소유자'번호를 무작위로 뿌린 다음, 만날 때까지 채워진 0 개의 영역으로 각각 "성장"합니다. – f5r5e5d

+0

감사합니다. 죄송합니다! 문제가 발생한 이후로 게시 할 위치가 확실하지 않았습니다. 가지고있는 것은이 모델의 코딩 부분입니다. 실제로 작동하는 방식입니다. 임의의 좌표 쌍과 임의 검색 반경 (r)을 선택합니다. 모든 0 세포 r 멀리 거리로 성장할 수 있습니다. 문제는 내가 이상한 모양의 긴 땅 패치로 끝나야한다는 것입니다. 그것은 무작위 방법으로 얻을 수있는 최선의 것일 수도 있습니다. – Chris

답변

1

샷을 제공하는 것을 거부 할 수 없으므로 여기에 scipy.ndimage.grey_dilation을 사용하는 시도가 상당히 빠르다. grey_dilation은 아래 코드에서 "구조 요소"- "성장 커널"을 사용하여 영역을 확장합니다. 나는 그들이 그 과정을 통해 제공 얼마나 제어에 관해서는 경험이 없지만 그들은 당신이 놀 수있는 일입니다

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

샘플 출력 : 질문이 여기에 코드를 중심으로 suppsed된다

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

이것은 훌륭하게 작동합니다. 위대한 발견! 나는 매개 변수를 가지고 놀 것이다. 그러나 나의 초기 반응은 그것이 나의 필요를 위해 작동한다는 것이다! – Chris

+0

@Chris 그것이 당신을 위해 일하는 것을 듣고 기쁘게 생각합니다. –

+0

나는 커널을 가지고 놀았지만 아직도 이해하고있다. 모서리가 더 정사각형이되고 각도가 작아지는 데 필요한 빠른 팁이 있습니까? – Chris