调度问题的这种特殊情况是否可以在线性时间内解决?


12

爱丽丝(Alice)是一名学生,在接下来的几周里要完成很多作业。每一项家庭作业都需要她一天的时间。如果每个项目都错过了截止日期,那么每个项目都有一个截止日期,并且会对她的成绩产生负面影响(假设为实数,仅假设可比性,则获得加分)。

编写一个函数,该函数给出了(截止日期,成绩影响)列表,该时间表列出了在哪一天进行作业的时间表,以最大程度地减少对她的成绩造成的负面影响。

所有作业都必须最终完成,但是如果她错过了某个项目的截止日期,那么上交多晚都没关系。

在替代公式中:

ACME公司希望向客户供水。他们都住在一条上坡路。ACME在这条街上分布着几口井。每口井可容纳一名顾客的水。客户出价要提供的金额不同。水只下坡。通过选择供应哪些客户来最大化收入。

我们可以使用存储桶排序对截止期限进行排序(或者假设我们已经按截止期限进行了排序)。

如果我们首先按降级影响进行排序,则可以使用贪婪算法轻松解决该问题。该解决方案不会比O(n log n)好。

受到中位数中位数随机线性最小生成树算法的启发,我怀疑我们也可以在(随机化的)线性时间内解决我的简单调度/流程问题。

我在寻找:

  • (潜在随机化)线性时间算法
  • 或者替代地,认为不可能有线性时间

作为垫脚石:

  • 我已经证明,仅知道在截止日期之前可以完成哪些项目,就足以在线性时间内重建完整的计划。(这种见解是我仅询问证书的第二种提法的基础。)
  • 一个简单的(积分!)线性程序可以对这个问题进行建模。
  • 使用该程序的对偶性,如果还为对偶程序提供了解决方案,则可以在线性时间内检查候选提议的解决方案是否最优。(两个解都可以用线性位数表示。)

理想情况下,我想在仅使用坡度影响之间比较而不在此处假设数字的模型中解决此问题。

对于这个问题,我有两种方法-一种基于使用截止日期和影响的挖掘,另一种类似于QuickSelect的方法,其基于选择随机枢轴元素并按影响对项目进行划分。两者都具有迫使O(n log n)或更坏的性能的最坏情况,但是我无法构造一个简单的特殊情况来降低两者的性能。

Answers:


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

O(n2)O(nlogn)


1
我认为这不是线性时间不能解决的非常令人信服的论点。
汤姆·范德赞丹

我也不是。重点是要避免按等级排序进行排序,因为您不需要有关完整排列的信息。(与QuickSelect中的想法相同。)
Matthias

@ Sheetal-U,还要澄清一下,我什么都不想执行---我只想建立时间表。
马提亚斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.