2017-04-10 81 views
0

我試圖創建在Python基於代理的模型。對於環境,我一直在使用MxN大小的numpy數組。每個像素代表一片土地。我想將每塊土地分配給一個所有者,使得所創建的較大的塊是連續的。理想情況下,我希望能夠指定大塊的數量。隨機填充整數numpy的陣列,使得整數被分組爲更大的連續塊

This is what I'm envisioning

我有一個令人驚訝的困難時期試圖生成隨機地圖。我能夠一起破解一個非常粗糙的解決方案,但它仍然存在一些主要缺陷。我認爲在接受這個命運之前,我會引出其他人的想法。

+0

問題是suppsed是代碼中心在這裏,但一個想法是隨機種子單「所有者0填充矩陣」的數字,然後iterativley‘成長’每次進0填充區域,直到他們滿足 – f5r5e5d

+0

謝謝,對不起!我不知道,因爲這個問題在哪裏發佈我在與這種模式的編碼部分。這實際上是我現在的工作方式。我選擇一個隨機座標對和隨機搜索半徑(R)個在距離遠的所有0個單元中生長。問題是我最終形成了奇怪形狀的長片土地。不過,這可能是我用隨機方法得到的最好結果。 – 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)) 

輸出示例:

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