Для фиксированного n рассмотрим матрицы Теплица n by n с записями, которые либо 0, либо 1. Цель состоит в том, чтобы найти максимальный определитель для всех таких матриц Теплица.
задача
Для каждого значения n
от 1 и выше выведите максимальный определитель по всем n на n матриц Тёплица с записями, равными 0 или 1. Должен быть один выход, для n
которого должен быть максимальный определитель, а также пример матрицы, которая его достигает.
Гол
Ваша оценка - самая большая сумма, которую n
ваш код получает за 2 минуты на моем компьютере. Чтобы уточнить, ваш код может работать в общей сложности 2 минуты, это не 2 минуты n
.
Стяжка
Если две записи получают одинаковый n
счет, то выигрышная запись будет той, которая наберет наибольшее n
за самое короткое время на моей машине. Если по этому критерию две лучшие записи равны, то победителем будет ответ, представленный первым.
Языки и библиотеки
Вы можете использовать любой свободно доступный язык и библиотеки, которые вам нравятся. Я должен быть в состоянии запустить ваш код, поэтому, пожалуйста, включите полное объяснение того, как запустить / скомпилировать ваш код в Linux, если это вообще возможно.
Моя машина Время будет запущено на моей машине. Это стандартная установка Ubuntu на восьмиъядерный процессор AMD FX-8350. Это также означает, что мне нужно иметь возможность запустить ваш код.
Маленькие ответы
Для n = 1..10 выходы должны быть 1,1,2,3,5,9,32,56,125,315
Эта последовательность отсутствует в OEIS, и поэтому победившая заявка также может предложить новую запись там.
Записи до сих пор
n=10
n=11
Vioz в Pythonn=9
Тийло в Сиn=12
Лежандр в Jn=10
Тенсибай в Rn=14
SteelRaven в C ++n=14
RetoKoradi в C ++
n = 1..10
: ghostbin.com/paste/axkpaОтветы:
C ++ с потоками
Это достигает п = 14 всего за 1 минуту на моей машине. Но поскольку это всего лишь 2-ядерный ноутбук, я надеюсь, что 8-ядерный тестовый компьютер сможет завершить n = 15 менее чем за 2 минуты. На моей машине это занимает около 4:20 минут.
Я действительно надеялся придумать что-нибудь более эффективное. Там уже есть должны быть способом более эффективно рассчитать детерминированные бинарную матрицу. Я хотел придумать какой-то подход динамического программирования, который учитывает члены +1 и -1 в вычислении детерминанта. Но пока что это не совсем так.
Поскольку срок действия награды истекает, я применил стандартный метод грубой силы:
Я протестировал это на Mac OS, но раньше я использовал похожий код в Ubuntu, поэтому я надеюсь, что он будет скомпилирован и запущен без проблем:
.cpp
расширением, напримерoptim.cpp
.gcc -Ofast optim.cpp -lpthread -lstdc++
.time ./a.out 14 8
. Первый аргумент - максимумn
. 14 наверняка закончится менее чем за 2 минуты, но было бы здорово, если бы вы тоже попробовали 15. Второй аргумент - количество потоков. Использование того же значения, что и число ядер машины, обычно является хорошим началом, но попытка некоторых вариантов может потенциально улучшить время.Дайте мне знать, если у вас возникнут проблемы со сборкой или запуском кода.
источник
J
Обновление: улучшен код для поиска более половины значений. Теперь
n=12
удобно вычислять в течение 120 секунд (с 217 до 60 секунд).Вам нужно будет последняя версия J установлена.
Запустите это и убейте, когда две минуты истекут. Мои результаты (MBP 2014 - 16 ГБ ОЗУ):
Общее время пробега = 61,83 с.
Просто для удовольствия
Это заняло около 210 секунд.
источник
n = 12
требуется примерно 18 ГБ памяти.n=13
. Вы можете изменить13
в строке от последней к последней, чтобы она вычисляла все, что вы пожелаете.)Python 2
Это очень простое решение и, вероятно, не выиграет конкурс. Но эй, это работает!
Я дам краткий обзор того, что именно происходит.
n
. Например, когдаn=2
это сгенерирует массив длиной 2 n + 1 , где каждая строка имеет длину 2n-1. Это будет выглядеть следующим образом :[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
.n
раз и отрезаю первыеn
элементы, чтобы сгенерировать соответствующую матрицу, и использую ееscipy
для вычисления определителя, сохраняя при этом отслеживание максимального значения. В конце этого я просто распечатываю максимум с шагомn
1 и продолжаю, пока не пройдет 10 минут.Для запуска вам понадобится Scipy .
Редактировать 1: Изменено, как начальные строки были построены с использованием вместо этого itertools.product, спасибо Sp3000!
Редактировать 2: Удалено хранилище возможных начальных строк для минимального улучшения скорости.
Изменить 3: Изменено, чтобы
scipy
иметь больше контроля над тем, какdet
работал.Вот пример выходных данных на моем домашнем компьютере (i7-4510U, 8 ГБ ОЗУ):
источник
C ++
Bruteforce с использованием OpenMP для распараллеливания и простой оптимизации, чтобы избежать оценки определителя для транспонированных матриц.
источник
С
Компилировать с:
Бежать с:
Может вывести максимальный определитель в течение
n = 1..10
~ 115 секунд на моем компьютере.Программа просто получает определитель каждой возможной двоичной матрицы Тёплица с размером
n
, однако каждый определитель матриц размера5x5
или меньше будет кэшироваться с использованием мемоизации.Сначала я ошибочно предположил, что каждая подматрица матрицы Тёплица также будет матрицей Тёплица, поэтому мне нужно было только запоминать
2^(2n-1)
значения вместо2^(n^2)
каждогоn
. Я сделал программу до того, как осознал свою ошибку, так что это представление - просто исправление этой программы.источник
O(n!)
сложность, поэтому вам лучше использовать другой алгоритм.O(n^3)
, я считаю, хотя можно быстрее с некоторыми интересными алгоритмами. Я полагаю, что большинство встроенных функций, используемых здесь, обычно используют вариант декомпозиции для выполнения определителей.O(n^2)
алгоритм, если я обновляю свой ответ.O(n^2)
. Но я думаю, что узким местом проблемы является поиск средиO(4^n)
множества 0-1n
поn
матрицам.р
Вам придется установить R и пакеты, перечисленные с
install.packages("package_name")
Не получалось менее 2 минут на моей машине с этой версией (я должен попробовать с параллельной модификацией)
Вызов и выход:
Бенчмарк на моей машине:
Для информации, для диапазона 1:11, это занимает 285 секунд.
источник
PARI / GP, n = 11
Это грубая сила, но она пользуется
det(A^T) = det(A)
. Я только публикую это, чтобы продемонстрировать, как легко пропустить транспонирование. Самый младший битb1
содержит верхнюю левую ячейку, а остальные биты содержат остаток верхней строки.b2
содержит остаток левой колонки. Мы просто применяемb2 <= (b1>>1)
.Что касается вычисления детерминантов Теплица во
O(n^2)
времени: в моем ограниченном исследовании я постоянно сталкивался с требованием, чтобы все ведущие главные миноры были ненулевыми, чтобы алгоритмы работали, что является основным препятствием для этой задачи. Не стесняйтесь указывать мне, если вы знаете об этом больше, чем я.источник
e_{k+1}
имеет в 4 раза больше компонентов, чемe_k
. В статье много упущений. Обратимая матрица имеет LU-разложение, если все ведущие главные миноры отличны от нуля. (Обратите внимание на знаменатели, напримерa_0
- неявно они гарантированно не равны нулю.) Уникальность исходит из того, что L является единичным треугольником. Автор также не упомянул численную стабильность. В случае, если ссылка становится недоступной, статья «О вычислении детерминантов матриц Теплица» Хсуан-Чу Ли (2011).