Entry tags:
задачка (программирование)
Мне эта задачка попалась недавно на сайте программистских соревнований, когда я помогал кое-кому готовиться к интервью и искал материал для интересных вопросов. Она мне понравилась тем, что я не смог ее быстро решить.
Комментарии я скрывать не буду - если хотите предложить там свое решение, то пожалуйста, если хотите подумать сами, не заглядывайте туда.
P.S. Я бы сказал, опираясь на собственный опыт, что эта задача несколько сложнее, чем типичная алгоритмическая задача на интервью в Гугле. Если вы можете эту задачу решить и за 45 минут написать работающий код, за разумное время дающий правильный ответ - ваш уровень по крайней мере в алгоритмах вполне подходит и даже превосходит то, что в Гугле просят продемонстрировать на интервью.
Вы - авиадиспетчер, которому нужно посадить N самолетов в аэропорту, у которого только одна посадочная полоса. Про каждый самолет известно окно времени, в которое он может безопасно приземлиться - оно задается в минутах, от 0 до 1440. Например, про один самолет может быть известно, что его можно посадить в любое время от 7-й минуты до 300-й включительно, про другой - в любое время от 100-й до 200-й, и так далее. Предположим, что вы для каждого самолета выбрали время посадки (его можно задать с точностью до секунды). Будет какое-то минимальное временное расстояние между посадками самолетов. Ваша задача -- это минимальное расстояние максимизировать.
На вход вам дается: число самолетов N, от 2 до 8; для каждого самолета начальная и конечная границы окна, от 0 до 1440. На выход вы должны дать: максимальное значение минимального расстояния между посадками, которое вы беретесь обеспечить.
Комментарии я скрывать не буду - если хотите предложить там свое решение, то пожалуйста, если хотите подумать сами, не заглядывайте туда.
P.S. Я бы сказал, опираясь на собственный опыт, что эта задача несколько сложнее, чем типичная алгоритмическая задача на интервью в Гугле. Если вы можете эту задачу решить и за 45 минут написать работающий код, за разумное время дающий правильный ответ - ваш уровень по крайней мере в алгоритмах вполне подходит и даже превосходит то, что в Гугле просят продемонстрировать на интервью.
no subject
no subject
no subject
no subject
(no subject)
(no subject)
no subject
Вход: (N окон, Start time, End Time)
Для всех самолетов А из N
- выбрать А первым самолетом в расписании посадок
- Назначить ему время посадки T_A - самое раннее из возможных
- Найти такое T', что
(Уравнение 1): (T'-T_A) = FindMaxMinGap(N-1 оставшихся окон, T', End Time)
(если такого нет, то наибольшее T', для которого левая часть меньше правой)
- вернуть (T'-T_A)
Если N=1, вернуть T_E - Start_time, где T_E = самое позднее время посадки данного самолета.
Ключевой момент - поиск T'. Здесь мы замечаем, что FindMaxMinGap - невозрастающая функция от второго параметра (Start Time), поэтому решение уравнения (1) можно провести бинарным поиском - т.е. порядка 16 попыток для 86400 возможных позиций. Итого сложность будет где-то 16^N * (N!).
no subject
первый самолет посадить в минимальную границу, последний - в максимальную.
Остальные самолеты первоначально расположить произвольно. Затем рассчитать попарные расстояния между соседними. понятно, что расстояния между не-соседними можно не принимать во внимание. после этого начать усреднять эти расстояния. В качестве начальной пары можно взять минимальное и усреднить с бОльшим из соседей. Далее цикл повторяется. Если новое значение оказывается за пределами окна для данного самолета - оставить на ближайшей к этому значению границе.
Поннятно, что при таком алгоритме минимальное расстояние не уменьшается, и ограницено сверху значением 1440/(N-1), поэтому имеет предел. Установить порог изменения в 1 секунду, после чего цикл обрывать при изменениях меньше секунды.
Насчет скорости сходимости алгоритма - надо подумать, сходу кажется, что количество операций - полином от N.
no subject
(no subject)
no subject
Делением пополам перебираем размеры минимального расстояния (log(1440/(N-1)).
Пытаемся расставить самолеты с заданным минимальным расстоянием и в заданном порядке (легко сделать за один проход).
Итого: O(N*N!*log(1440/(N-1))) - при ограничении на N <= 8 должно давать разумное время.
no subject
(no subject)
no subject
no subject
no subject
(no subject)
(no subject)
(no subject)
no subject
Но вот что с перестановками делать - ума не приложу.
no subject
no subject
должно сработать. конечно, при таком алгоритме порядок посадки самолетов не изменится, так что на глобальный оптимум не надеемся. но можно попробовать несколько раз с первыми случайными распределениями (т.е. с разной очередностью).
no subject
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
no subject
Почему ? Как ?
(no subject)
(no subject)
(no subject)
(no subject)
no subject
no subject
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Ставим все времена на левые края окон.
Берем 1 самолет и двигаем его по его интервалу - если какое то новое положение 1го самолета дает общий выигрыш, то оставляем его.
Берем 2 самолет и двигаем ...
...
Берем N самолет и двигаем...
И снова берем 1 самолет ...
Продолжать, пока не получим, что ни один из N самолетов нельзя переставить не ухудшив результат.
no subject
no subject
no subject
- Ищем min левых границ и max правых, этот диапазон разбиваем на равные N-1 частей - получаем "идеальные" точки
- Смотрим, диапазоны, не покрывающие ни одной, ищем среди них минимальное расстояние от границы диапазона до одной из точек, сдвигаем её на границу диапазона, отрезки по обе стороны переразбиваем, диапазон и точку убираем из рассмотрения
- Смотрим точки, не покрытые ни одним диапазоном, та же процедура
- Все диапазоны покрывают хотя бы одну точку и каждая покрыта хотя бы одним диапазоном - можно распределить без дальнейших сдвигов времени вылетов - не будем этого делать, просто смотрим минимум, это результат
В каком случае такой подход ломается?
no subject
(no subject)
(no subject)
no subject
Будем рассматривать частичные последовательности, хранить их в приоритетной очереди и расширять, начиная с текущуей отимальной.
Начнём с (1,2) и (2,1), где цифры - номера самолётов. Пусть в первой интервал меньше, тогра по ней строим (3,1,2), (1,3,2), (1,2,3).
Невозможные выкидываем, медлыенные ставим на нужное место в очереди. Возможно, в оценке медленности стот добавить длинну последовательности.
Ещё пара эвристик - заранее выкинуть невозможные двойки и тройки, на случайных данных они должны хорошо сократить количество вариантов.
PS. Хочу узнать правильный ответ ))
no subject
no subject
no subject
Во-первых, никаких симплекс-методов и т.д. такие задачки не подразумевают. Даже думать в эту сторону не надо.
Во-вторых, ограничение на N от 2 до 8 нам явно говорит о том, что ожидаемое решение подразумевает перебор N! А иначе, почему N такое маленькое ?
И в-третьих, вот это mim max условие максимальное значение минимального расстояния очень напоминает пример FairWorkload отсюда (http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binarySearch)
no subject
(no subject)
(no subject)
(no subject)
no subject
no subject
Перебираем N! перестановок самолётов (для N=8 это вполне обозримое количество - 40320 гипотез) задающих очерёдность захода на посадку.
Каждый самолёт сажаем как можно раньше, - разумеется, строго после предыдущего.
Находим минимальное время.
no subject
no subject
Еще я не заметил, что самолетов "до 8" - это сразу сводит задачу к "все пермутации и больше ни о чем не думай".
Как решавший эту задачу на практике - выстраивание очереди кораблей к причалу - практически те же условия, как и у самолетов, добавлю, что на практике такое решение не очень годится, если очередь из 20-30.
no subject
Тогда, конечно, все перестановки и пошло оно нах.
no subject
no subject
no subject
звучит как требование сделать одно расстояние максимально большим, но не оптимизировать весь набор
ставим всех на начало интервала, последнего на конец интервала и затем двигаем в минимальной паре тот самолет на секунду наружу, чей третий сосед дальше. для малых Н должно сработать за разумное время
no subject
(no subject)
(no subject)
no subject
В худшем случае исходную задачу быстрее решить не удастся, но если интервалы случайно распределены, то или оптимальное время на какой-нибудь перестановке получим или самих перестановок будет существенно меньше, чем N!
no subject
https://github.com/Alexander-Panin/planes/blob/master/my.py