2012-04-02 1 views
4

나는 가장 가까운 이웃 노드를 유한 3D 육각형 가장 가까운 패킹 (HCP) 격자에 저장하는 가장 가까운 이웃리스트를 파이썬에서 구성하려고합니다. 나는 이렇게 구조를 정의하는 2 차원 정사각형 격자로 이미 이것을했습니다. 나는 좌표를 원하지 않지만 정수 목록에서 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

[이 기사] (http://www.rephorm.com/thoughts/indexing-hexagonal-close-packed-lattice/)에 더 자세한 내용이 나와 있습니다. – rephorm