Это задача с наименьшим количеством операций, цель которой состоит в том, чтобы отсортировать вектор по возрастанию, используя наименьшее количество обращений. Ваш алгоритм может сортировать вектор только с использованием «инверсий субвекторов» 1 , но он может использовать другие операции для арифметических операций, циклов, проверки его сортировки и т . Д. Число инверсий субвекторов, которые выполняет ваш алгоритм, - это его оценка.
1 «Подвекторное обращение»:
- Выберите диапазон чисел в векторе и поменяйте местами элементы в этом диапазоне.
Чтобы привести простой пример, если вы начинаете с вектора {4,3,2,1}
, то вы можете отсортировать его различными способами:
- Обратный весь вектор. Это, очевидно, самый короткий подход, поскольку он требует только одного обращения:
{4,3,2,1} -> {1,2,3,4}
- Вы можете сделать версию пузырьковой сортировки, которая требует 6 разворотов:
{4,3,2,1} -> {3,4,2,1} -> {3,2,4,1} -> {2,3,4,1} -> {2,3,1,4} -> {2,1,3,4} -> {1,2,3,4}
- Вы можете начать с первых 3 элементов, затем с трех последних и, наконец, с двух первых и двух последних, что требует 4 перестановок:
{4,3,2,1} -> {2,3,4,1} -> {2,1,4,3} -> {1,2,4,3} -> {1,2,3,4}
- ... и так далее. Существует бесконечное количество доступных вариантов (вы можете повторить любую операцию, если хотите).
Правила и требования:
Ваш код должен завершиться менее чем за одну минуту для списка из 100 номеров. Вы можете рассчитать это самостоятельно, но, пожалуйста, играйте честно 2 .
Вы должны сохранить начальный и конечный индексы всех выполненных обменов, чтобы решение могло быть проверено. (Я объясню, что это значит ниже).
Код должен быть детерминированным.
Вы можете использовать входные данные в любом формате: числовой вектор, связанный список, массив с длиной ... все что угодно.
Вы можете делать что угодно на копии вектора. Это включает в себя попытки различных разворотов и проверки, которая является наиболее эффективной. Грубое принуждение прекрасно, но придерживается ограничения по времени.
Оценка - это общее количество сальто для 5 тестовых векторов. Тай-брейк будет с отметкой даты.
Пример:
4 1 23 21 49 2 7 9 2 | Начальный вектор / список 4 1 2 9 7 2 49 21 23 | (2, 8) (перевернули элементы между индексами 2 и 8) 4 1 2 2 7 9 49 21 23 | (3, 5) 4 1 2 2 7 9 23 21 49 | (6, 8) 4 1 2 2 7 9 21 23 49 | (6, 7) 2 2 1 4 7 9 21 23 49 | (0, 3) 1 2 2 4 7 9 21 23 49 | (0, 2)
Счет будет 6, так как вы выполнили 6 разворотов. Вы должны хранить (не печатать) индексы, перечисленные справа, в подходящем формате, который можно легко распечатать / вывести для целей проверки.
Тестовые векторы:
133, 319, 80, 70, 194, 333, 65, 21, 345, 142, 82, 491, 92, 167, 281, 386, 48, 101, 394, 130, 111, 139, 214, 337, 180, 24, 443, 35, 376, 13, 166, 59, 452, 429, 406, 256, 133, 435, 446, 304, 350, 364, 447, 471, 236, 177, 317, 342, 294, 146, 280, 32, 135, 399, 78, 251, 467, 305, 366, 309, 162, 473, 27, 67, 305, 497, 112, 399, 103, 178, 386, 343, 33, 134, 480, 147, 466, 244, 370, 140, 227, 292, 28, 357, 156, 367, 157, 60, 214, 280, 153, 445, 301, 108, 77, 404, 496, 3, 226, 37
468, 494, 294, 42, 19, 23, 201, 47, 165, 118, 414, 371, 163, 430, 295, 333, 147, 336, 403, 490, 370, 128, 261, 91, 173, 339, 40, 54, 331, 236, 255, 33, 237, 272, 193, 91, 232, 452, 79, 435, 160, 328, 47, 179, 162, 239, 315, 73, 160, 266, 83, 451, 317, 255, 491, 70, 18, 275, 339, 298, 117, 145, 17, 178, 232, 59, 109, 271, 301, 437, 63, 103, 130, 15, 265, 281, 365, 444, 180, 257, 99, 248, 378, 158, 210, 466, 404, 263, 29, 117, 417, 357, 44, 495, 303, 428, 146, 215, 164, 99
132, 167, 361, 145, 36, 56, 343, 330, 14, 412, 345, 263, 306, 462, 101, 453, 364, 389, 432, 32, 200, 76, 268, 291, 35, 13, 448, 188, 11, 235, 184, 439, 175, 159, 360, 46, 193, 440, 334, 128, 346, 192, 263, 466, 175, 407, 340, 393, 231, 472, 122, 254, 451, 485, 257, 67, 200, 135, 132, 421, 205, 398, 251, 286, 292, 488, 480, 56, 284, 484, 157, 264, 459, 6, 289, 311, 116, 138, 92, 21, 307, 172, 352, 199, 55, 38, 427, 214, 233, 404, 330, 105, 223, 495, 334, 169, 168, 444, 268, 248
367, 334, 296, 59, 18, 193, 118, 10, 276, 180, 242, 115, 233, 40, 225, 244, 147, 439, 297, 115, 354, 248, 89, 423, 47, 458, 64, 33, 463, 142, 5, 13, 89, 282, 186, 12, 70, 289, 385, 289, 274, 136, 39, 424, 174, 186, 489, 73, 296, 39, 445, 308, 451, 384, 451, 446, 282, 419, 479, 220, 35, 419, 161, 14, 42, 321, 202, 30, 32, 162, 444, 215, 218, 102, 140, 473, 500, 480, 402, 1, 1, 79, 50, 54, 111, 189, 147, 352, 61, 460, 196, 77, 315, 304, 385, 275, 65, 145, 434, 39
311, 202, 126, 494, 321, 330, 290, 28, 400, 84, 6, 160, 432, 308, 469, 459, 80, 48, 292, 229, 191, 240, 491, 231, 286, 413, 170, 486, 59, 54, 36, 334, 135, 39, 393, 201, 127, 95, 456, 497, 429, 139, 81, 293, 359, 477, 404, 129, 129, 297, 298, 495, 424, 446, 57, 296, 10, 269, 350, 337, 39, 386, 142, 327, 22, 352, 421, 32, 171, 452, 2, 484, 337, 359, 444, 246, 174, 23, 115, 102, 427, 439, 71, 478, 89, 225, 7, 118, 453, 350, 109, 277, 338, 474, 405, 380, 256, 228, 277, 3
Я совершенно уверен, что найти оптимальное решение сложно с NP (поскольку регулярная сортировка блинов).
2 Да, люди с очень быстрыми компьютерами могут получить выгоду из-за ограничения времени в одну минуту. После долгих обсуждений я решил, что лучше всего, если каждый сделает свой собственный сравнительный анализ, это не самая быстрая проблема с кодом.
источник
n-1
флипами? Я могу доказать только нижнюю границу около 50.Ответы:
Java, генетический алгоритм, 80 + 81 + 79 + 78 + 80 = 398 (ранее
418)Перепробовав кучу разных идей и в большинстве случаев потерпев неудачу, я остановился на этом алгоритме: начните с входного массива, попробуйте все возможные инверсии и сохраните определенное количество результатов с наименьшим числом прогонов, затем делайте то же самое для тех результатов, пока мы получаем отсортированный массив.
Под «запусками» я подразумеваю максимальные подмассивы, которые появляются точно или в обратном порядке в отсортированном массиве. По сути, это максимально отсортированные подмассивы, но в случае повторяющихся элементов количество элементов в середине должно совпадать. Например , если отсортированный массив ,
2, 2, 3, 3, 4, 4
то4, 3, 3, 2
есть запустить , но2, 2, 3, 4
не является (и ни один2, 3, 2
).В этой версии я оптимизировал алгоритм для реверсирования только на границах прогона и только в том случае, если перевернутый прогон можно объединить с новым смежным прогоном. Кроме того, прогоны корректируются и объединяются на каждом шаге, чтобы избежать их пересчета из измененного массива. Это позволило мне увеличить «численность населения» с 30 до примерно 3000 и провести несколько симуляций разных размеров.
Ввод - это список чисел, разделенных запятой и / или пробелом (от стандартного ввода). Если вход пуст, программа запускает 5 тестов. Каждый из них занимает около 40 секунд здесь.
источник
Один ход грубой силы, затем сортировка выбора (также наивное решение), 90 + 89 + 88 + 87 + 89 = 443 хода
для каждого возможного первого шага, попробуйте его, а затем сделайте сортировку выбора.
Да, это еще одно наивное решение.
Я не уверен, что это должно быть редактирование или другой пост, но кажется, что решение слишком простое, поэтому редактирование выбрано.
Сортировка выбора (Наивное решение), 92 + 93 + 95 + 93 + 96 = 469 ходов
Наивное решение использует сортировку выбора.
Там должны быть какие - то более эффективные решения, но этот пост , так как я не нашел лучшего один (без поиска перебором).
(Выше кода JavaScript Shell )
источник