Алгоритм для поиска прямоугольных перестановок

Перестановка является квадратной цепью, если сумма последовательных чисел всегда является идеальным квадратом. Например,

8 1 15 10 6 3 13 12 4 5 11 14 2 7 9 16

представляет собой квадратную перестановку цепей чисел от 1 до 16. Я хочу написать программу, чтобы найти квадратную цепочку с номерами от 1 до n, для n от 1 до 100.

Простейшая задача - лексикографически перейти через все перестановки n (я знаю, как это записать) и проверить условие с квадратным прикосом, но это займет возраст для n больших.

Немного лучший способ - выбрать числа в моей перестановке по одному, проверить, чтобы номер, который я только что выбрал, делает квадрат при добавлении к предыдущему номеру и надеюсь, что я доберусь до конца. Однако мне придется много работать, и я не думаю, что это будет очень эффективно.

Есть ли лучший способ? Кроме того, это известная проблема? Благодарим за помощь.

Ответы

Ответ 1

Интересная проблема; Я сделаю снимок. Переформулируйте проблему как TSP.

Сделайте граф, где узлы являются целыми числами от 1 до 100 (максимально n, которые вы считаете). Теперь соедините i и j, если i+j - идеальный квадрат. Вопрос спрашивает: "Существует ли путь Гамильтона через узлы 1 до n?"

Сделайте график один раз, и, возможно, вы можете настроить путь для i, когда у вас есть его, чтобы включить i+1.

Здесь график до 14:

                   13 --(25)-- 12 --(16)-- 4 --(9)-- 5 --(16)-- 11
                    |                                           |
                  (16)                                         (25)
                    |                                           |
8 --(9)-- 1 --(4)-- 3 --(9)-- 6 --(16)-- 10                     14
                                                                |
                                                               (16)
                                                                |
                                           9 --(16)-- 7 --(9)-- 2

График не был подключен до добавления 14, и даже после добавления 14 нет пути Гамильтона. Здесь показан милый способ рисования графа с добавлением 15, который легко показывает, как сжать 16, а затем 17, продолжая гамильтоновую траекторию:

    12  11  10  09  08
13
                    07
14
                    06
15
                    05
    01  02  03  04

Нарисуйте это на графической бумаге и соедините диагонали и антидиагонали (например, 12-13, 14-11,... и 09-07, 10-06,...), это способы добавления пары, чтобы получить 9 или 16. Здесь я игнорирую край между 1 и 3, потому что это не помогает. Представьте себе, чтобы стрелять по диагонали по шагу от 8 до 1, и когда он попадает в число, он отскакивает под прямым углом. Шар перемещает гамильтоновую траекторию, которую вы дали (с 16 выпавшими). ​​

Чтобы получить путь для 16, просто добавьте его в левый нижний угол. Чтобы получить 17, нанесите его на путь, в который шарик входит в 8.

Существуют разумные алгоритмы поиска пути Гамильтона, и этот подход, скорее всего, быстрее, чем проверка для каждого n на основе любого предлагаемого вами подхода.

Я решил, что для n <= 25 решения существуют только для 15, 16, 17, 23, 25. Вот и вот! Эта последовательность находится в OEIS. Согласно этой странице, предполагается, что решения существуют для всех n > 24, поэтому, очевидно, эта проблема известна, хотя я бы не стал называть ее общеизвестной.