Создание сферы, упаковывающей список ближайших соседей из целых чисел - PullRequest
4 голосов
/ 02 апреля 2012

Я пытаюсь построить список ближайших соседей в python, который хранит ближайших соседей узла в решетке конечной трехмерной гексагональной упаковки (HCP). Я сделал это уже с двумерной квадратной решеткой, определяющей структуру следующим образом. Я не хочу координаты, но просто быстрый способ создать список ближайших соседей для 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, как я это делал с квадратной решеткой. Можете ли вы помочь мне сложить?

1 Ответ

3 голосов
/ 04 апреля 2012

Ответ на этот вопрос зависит от того, как можно усечь решетку HCP и проиндексировать ее. Один выбор -

Indexed HCP lattice Indexed HCP lattice part 2

При таком выборе следующий код вернет список соседей данного сайта.

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

Чтобы убедиться, что я правильно понял логику, я использовал следующий тест при написании вышеуказанной функции

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])

Обратите внимание, что тест не охватывает все уникальные типы сайтов, поэтому в любом случае может быть неправильный случай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...