Я реализую алгоритм, который будет довольно сложным в вычислительном отношении, и хочу попытаться убедиться, что я не делаю ненужную работу.
Существует nxnxn кубическая решетка, например, если n = 2, она состоит из (0,0,0), (0,1,0), (1,0,0), (1,1,0), (0, 1,1), (0,0,1), (1,0,1), (1,1,1).
Из этой решетки я буду рекурсивно генерировать все множества m точек, что-то вроде:
solve(set_of_points) {
if set_of_points.size = m, finish
do some useful computation here
for each point in lattice not in set_of_points:
solve(set_of_points + new_point);
}
Затем это можно вызвать, начиная с пустого set_of_points.
Природа проблемы такова, что на самом деле мне не нужны все перестановки из m точек, а только те, которые уникальны при естественных симметриях куба.
Например, возьмите куб 2x2x2 и предположим, что мы хотим, чтобы все множества были равны 1 точке. В соответствии с базовым алгоритмом, приведенным выше, существует 8 различных наборов по 1 точке.
Однако, используя симметрии куба, мы можем уменьшить его до 1 уникального набора из 1 точек, поскольку все исходные 8 эквивалентны при симметрии куба (в этом случае все они являются «углами»).
Если куб имеет размер 2x2x2 и m = 2, в базовом алгоритме 28 наборов, но при симметрии он уменьшается до 3 (например, {(0,0,0), (1,0,0)}, {(0 , 0,0), (1,1,0)}, {(0,0,0), (1,1,1)})
Очевидно, что вычисление трех наборов точек намного лучше, чем 28, поэтому мой вопрос: как мне не генерировать наборы точек, которые симметрично эквивалентны уже сгенерированному набору? Или, если это невозможно, как я могу хотя бы немного уменьшить количество подходов.
(Обратите внимание - если m = 1, это относительно просто - просто выберите точки, которые ближе к (0,0,0), чем любая из других вершин, с небольшим перемалыванием на границах. Это для m> 1 это быть настоящей проблемой)