2017-02-05 7 views
0

私はビジュアルアーティストで、特定の作品を作成するためにPythonを学んでいます。 1つは、2160x3840グリッドを使用して、Conwayの古典的なGame of Lifeをコーディングしています。Python(Numpy)配列の等しい関数が遅いです...より速い方法がありますか?

しかし、プログラムは私が望んでいたよりも遅く実行されています。私の3歳のiMacで24時間稼働しています.2.5フレームしか処理されません。走るには数週間かかりますが、私はいくつかの走りがあります。

私はSnakeVizを実行しました。私のプログラムの時間の93%は、一次アクティビティが一連の比較である単一の関数で費やされています。すべての「ピンチ」カラーとflashOfLifeColorは、コンウェイのルールの点で「ライブ」セルとみなされます。

def isLive (theColor): 

    isCellLive = False 
    finchColor_1 = numpy.array([247, 238, 214]) 
    finchColor_2 = numpy.array([202, 184, 88]) 
    finchColor_3 = numpy.array([103, 81, 68]) 
    flashOfLifeColor = numpy.array([249, 192, 0]) 

    if (numpy.array_equal(theColor, finchColor_1)) or 
     (numpy.array_equal(theColor, finchColor_2)) or 
     (numpy.array_equal(theColor,  finchColor_3)) or 
     (numpy.array_equal(theColor, flashOfLifeColor)): 

     isCellLive = True 

    return isCellLive 

if文を書く方が良い(より速い)方法はありますか?私は物事をスピードアップするために最適化以外で何かできることはありますか?

おかげで、

--Darin編集:ここでは

は私がやっているものを理解するためにisLiveの各を呼び出している関数です。また、私はPythonプログラミングの新機能であり、オブジェクトプログラミングも全く知らないということをもう一度言及したいと思います。先進的なテクニックではありません。私が見ているConwayの規則の実装の一部を解読するのは苦労します。ウェブ。

def countNeighborsNine(theArray, row, column): 

    numberOfNeighbors = 0 
    maxRow, maxColumn, depth = theArray.shape 
    for rowModifier in range (-1,2): 
     for columnModifier in range (-1, 2): 

      rowNeighborPointer = (row + rowModifier) % maxRow 
      columnNeighborPointer = (column + columnModifier) % maxColumn 

      thePixel = theArray[rowNeighborPointer, columnNeighborPointer] 

      if isLive(thePixel): 
       numberOfNeighbors = numberOfNeighbors + 1 

    return numberOfNeighbors 
+0

とすぐに私は明らかに改善が見られ、この投稿として - 比較のため、代わりにライブ色の「死んだ」色を使用。死んだ色は3色あります。それ以上の改善はまだ必要です。 –

+1

私が理解する限り、細胞の色を保存してから、その色から状態を再構成します。なぜあなたはそれをやっているのですか?セルの状態をブール値または整数値として保存し、この 'isLive'関数を完全に避けてみませんか? –

+0

btw、この実装を試すことができますhttps://rosettacode.org/wiki/Conway%27s_Game_of_Life#Python –

答えて

2

可能な解決策があります。あなたの画像の色はおそらくR、G、Bそれぞれ0..255の範囲にあります。私はまず、画像全体のための単一の一意の「カラーID」に変換します(処理しやすい)。

cid = grid_r * 256 * 256 + grid_g * 256 + grid_b 

あなたの生/死リストについては、同じ操作を行います:

def get_id(a): 
    return a[0] * 256 * 256 + a[1] * 256 + a[2] 
live_colours = np.array([get_id(finchColor_1), get_id(finchColor_2), get_id(finchColor_3), get_id(flashOfLifeColor)]) 

今、あなたはすべて1つのコマンドで 'ライブ' の細胞を得ることができます。

ここ
alive = np.in1d(cid, live_colours).reshape(cid.shape) 

alive意志をTrueFalse要素の2160x3840の配列である必要があります。 np.in1dは、cidに各要素をとり、live_coloursにある場合はTrueを返します。返される配列は1-dなので、元のイメージと同じ形に変更する必要があります。

を編集します。これを使用して、各セルのライブネイバーの数をカウントします。まず、2-dロール関数を定義します。

def shifter(x, a, b): 
    return np.roll(np.roll(x, a, axis=0), b, axis=1) 

私はすべての4つの側面に「死んだ」細胞とaliveアレイとパッドそれを取る:

width = 2160 
height = 3840 
biglive = np.zeros((width + 2, height + 2)) 
biglive[1:-1, 1:-1] = alive.astype(int) 
live_count = shifter(biglive, -1, -1) + shifter(biglive, -1, 0) + shifter(biglive, -1, 1) + shifter(biglive, 0, -1) + shifter(biglive, 0, 1) + shifter(biglive, 1, -1) + shifter(biglive, 1, 0) + shifter(biglive, 1, 1) 

我々は最後にパディングゼロのセルを無視します。

live_count = live_count[1:-1, 1:-1] 

これは2160x3840のグリッドで、各セルにはライブネイバーの数が含まれています。私はランダムな画像を生成し、完全な2160x3840セットの生きているネイバーの数を計算するために、プロセス全体に数秒かかりました。

+0

こんにちはVBB、詳細な答えをいただきありがとうございます。私はあなたがコードを読んでいるところで半分を取得しています - 明日はもっと明瞭です(!)私はそれを通訳に付けるので、何が起きているのか、そしてなぜそれが本当に理解できるでしょう。再度、感謝します。あなたのコードは私よりもはるかにコンパクトに見えます! :) –

+1

良い解決策。 1つの言い訳:OPのネイバーコードが実際にラップアラウンドするので、パディングを取り除くことができます。また、意図的なものであるかどうかを確認する必要があります。中央のピクセルを隣人として数えているようです。 –

+0

ありがとう@PaulPanzer。私はノーラップと8人の隣人を、通常の生活ルールのゲームと同じように仮定しました。 – VBB

1

あなた自身で最も良い方法を見つけることをアドバイスしてください。

  • 純粋なpythonプロジェクトから始まり、numpyのものから始めます。

  • ゲームロジックとビジュアライゼーションを分ける。

    生きている/死んでいる人を区別するための1つのアレイを例にとると、他の人をカウントする隣人。 可視化のためにimshow(neighbors、cmap = my_conway_map)を使用します。

  • numpy配列ではforループを使用しないでください。遅いです。

最小限exemple:

world=randint(0,2,(5,5)) 
mask=ones((3,3)) 
mask[1,1]=0 
neighb=scipy.signal.convolve2d(world,mask,'same') 
subplot(121) 
a=imshow(world,interpolation='none',cmap=cm.Greys) 
subplot(122) 
colorbar() 
b=imshow(neighb,interpolation='none') 
show() 

conway

関連する問題