Если вы её ещё оптимизируете, будет вообще отлично.
А вариант другого языка (с более высоким быстродействием) возможен?
Кое-что я вчера сделал, но сначала несколько слов о вашем алгоритме для тех, кто не стал смотреть текст на васике. В нем идет перебор с помощью вложенных циклов - в таблице ниже показаны переменные перебора i,j,..,v. Прежде чем входить в очередной вложенный цикл идут проверки о необходимости подобного вхождения. Например, после задания переменных i,j,k,l вычисляется элемент с индексом x1 и процесс не идет дальше, если проверки не пройдены. Понятно, что это можно организовать разными способами. У Наталии последовательно вычисляются элементы квадрата с индексами x1,x2,x3,x4,x5,x6, а далее элементы 21,22,23,24,25 (это не числа, а обозначения элементов квадрата). Насколько оптимально это сделано у Наталии? Вопрос, вообще говоря, открыт. Но, по крайней мере, весьма неплохо сделано.
Прежде всего (это сделано уже в программах mak3 и mak4), когда я переписывал алгоритм, то обратил внимание, что индексы x1,..,x6 находились, но из дальнейшего перебора не исключались - я немного поправил текст и быстродействие увеличилось в 4 раза. Выкинул ненужные проверки на финише - сумму элементов последней строки проверять не надо, т.к. уже исходный набор чисел выбран с суммой равной 5 магическим числам. Кстати, особого выигрыша по времени это не дало - до последних операций нужно еще добраться
.
Код:
i j k x1 l
t x3 x5 m x4
x6 21 n v s
u x2 22 q r
o 23 24 25 p
После тестирования на смитах стало очевидно, что молотить уже найденные варианты дополнительно 31 раз совсем ни к чему. Для квадратов 5 порядка, хорошо известно, существует понятие изоморфизма, т.е. повороты и симметрия из любого квадрата дают традиционно эквивалентные квадраты, плюс два специальных преобразования увеличивают набор эквивалентных квадратов до 32.
1. Посмотрим на элементы i,l,p,o,x3,m,q,x2 - максимальный элемент можно с помощью преобразования вывести на внешнюю границу, а затем с помощью поворота перевести его на место i. Итак:
i>l,p,o,x3,m,q,x2
2. Смотрим на элементы j,x1,u,t. Не затрагивая элемента i, можно с помощью второго спец. преобразования (одновременное переворачивание внутренних горизонтальных и вертикальных полос) и симметрии относительно диагонали i-p добиться, чтобы максимальный элемент рассматриваемой группы оказался на месте j. Итак:
j>t,x1,u
Осталось чуть изменить пределы перебора циклов и... модифицированная программа mak5 заработала.
Сначала я протестировал ее на тех же смитах, что предложила Наталия.
Было: 12148.90 сек
Стало: 594.83 сек
Программа, как ей и положено, выдала 2 не изоморфных квадрата.
Далее я подсунул программе исходный набор из простых чисел 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 101 103 и лег спать. Результат:
Время работы: 26968.40 сек
Количество не изоморфных квадратов - 58257, что соответствует 233028 традиционно различным квадратам и 1864224 всех квадратов.
Что дальше? Пока выбор элементов из уменьшающегося набора в алгоритме идет с помощью линейного поиска, что "не есть хорошо" - любая "деревянная" конструкция, обычно, лучше, особенно, если попытаться расширить исходный набор. Выбор другого языка и технических средств - это за пределами алгоритма. Конечно, 16-битовый BP7 нужно заменить на FP - эффект должен быть. Далее, в mak4 я заложил тип integer, что уже на смитах мало - пришлось кое-где поставить longint. В особые свойства иных языков я не очень верю - необходимые ассемблерные вставки можно делать уже древнем паскале. Все-таки, основной эффект дает алгоритм, а не язык (интерпретаторы исключаем
), и удачное структурирование данных. Вот здесь всегда есть, над чем поработать.
-- Вс фев 14, 2010 16:51:14 --Если брать массив, из которого магический квадрат не складывается, такой массив проверяется около 4 минут (обратите внимание: полный перебор всех вариантов!). Всего 4 минуты!
Я проверила уже 10 таких массивов.
Первый массив взяла тот, который первым переваливает за миллион, вот этот:
Код:
999153, ..., 1000462
Внимание! Будьте осторожны - в вашем варианте программы тип переменных на дает возможности использовать числа более 32000. Я вам уже писал - замените integer на longint в тексте mak4.pas и откомпилируйте. Строка для запуска компилятора:
tpc.exe mak4.pas