Является ли этот частный случай задачи планирования разрешимым за линейное время?

12

У Алисы, студентки, есть много домашней работы в течение следующих недель. Каждый предмет домашнего задания занимает у нее ровно один день. Каждый элемент также имеет крайний срок и отрицательно влияет на ее оценки (допустим реальное число, бонусные баллы только при условии сопоставимости), если она пропустит крайний срок.

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

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

В альтернативной формулировке:

ACME Corp хочет поставлять воду клиентам. Все они живут на одной гористой улице. У ACME есть несколько колодцев, распределенных вдоль улицы. В каждой скважине достаточно воды для одного клиента. Клиенты предлагают разные суммы денег для поставки. Вода течет только вниз. Максимизируйте доход, выбирая, какие клиенты поставлять.

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

Мы можем легко решить эту проблему с помощью жадного алгоритма, если сначала отсортируем по убыванию степени влияния. Это решение будет не лучше, чем O (n log n).

Вдохновленный Медианой медиан и алгоритмами рандомизированного линейного минимального связующего дерева , я подозреваю, что мы можем решить мою простую задачу планирования / потока в (рандомизированное?) Линейное время.

Я ищу:

  • (потенциально рандомизированный) алгоритм линейного времени
  • или в качестве альтернативы аргумент, что линейное время невозможно

В качестве трамплина:

  • Я уже доказал, что просто зная, какие пункты могут быть выполнены до истечения срока, достаточно, чтобы восстановить полный график за линейное время. (Это понимание лежит в основе второй формулировки, где я спрашиваю только о сертификате.)
  • Простая (целочисленная!) Линейная программа может моделировать эту проблему.
  • Используя двойственность этой программы, можно проверить предлагаемое решение-кандидат в линейном времени на оптимальность, если также дано решение для двойной программы. (Оба решения могут быть представлены в линейном количестве битов.)

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

У меня есть два подхода к этой проблеме - один, основанный на ловушках, использующих крайний срок и воздействие, другой, подобный QuickSelect, основанный на выборе случайных элементов поворота и разделении элементов по воздействиям. Оба имеют худшие случаи, которые вызывают O (n log n) или худшую производительность, но я не смог построить простой особый случай, который снижает производительность обоих.

Матиас
источник

Ответы:

1

Несколько вещей, которые я узнал до сих пор.

Мы можем свести себя к решению следующей связанной проблемы:

newtype Slot = Slot Int
newtype Schedule a = Schedule [(Slot, [a])]

findSchedule :: Ord a => Schedule a -> Schedule (a, Bool)

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

Следующая функция может проверить, выполнимо ли расписание, данное в этом формате, т.е. можно ли запланировать все элементы, все еще находящиеся в расписании, до их крайних сроков:

leftOverItems :: Schedule a -> [Int]
leftOverItems (Schedule sch) = scanr op 0 sch where
  op (Slot s, items) itemsCarried = max 0 (length items - s + itemsCarried)

feasible schedule = head (leftOverItems schedule) == 0

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

carry1 :: Ord a => Schedule a -> [Bound a]
carry1 (Schedule sch) = map (maybe Top Val . listToMaybe) . scanr op [] $ sch where
  op (Slot s, items) acc = remNonMinN s (foldr insertMin acc items)

-- We only care about the number of items, and the minimum item.
-- insertMin inserts an item into a list, keeping the smallest item at the front.
insertMin :: Ord a => a -> [a] -> [a]
insertMin a [] = [a]
insertMin a (b:bs) = min a b : max a b : bs

-- remNonMin removes an item from the list,
-- only picking the minimum at the front, if it's the only element.
remNonMin :: [a] -> [a]
remNonMin [] = []
remNonMin [x] = []
remNonMin (x:y:xs) = x : xs

remNonMinN :: Int -> [a] -> [a]
remNonMinN n l = iterate remNonMin l !! n

data Bound a = Bot | Val a | Top
  deriving (Eq, Ord, Show, Functor)

-- The curve of minimum reward needed for each deadline to make the cut:
curve :: Ord a => Schedule a -> [Bound a]
curve = zipWith min <$> runMin <*> carry1

-- Same curve extended to infinity (in case the Schedules have a different length)
curve' :: Ord a => Schedule a -> [Bound a]
curve' = ((++) <*> repeat . last) . curve

-- running minimum of items on left:
runMin :: Ord a => Schedule a -> [Bound a]
runMin = scanl1 min . map minWithBound . items . fmap Val

minWithBound :: Ord a => [Bound a] -> Bound a
minWithBound = minimum . (Top:)

-- The pay-off for our efforts, this function uses
-- the candidate solution to classify the left-out items
-- into whether they are definitely _not_ in
-- the optimal schedule (heavy items), or might be in it (light items).
heavyLight :: Ord a => Schedule a -> Schedule a -> ([[a]],[[a]])
heavyLight candidate leftOut =
    unzip . zipWith light1 (curve' candidate) . items $ leftOut
  where
    light1 pivot = partition (\item -> pivot < Val item)

heavyLight не только проверяет предложенные графики на оптимальность, но и дает список пунктов, которые могут улучшить неоптимальное расписание.

Матиас
источник
-4

Нет. Это не частный случай проблемы потока, решаемой за линейное время. Поскольку сложность задается и при самой сортировке мы получаем сложность как и для выполнения всех других n процессов сложность определенно не останется линейной.O ( n log n )O(n2)O(nlogn)

Sheetal U
источник
1
Я не считаю это очень убедительным аргументом в пользу того, что эта проблема не решаема за линейное время.
Том ван дер Занден
И я тоже. Весь смысл в том, чтобы избежать сортировки по степени влияния, так как вам не нужна информация о полной перестановке. (Та же идея, что и в QuickSelect.)
Матиас,
@ Sheetal-U, Также, чтобы уточнить, я не хочу ничего выполнять --- я просто хочу построить график.
Матиас