Как стать автором
Обновить
77
4
Владислав @rebuilder

Разработчик

Отправить сообщение

Не утверждаю, что решение с ЦЛП - серебряная пуля.

Возможно, решение находится не всегда быстро, но по памяти более гуманно факт.

Алгоритм ДП, что я рассматривал, очень неэффективен по сравнению с тем, что предоставили Вы.

Беру свои слова назад, в такой реализации ДП на многих наборах обходит мою версию ЛП.

Любопытно, на некоторых наборах сильно лидирует ЛП, но если проигрывает, то часто значительно, тогда как ДП более стабилен. Как вариант интересно устраивать гонку алгоритмов, какой финиширует первым.

Однако меня огорчил тот факт, что на больших наборах входных данных, памяти ДП всё же не хватает, и он не выполняется с ошибкой:

MemoryError: Unable to allocate 14.2 GiB for an array with shape (15207959671,) and data type bool.

n = 200
t = 15207959670
source = [118034063, 176397250, 108470054, 134234785, 115826780, 166496171, 160329669, 163383683, 187455328, 150951092, 128179657, 112597620, 165479012, 103804733, 152319252, 158085012, 181528947, 100282669, 193393106, 159778857, 135746282, 196843463, 130703945, 179343270, 113720696, 142604684, 104105718, 102996023, 103415285, 187180606, 172667152, 101235465, 151164366, 192138303, 129071478, 156655527, 197422287, 103897788, 170817221, 129754951, 158772277, 166546792, 174203556, 131284065, 146399124, 130986382, 190845073, 129364293, 161686932, 138893829, 102884299, 155858725, 174686034, 186207290, 113421809, 124951916, 184470316, 197125183, 139780845, 116225575, 199743456, 144653591, 196835997, 195454543, 167216197, 156654242, 168144655, 189966890, 125481199, 140717432, 138139224, 178863733, 167023240, 167818046, 152795029, 179054544, 104633978, 164454973, 132580007, 199821838, 154262629, 155608283, 189220365, 123220660, 149274526, 173658522, 194360533, 190527955, 199081602, 150291788, 111605483, 158916432, 189088064, 168239848, 114486288, 121971213, 169919170, 152781805, 149730710, 165725551, 198350162, 103969484, 162991083, 105836765, 141410118, 194406345, 182518497, 179615772, 177601456, 152828055, 186859830, 122863882, 122628343, 167409318, 130459014, 101651090, 126778633, 172426227, 173596743, 131162152, 154285013, 168957265, 146147529, 177550306, 147415655, 161623617, 136142079, 188478314, 173550819, 181731190, 197898435, 100766266, 151497950, 199388685, 168786576, 117347564, 169615820, 175344177, 127579764, 157188922, 107532741, 164572392, 148954043, 176504015, 174410468, 126821992, 167742434, 155485614, 165085546, 147887538, 155623117, 146449792, 100212701, 172273400, 172492277, 183683337, 182201978, 144444516, 161491422, 180511200, 103754738, 130817065, 185278064, 123784892, 173921254, 178445010, 124264416, 112294532, 173957878, 134264986, 104356590, 190343768, 109456105, 111171496, 102240178, 160800468, 101954206, 137741579, 133495272, 136056483, 114695314, 183859516, 124777959, 146227654, 138961302, 109330196, 122477484, 121424575, 134254527, 170783798, 122568032, 188134944, 136629955, 187000307, 195507983, 139526151, 161029019, 194304805, 143218345, 166638250]

solution optimized = [176397250, 166496171, 160329669, 163383683, 187455328, 165479012, 181528947, 193393106, 159778857, 179343270, 187180606, 172667152, 192138303, 197422287, 170817221, 166546792, 174203556, 190845073, 161686932, 174686034, 186207290, 184470316, 197125183, 199743456, 196835997, 195454543, 167216197, 189966890, 178863733, 167023240, 179054544, 164454973, 199821838, 189220365, 173658522, 194360533, 190527955, 199081602, 158916432, 189088064, 169919170, 165725551, 198350162, 194406345, 182518497, 179615772, 177601456, 186859830, 167409318, 172426227, 173596743, 168957265, 177550306, 188478314, 173550819, 181731190, 197898435, 199388685, 168786576, 169615820, 175344177, 164572392, 176504015, 174410468, 155485614, 172273400, 172492277, 183683337, 182201978, 180511200, 185278064, 173921254, 178445010, 173957878, 190343768, 160800468, 183859516, 170783798, 188134944, 187000307, 195507983, 161029019, 194304805, 143218345, 166638250]

И ещё проблема, что решение должно быть точным, а любая микро-погрешность не найдёт решение Xi in {0,1}, посчитается какой-нибудь Xi=0.99999 и всё, вариант отсечётся. То есть, я думаю, тщательное тестирование на очень сложных случаях покажет, что этот метод не всегда даёт правильный результат.

Это зависит от качества решателя. Если под капотом используются float64, так и бывает у большинства решателей.

Однако, как я считаю хороший решатель должен работать с натуральными дробями, и тогда погрешность не возникает совсем.

ДП больше пары десятков элементов у меня не тянет. Тот алгоритм что я использовал сжирает всю память для кэша.

Возможно алгоритм что не хранит всё кэше и вывезет. Но если предположить, что по скорости алгоритм с меморизацией и без равны, то навряд ли сравняется с ЛП.

Выигрыш есть, именно для этого пост и писался. Только что бы это показать нужно смотреть на практике. Выигрыш очень велик, когда количество чисел превалирует над размером.

n = 100
val = 77019193
source = [1885440, 1403958, 1794772, 1933488, 1441001, 1042450, 1271493, 1536110, 1509532, 1424604, 1962838, 1821872, 1870163, 1318046, 1499748, 1375441, 1611720, 1934973, 1952225, 1229053, 1529202, 1146039, 1295528, 1146534, 1792518, 1099437, 1648406, 1838234, 1262674, 1953938, 1558433, 1739426, 1849574, 1631140, 1945989, 1154100, 1325213, 1103560, 1765284, 1077324, 1942500, 1891786, 1717209, 1346236, 1495077, 1587007, 1105592, 1370977, 1455262, 1331556, 1640561, 1671532, 1957361, 1214410, 1579363, 1500181, 1464197, 1907343, 1546678, 1273145, 1065304, 1844132, 1963080, 1575352, 1960489, 1014723, 1097802, 1754665, 1880899, 1418196, 1744754, 1864912, 1823182, 1700609, 1655638, 1001198, 1641620, 1517553, 1868287, 1909747, 1349317, 1255759, 1765752, 1341001, 1737822, 1912755, 1066043, 1200348, 1961564, 1595078, 1232473, 1250206, 1842368, 1149416, 1842194, 1569366, 1469730, 1095646, 1084353, 1335601]

solution optimized = [1794772, 1933488, 1536110, 1509532, 1962838, 1821872, 1870163, 1611720, 1934973, 1952225, 1792518, 1648406, 1838234, 1953938, 1558433, 1631140, 1945989, 1942500, 1891786, 1717209, 1640561, 1671532, 1957361, 1579363, 1907343, 1546678, 1844132, 1963080, 1960489, 1880899, 1864912, 1823182, 1700609, 1641620, 1517553, 1868287, 1909747, 1765752, 1912755, 1961564, 1842368, 1842194, 1569366]
time = 4.474821

Динамическое программирование требует очень много память на больших N и P. Линейное в этом смысле сильно выигрывает, но у него плохо со стабильностью результатов, уже больно оно зависит от набора входных данных. На некоторых наборах выигрыш феноменален, не некоторых экспонента всё портит. Но по моим наблюдениям в среднем разы рвёт ДП.

На случайных наборах результат очень хороший, особенно когда допустимых решений много.

Если вы приложите набор тестовых данных, то могу протестировать.

То, что задача NP - полна коллега вроде и не оспаривал. Видимо он хотел указать, что сложность задачи зависит не только от числа элементов (N), но и от точности (P) и это не имеет отношение к NP-полноте. Я не верно понял?

Вы правы. Мне не хотелось излишне усложнять текст.

Так как для чисел порядка миллиарда, число двоичных разрядов практически не имеет значения, то я несколько упростил повествование.

Скорее забэкапить крайний дамп... в облако?

Да, это эпичный феил! На простых кейсах такого не наблюдалось, а вот когда точки как забор и легли улиткой.

Спасибо! Осознал, признаю ошибку! Вам + в карму, буду думать. Хорошие кейсы.

обводил по точкам.

Правильная триангуляция
Правильная триангуляция

Иногда даже удивительно как выбираются рёбра

В том то и дело, что такое поведение как вы нарисовали, невозможно. Как только вы приводите алгоритм к граничному состоянию, весь маршрут перестраивается полностью. Ещё в прошлой статье с окружностями подметил эту тенденцию, но там подход был не совсем верным. Я очень долго моделировал общее решение, в том числе и с триангуляциями. И только триангуляция Делоне даёт нужный результат. С остовыми деревьями такого эффекта нет.

Конечно, мне повезло, только не в том смысле, что решение случайное. В статье про ветви и границе, лично Вы, предлагали мне поискать эвристику через эвклидово расстояние. И вот, спустя год, я предлагаю вам решение, код для проверки, а вы ещё требуете доказательства.

Моё понимание математики находится не на том уровне, чтобы вывести доказательство в виде формул. Однако, определённые основания утверждать, что граф содержит точное решение у меня есть. Хотелось бы получить контрпример со стороны сообщества или хотя бы выкладку, почему я не прав.

В работе описаны два алгоритма, первый для плоскости он быстрее, второй для общей задачи коммивояжера (в том числе для молекулярной структуры), он медленнее, но так же решается точно.

Это как если у вас был бы спортивный автомобиль для ровных дорог, и кроссовер для бездорожья.

Звучит как вызов. Теоретически наверно можно замахнуться на n = 6, но это уже на грани.

Нет, тут всё проще. 39800 переменных – это и есть n^2-n, от 200 вершин.

Изначально решается матрица 39800 x 400. На следующих шагах, она станет немного больше по высоте, но не так уж сильно (в 2-4 раза). Шагов за 15-30 (в худшем случае n/2) алгоритм находит решение такого размера. Так что всё не как уж и печально. Кроме того солверы обычно наделяют различными методами, ускоряющими решения.

Размерность многомерного пространства и правда будет очень высокой. Пример: для направленного графа на 200 вершин = 39800 мерное пространство. Но это уже сложность решателя линейных уравнений, его для этого и делают.

1
23 ...

Информация

В рейтинге
885-й
Откуда
Краснодарский край, Россия
Зарегистрирован
Активность