2012-04-02 2 views
4

私は、有限の3次元六方最密パッキング(HCP)格子にノードの最近傍を格納する最も近いネイバーリストを、Pythonで構築しようとしています。私はすでに2d正方格子で構造を定義しています。私は座標を必要としませんが、整数リストからHCPのための最も近い隣人リストを作成するための素早い方法です。以下は、正方形の格子でこの作業をどのように行ったかのサンプルコードです。整数から最近傍リストをパッキングする球を作成する

N = int #number of nodes 
L = side # a 32x32 graph, L would be 32 

for i in range(N): 

    nearNeighbor[i][0] = (i + 1) % N 
    nearNeighbor[i][1] = (i + (N - 1)) % N 
    nearNeighbor[i][2] = (i + L) % N 
    nearNeighbor[i][3] = (i + N - L) % N 

    if (i-L < 0): 
     nearNeighbor[i][3] = -2 
    if (i+L >= N): 
     nearNeighbor[i][2] = -2 
    if (i%L) == 0: 
     nearNeighbor[i][1] = -2  
    if ((i+1)%L) == 0: 
     nearN[eighbori][0] = -2 

これだけです。 HCP格子は、視覚化されると、一緒に密集した巨大な球体の立方体に似ています。各ノードは、最大12個の最近隣を持つ必要があり、立方体のようなものを作るために出てくるはずです。主に、正方格子で行ったように、HCP格子を表現するために整数とモジュラー演算を使う方法を知りたいと思います。私はスタックすることができますか?

答えて

3

この質問に対する答えは、どのようにHCP格子を切り捨てて索引付けするかによって異なります。一つの選択肢は、この選択により

Indexed HCP lattice Indexed HCP lattice part 2

で、次のコードでは、特定のサイトのネイバーのリストを返します。テストは、サイトのユニークな種類のすべてをカバーしていないことを

def test_neighbors(): 
    n = lambda i: set(neighbors(i, 5, 5, 5)) 

    # test bottom layer 
    assert n(0) == set([1,5,6,25,30]) 
    assert n(2) == set([1,3,7,8,26,27,32]) 
    assert n(4) == set([3,9,28,29,34]) 
    assert n(5) == set([0,6,10,30]) 
    assert n(9) == set([3,4,8,13,14,33,34,38]) 
    assert n(20) == set([15,16,21,45]) 
    assert n(21) == set([16,17,20,22,45,46]) 
    assert n(24) == set([19,23,48,49]) 

    # test second layer 
    assert n(25) == set([0,1,26,30,31,50,51]) 
    assert n(34) == set([4,9,28,29,33,38,39,54,59]) 
    assert n(36) == set([7,11,12,31,32,35,37,41,42,57,61,62]) 
    assert n(49) == set([24,44,48,74]) 

注意上記の関数を書きながら

def neighbors(i, W, H, D): 
    A = W * H 

    plane = i/A 
    plane_index = i % A 
    row = plane_index/W 
    col = plane_index % W 

    r = -1 if row % 2 else 1 # (-1)**row 
    p = -1 if plane % 2 else 1 # (-1)**plane 

    nbors = [] 

    # first include neighbors in same plane 
    if col != W-1: nbors.append(i+1) 
    if col != 0: nbors.append(i-1) 
    if row != H-1: nbors.append(i+W) 
    if row != 0: nbors.append(i-W) 
    if (col != 0 or r > 0) and (col != W-1 or r < 0): 
    if row != H-1: nbors.append(i+W+r) 
    if row != 0: nbors.append(i-W+r) 

    # now add neighbors from other planes 
    if plane != D-1: nbors.append(i+A) 
    if plane != 0: nbors.append(i-A) 

    if (col != 0 or p < 0) and (col != W-1 or p > 0): 
    if plane != D-1: nbors.append(i+A-p) 
    if plane != 0: nbors.append(i-A-p) 

    if ((col != W - 1 or p > 0 or r < 0) and 
     (col != 0 or p < 0 or r > 0) and 
     (row != H-1 or p < 0) and 
     (row != 0 or p > 0)): 
    if plane != D-1: 
     nbors.append(i + A + p*W + (r-p)/2) #10 
    if plane != 0: 
     nbors.append(i - A + p*W + (r-p)/2) #11 

    return nbors 

私はロジックが正しい得たことを確認するためには、私は、次のテストを使用しました間違った場所にコーナーケースが残っている可能性があります。

+0

私はもともと、このコードを動機づけして構築するはるかに長い回答を書いていました。しかし、SOは私の投稿に「コードとして適切に書式設定されていないコードが含まれているように見える」ということを私に教えてくれます。 (すべてが正しく表示されているように見えますが)。誰かが長い記述を望むなら、私に知らせて、私は別の場所に置くでしょう。 – rephorm

+0

これは本当に有益でしたありがとう!私はまたあなたの長い記述に興味があり、おそらく他の構成(巨大な球の中の球の詰め物のような)で最も近い隣人を見つける方法。ほんとうにありがとう。 – elais

+0

詳細については、[this article](http://www.rephorm.com/thoughts/indexing-hexagonal-close-packed-lattice/)を参照してください。 – rephorm

関連する問題