
Кольца Барромео — это конструкция из трёх колец, обладающая интересным свойством: эти кольца не сцеплены попарно между собой, но полная конструкция из трёх колец неразделима. Ну или если перефразировать: вся конструкция неразделима, но если любое из колец магическим образом пропадает, то оставшиеся два можно разделить. Единственное известное мне практическое применение этих колец — использование в качестве логотипа пива Ballantine. В прошлом году в моей практике повстречался интересный алгоритмический баг, который у меня ассоциируется именно с этой конструкцией.
Сразу скажу, что в последующем повествовании математика заметна упрощена. Итак, я работал над некоторой системой, которая решала задачу максимизации с помощью градиентного подъема (как градиентный спуск, но для максимизации), т. е. строила следующую последовательность
В какой-то момент градиентный подъем было решено заменить на метод побыстрее, попробовали метод Ньютона и в итоге получили работающую систему в виде, в котором она попала мне попробовать еще её ускорить. На моё удивление любые попытки как-то улучшить сходимость известными стандартными техниками приводили к полностью противоположному результату, что-то явно было не так, но я никак не понимал что именно. После долгой ревизии я все-таки кое-что заметил, итак вот форма метода Ньютона, которая я обнаружил
Что-нибудь заметили?
А вот в чем проблема
неправильный знак
Проиллюстрирую её на небольшом примере: допустим мы хотим найти максимум функции

Легко проверить, что у этой функции два максимума . Метод Ньютона по указанной выше формуле строил бы последовательность
Приводить дальше это выражение не буду, его уже можно анализировать: если , то дробь в выражении выше положительна, а значит если
, то последовательность возрастает и, более того, расходится. Хмм, как-то странно для метода Ньютона. Ну да ладно, я уже достаточно написал текста для тех, кто хотел разобраться сам и не хотел спойлеров в поле зрения. Проблема в знаке дроби, там должен быть минус, можете поэкспериментировать со следующим кодом и убедиться, что при
wrong_sign=True
метод почти всегда расходится
def newton_method_example1(x0, wrong_sign):
for i in range (10):
step = (x0 - x0 ** 3) / (1 - 3 * x0 ** 2)
x0 = x0 + (step if wrong_sign else -step)
print(x0)
return x0
newton_method_example1(2., True)
А вот с wrong_sign=False
метод сходится, но возникает другая особенность метода Ньютона: он будет сходиться к или
. Почему
? Это локальный минимум функции и, как оказывается, метод Ньютона для поиска минимума или максимума имеет одинаковую форму в отличие от градиентного спуска. Например для функций
и
метод Ньютона бы имел одинаковую форму
в первом случае искал бы минимум, а во втором максимум. В ситуации выше в зависимости от начальной точки мы попадём либо в максимумы, либо в локальный минимум
. Если быть точнее, то для выпуклых функций метод Ньютона ищет минимум, для выпуклых вверх — максимум. Функция
меняет свою кривизну в точках
и из-за этого возникают спецэффекты.
Итак, мы выяснили, что проблема была в знаке. Казалось бы, меняем знак и всё должно заработать, так и сделал — всё сломалось. В предыдущем примере метод Ньютона с неправильным знаком расходился, а у нас же изначально система с неправильным знаком работала, а после его замены перестала работать. Опять что-то не сходится, почему изначально всё работало, а при исправлении знака сломалось? Самое время посмотреть, что за функцию мы пытаемся оптимизировать, как оказалось это что-то вида

Интересна эта функция тем, что она выпукла, а значит метод Ньютона по идее должен искать у неё минимум. С другой стороны очевидно, что минимума у неё нет, есть максимум в нуле, в котором она еще и не дифференцируема. Что же будет, если мы применим метод Ньютона к этой функции? Давайте проверим, если , то правильный метод Ньютона будет иметь вид
а неправильный
а значит неправильный будет сходиться, а правильный не будет. В итоге вот что имеем:
Метод Ньютона не должен работать с неправильным знаком
Метод Ньютона не должен работать с неправильный функцией
Градиентный спуск с неправильным знаком и неправильной функцией также не работает
Внезапно метод Ньютона с неправильным знаком и неправильной функцией работает!
Эпилог
Как я сказал, ситуацию я довольно сильно упростил, мне понадобилось много времени, чтобы осознать происходящее в реальной системе. Пока я не увидел все три компоненты, то не осознал что и почему не работает, а они не лежали передо мной в явной форме. В описанной ситуации эффект колец Барромео негативен, но существуют и ситуации когда подобные объекты наоборот приносят пользу. Например в криптографии есть задача о разделении секрета: вам нужно научиться преобразовывать объект таким образом, чтобы его можно было разделить на частей и при этом из любых
этих частей можно было восстановить исходный объект, но никаких
частей недостаточно чтобы даже частично его восстановить. Решение такой задачи существует, например схема Шамира, она мало имеет общего с кольцами Барромео, но они всё еще представляют собой хорошую иллюстрацию эффекта.
Комментарии (0)
Yami-no-Ryuu
16.09.2025 05:02А что мешает выбирать направление следующего шага? Какая-то надуманная проблема.
malkovsky Автор
16.09.2025 05:02Ничего не мешает. Посыл в другом: я занимаюсь R&D и мы постоянно экспериментируем с разными методами, ошибки так или иначе случаются и их комбинации иногда приводят к очень странным узлам.
belch84
16.09.2025 05:02Вот представление колец Борромео в виде трёх трёхмерных параметрических кривых (эллипсов)
Анимированное изображение эллиптических колец Борромео
Анимированное изображение более сложных изогнутых колец Борромео
Oldgreen17
16.09.2025 05:02Градиентный спуск всегда сходится из любой начальной точки (если сходится), но требует больше итераций. Метод Ньютона требует примерно на порядок меньше итераций, но может расходиться. Существуют гибридные способы поиска экстремума, где сначала применяется градиентный спуск, а после (в локальной области) — метод Ньютона, что позволяет уменьшить количество итераций до сравнимого с методом Ньютона, обеспечив сходимость.
malkovsky Автор
16.09.2025 05:02Градиентный спуск всегда сходится из любой начальной точки (если сходится)
Как-то очень странно вы написали. Возможно вы имели в виду, что как для градиентного спуска, так и для метода Ньютона гарантии сходимости есть только в случае выпуклости функции, но методу Ньютона дополнительно нужно еще достаточно близкое начальное приближение. Посыл был в том, что методы применялись в ситуациях, в которых теоретических гарантий в принципе нет. На текущий момент самое распространённое применение градиентного спуска - обучение нейросетей, где также нет никаких теоретических гарантий.
Asterris
Химики давеча научились молекулы завязывать в кольца Борромео. Получаются молекулы без химической связи