Поиск оптимального маршрута. Постановка задачи.
В этот понедельник с утра ребята спешили на работу. Ещё бы, нужно было прийти к 12:00 на планирование спринта! Свободный график — это здорово, но гибкие методологии разработки, скрам и всё такое...
Собрание прошло как обычно. Все получили задачи и пошли, кто код писать, кто ревью делать, кто статьи на хабре читать, кто новую кофемашину тестировать. Работать, в общем.
Гоше досталось очень ответственное задание. То есть ответственное оно было по словам руководителя. Картинка: руководитель: мы хотим оптимизировать работу всех наших серверов. Нужно доставлять на них обновления софта оптимальным способом. Некоторые из них в конкретный момент времени могут не работать или просто быть слейвами, нужно распространять пакеты на мастер-сервера. Распространять софт нужно по цепочке. Если на каком-то шаге не получилось поставить обновление, откатываемся. Так как картина может очень быстро меняться, нужно использовать быстрый алгоритм.
Гоша: Да-да, конечно, Иннокентий Еремеевич, изи задачка! Пойду потроллю Риту, покормлю рыбок в аквариуме и буду код писать!
И в общем-то сегодня уже пятница. Обычно в этот день проводится ретро, на котором все рассказывают о своих успехах за неделю.
Иннокентий особенно поинтересовался, как идут дела у Георгия с его задачей. Георгий сказал, что уже давно закомитил код, и он в ревью. Руководитель открыл репозиторий и начал смотреть.
Иннокентий: Расскажи-ка нам, что ты тут такое понаписал и как пришёл к такому решению?!
Гоша: Ну, это долгая история... Первой версией, значит, было по очереди на все сервера отправлять пакет и в случае неудачи останавливать процесс. Но потом Тимофей написал комментарий, что главный сервер не соединён со всеми напрямую. Так что пришлось подумать. Ну подумал я и вот к чему пришёл. У всех серверов есть id. Начинаем с главного сервера, остальные сортируем по их id. Проходим, значит, по этому списку, если к следующему пути от текущего нет, добавляем его в очередь и переходим к следующему. И каждый раз, когда у нас новый сервер, проверяем, можно ли из него попасть в те, которые в очереди. Вроде работает, я проверял! Даже тест написал, целых два теста!
Иннокентий: И какая сложность у этого алгоритма?
Гоша: Ну... Если сравнивать с моим первым вариантом, то по десятибалльной шкале я бы поставил 9 или даже 9,5. Пришлось с ним повозиться конечно! Но он готов! Ура!
Иннокентий: Ты шутишь?
Гоша: Нет, не шучу, правда готов.
Тимофей: Георгий, вопрос про алгоритмическую сложность. «O» большое и всё такое.
Гоша: Ах, это! Я немного подзабыл эту академическую информацию. Я всегда думал, что программисты в наше время в основном другими задачами занимаются.
Иннокентий: Георгий, я говорил, что решение должно быть эффективным. К тому же у нас в планах выход в новые регионы, и, соответственно, подключение новых серверов. Это нужно переписать!
Гоша: Да-да, я понял, конечно!
И пошёл Гоша думать над новым решением. Что-то гуглил из стандартной библиотеки, исследовал GitHub, пробовал добавлять побольше очередей, искал что-то существующее в проекте... И вот так настал вечер пятницы.
Алла: Гоша, ты чего сидишь, мы же в бар собирались!
Рита: Сегодня пятница, хватит работать!
Гоша: Ребят, вы идите, а я ещё подумать над задачей хотел.
Все ушли, и остался Георгий наедине со своим неэффективным алгоритмом, ну и рыбками в аквариуме.
Интересно, думает Гоша, вот это плывёт рыбка — самка или рыбка — самец?