Функция для генерации гиперкуба в любом измерении (Python) - PullRequest
0 голосов
/ 21 апреля 2020

Мне нужно написать функцию python, которая возвращает список или кортеж координат для единичного гиперкуба (square / box / tesseract et c.) На основе начальных координат, которые будут размещены в левом верхнем углу. У меня есть векторный класс, который принимает список любой длины, который я использую для разных несвязанных частей проекта. Порядок точек на самом деле не имеет значения, только то, что начальная позиция является «самой низкой точкой», ie [x, y, z ...] и что никакая другая точка не является [x-1, y] или что-то такое. Он должен работать для любого числа измерений, и каждая сторона имеет длину в одну единицу.

Для квадрата это будет выглядеть так:

def square(x, y):
  return [
    Vector([x, y]),
    Vector([x + 1, y]),
    Vector([x + 1, y + 1]),
    Vector([x, y + 1])
  ]

Куб будет выглядеть так:

def cube(x, y, z):
  return [
    Vector([x, y, z]),
    Vector([x + 1, y, z]),
    Vector([x + 1, y + 1, z]),
    Vector([x, y + 1, z]),
    Vector([x, y, z + 1]),
    Vector([x + 1, y, z + 1]),
    Vector([x + 1, y + 1, z + 1]),
    Vector([x, y + 1, z + 1]),
  ]

Это продолжается, поэтому мне нужно написать функцию, которая бы выглядела примерно так:

def hypercube(start):
  points = [];

  #Add all the points to the list (need to figure out)

  return points

# And it will be used like so:

starts = [35, 12]
print(hypercube(starts))
# result: 
#[Vector(35, 12), Vector(36, 12), Vector(36, 13), Vector(35, 13)]


starts = [35, 12, 34, 17, 2]
print(hypercube(starts))
#result :
#[Vector(35, 12, 34, 17, 2), ... Vector(36, 13, 35, 18, 3)]

Я понимаю, что, вероятно, существует рекурсивный способ сделать это Я просто не могу думать об этом.

1 Ответ

1 голос
/ 21 апреля 2020

Функция itertools combinations_with_replacement может дать вам все необходимые комбинации «добавить 1» или «добавить ничего» для каждой оси в вашем кубе.

Итак, предположим, что ваш класс Vector поддерживает Добавление вектора:

from itertolls import combinations_with_replacements

from ... import Vector

def hypercube(starts):
    dimensions = len(starts)
    return [starts + Vector(*combination) for combination in combinations_with_replacements((0, 1), dimensions)]

И если ваш "Вектор" еще не поддерживает добавление с помощью оператора +, все, что вам нужно сделать, это включить в него метод __add__:


class Vector:

    def __add__(self, other):
       return self.__class__([comp1 + comp2  for comp1, comp2 in zip(self, other)]) 

(В этом случае, если ваш «Вектор» наследует от Python Последовательности, такие как список, или collection.ab c .Sequence, и он правильно повторяется - в противном случае просто передайте zip атрибут Vector, который содержит данные последовательности)

...