Я реалізую алгоритм, який буде досить обчислювально складним, і хочу спробувати переконатися, що я не виконую зайвих робіт.
Існує 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 точок, лише ті, які є унікальними за природними симетріями куба.
Наприклад, візьміть куб 2х2х2 і припустимо, що ми хочемо, щоб усі множини по 1 балу. За базовим алгоритмом, наведеним вище, існує 8 різних наборів з 1 балом.
Однак, використовуючи симетрію куба, ми можемо зменшити це до 1 унікального набору в 1 бал, оскільки всі початкові 8 є еквівалентними за симетрією куба (у цьому випадку вони всі "кути").
Якщо куб 2х2х2 і m = 2, в базовому алгоритмі є 28 множин, але це зменшується до симетрики лише на 3 (наприклад, {(0,0,0), (1,0,0)}, {(0 , 0,0), (1,1,0)}, {(0,0,0), (1,1,1)})
Очевидно, що обчислення на 3 наборах точок набагато краще, ніж 28, тому моє питання полягає в тому, як я можу не сформувати набори точок, які симетрично еквівалентні вже створеному набору? Або якщо це неможливо, як я можу принаймні трохи зменшити кількість наборів.
(Примітка - якщо m = 1, це відносно просто - просто виберіть точки, ближчі до (0,0,0), ніж будь-які інші вершини, з невеликим розтушовуванням меж. Це для m> 1 це отримує бути справжньою проблемою)