Всем привет! :)
На случай, если вы пропустили рассылку, сообщаем, что сегодня в 10:00 UTC +3 стартовал второй раунд Оптимизационного трека. Как и первый раунд, он продлится 7 дней. Вам предложена одна задача, которая не предполагает наличие полного решения, но допускает множество подходов. По результатам двух раундов (смотрите раздел 3 в https://contest.yandex.ru/algorithm2018/rules/ — правила суммирования раундов одинаковы для алгоритмического и оптимизационного треков) будут определены победители трека и 128 будущих обладателей футболок с символикой конкурса.
Мы подготовили для вас задачу, которая симулирует работу поискового робота. Предлагаем вам ощутить на себе сложности индексации сайтов и постараться оптимизировать обход интернета — это всего лишь одна из задач, которую в Яндексе решают разработчики. Разумеется, задача была достаточно сильно упрощена, поскольку на её решение у вас всего неделя, но сможете ли вы научиться назначать сайты роботам достаточно оптимально?
Регистрация на конкурс еще открыта, так что всё в ваших руках — удачи!
Hi! When the final testing results are going to be published?
Also I really wonder what were the solutions that reach 8500+ on current standings. Could someone share one of those ideas, please?
Out of curiosity, one more question regarding the real-world application inspiration of the problem statement. I understand that it would make sense for robots to follow some kind of a repeating list of sites — to save memory, for example. However, why do robots' paths have to be cycles in the links graph and not just a repeating list of any sites, not necessary connected in a cycle?
Final standings are published!
Some 8300+ ideas:
8150+: greedy solution constructing cycles one by one: pick starting site randomly and choose next site that has a topic with minimum current "score contribution" (*timeToIndex[site] / newsProb[site]). When I add a new site to a cycle I update scoreContribution(topic) += newsProb[site] / timeToIndex[site] for all topics published on that site. When there are enough (C = n/r/2) sites per cycle I use Dijkstra to finish the cycle (C doesn't seem to matter too much)
8250+: repeat previous algorithm multiple times and pick the "best" solution. ("best" is not always the best because there is a lot of variance in the scores because of randomness)
8300+: pick the topic TM with the lowest score and try the previous greedy algorithm ignoring TM (explanation: if a topic doesn't bring any points let the robots focus on other topics)
8350: Fix one TLE by stopping slightly earlier :)
I suspect one can get to 8500+ by speeding up the simulation step (currently only 10-30 random starting points can be tested because of slow list/sort/vector operations) and using an incremental approach where some sites are added only if they increase the overall score.
If I didn't miss anything you can see your final score in your last submission before results will be published
Nice hacker skills! That's not the final scoreboard, but it's something.
Now I know that my solution has Runtime Error only on 1 test out of 500. I guess I got that going for me which is nice. :D
Общая схема
Для начала заметим, что в 1/8 случаев робот всего один, поэтому научиться генерировать хотя бы один хороший цикл всё равно придётся. После того, как это сделано, оказывается, что неплохо работает Hill Climbing, на каждом шаге пытающийся обновить ответ, заменив произвольный цикл на случайно сгенерированный. Кроме этого, оказывается, что более сложные подходы, например отжиг вместо HC или попытка как-то достраивать имеющееся решение, работают плохо.
Генерация циклов
Это основная часть решения. От качества эвристики при генерации циклов зависит практически всё (скорость генерации и оценивания имеет гораздо меньший эффект, например). На среднего размера тесте HC у меня делает пару десятков обновлений ответа на несколько десятков тысяч итераций, т.е. мы ищем иголку в стоге сена, и направленность поиска предельно важна.
Будем каждый раз возвращать случайный цикл из какого-то контролируемого эвристиками распределения. Цикл генерируется без оглядки на уже имеющиеся, на количество роботов и на предыдущие попытки. Всё взаимодействие между роботами таким образом перекидывается на функцию оценки решения, а на этапе генерации можно считать, что робот один.
Цикл можно генерировать так: стартовав из случайной вершины, каждый раз переходить жадно в лучшую по набору параметров. Получится путь, из которого потом можно выбрать две случайных вершины u и v, взяв в ответ подпуть от u до v, если есть ссылка . Если её нет, можно выбрать другие случайные вершины. Необязательно делать так, чтобы u совпадала с началом пути. Одной и той же вершине можно запрещать появляться в пути дважды, а можно не запрещать. Это практически не влияет на результат.
Теперь об упомянутом "наборе параметров".
Оценка решения
Лучше всего работает метод Монте-Карло, т.е. переписывание кода из чекера.
Что ещё не работает
Вот ещё несколько идей, которые мне не удалось использовать для улучшения счёта.