2017-04-10 13 views
0

私はPythonでエージェントベースのモデルを作成しようとしています。環境のために、私はMxNサイズの配列を使いました。各ピクセルは土地のパッチを表します。作成された大きなブロックが連続しているように、土地の各パッチを所有者に割り当てたいと思います。理想的には、より大きなブロックの数を指定できるようにしたいと考えています。整数が大きな連続ブロックにグループ化されるようにnumpy配列に整数を無作為に取り込みます。

This is what I'm envisioning

私はランダム化されたマップを生成しようとしている意外に苦労しています。私は本当に粗末なソリューションを一緒にハックすることができましたが、まだ大きな欠陥があります。私はこの運命を受け入れる前に、他の人にアイデアを惹きつけたいと思った。

+0

しかし、アイデアは無作為に1つの「所有者」番号で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

関連する問題