กรณีพิเศษของปัญหาการตั้งเวลาสามารถแก้ไขได้ในเวลาเชิงเส้นหรือไม่?


12

อลิซนักเรียนทำการบ้านมากมายในสัปดาห์หน้า การบ้านแต่ละรายการจะใช้เวลาหนึ่งวัน แต่ละรายการมีกำหนดเวลาและผลกระทบทางลบต่อผลการเรียนของเธอ (สมมติว่าเป็นจำนวนจริงคะแนนโบนัสสำหรับการเปรียบเทียบเท่านั้น) หากเธอพลาดกำหนดเวลา

เขียนฟังก์ชั่นที่ให้รายการของ (กำหนดเวลาผลกระทบระดับคะแนน) กำหนดตารางเวลาสำหรับการทำการบ้านในวันที่ลดผลรวมของผลกระทบที่ไม่ดีต่อเกรดของเธอ

การบ้านทั้งหมดจะต้องทำในที่สุด แต่ถ้าเธอพลาดกำหนดเวลาสำหรับรายการมันไม่สำคัญว่าเธอจะเปิดช้าแค่ไหน

ในสูตรทางเลือก:

ACME corp ต้องการส่งน้ำให้กับลูกค้า พวกเขาทั้งหมดอาศัยอยู่ตามถนนสายเดียว ACME มีหลุมหลายแห่งกระจายอยู่ตามถนน แต่ละบ่อมีน้ำเพียงพอสำหรับลูกค้าหนึ่งราย ลูกค้าเสนอราคาเป็นจำนวนเงินที่แตกต่างกัน น้ำไหลลงเขาเท่านั้น เพิ่มรายได้ให้สูงสุดด้วยการเลือกลูกค้าที่จะจัดหา

เราสามารถจัดเรียงกำหนดเวลาโดยใช้การจัดเรียงกลุ่ม (หรือสมมติว่าเราได้เรียงลำดับตามกำหนดเวลาแล้ว)

เราสามารถแก้ปัญหาได้อย่างง่ายดายด้วยอัลกอริธึมโลภหากเราจัดเรียงโดยการกระทบจากระดับสูงสุดก่อน ทางออกนั้นจะไม่ดีไปกว่า O (n log n)

ได้รับแรงบันดาลใจจากMedian of MediansและอัลกอริทึมSpanning Tree แบบขั้นต่ำแบบเส้นตรงฉันสงสัยว่าเราสามารถแก้ปัญหาการตั้งเวลา / การไหลแบบง่าย ๆ ของฉันในเวลาเชิงเส้น (แบบสุ่ม?) ได้เช่นกัน

ฉันกำลังมองหา:

  • อัลกอริทึมเวลาเชิงเส้น (อาจสุ่ม)
  • หรือมิฉะนั้นก็โต้แย้งว่าไม่สามารถใช้เวลาเชิงเส้นได้

ในฐานะที่เป็นหินก้าว:

  • ฉันได้พิสูจน์แล้วว่าเพิ่งรู้ว่ารายการใดที่สามารถทำได้ก่อนกำหนดเวลาของพวกเขาเพียงพอที่จะสร้างตารางเวลาที่สมบูรณ์ในเวลาเชิงเส้น (ข้อมูลเชิงลึกนั้นเป็นรากฐานของสูตรที่สองที่ฉันถามเกี่ยวกับใบรับรองเท่านั้น)
  • โปรแกรมเชิงเส้นตรง (integral!) สามารถจำลองปัญหานี้ได้
  • การใช้สองโปรแกรมนี้สามารถตรวจสอบวิธีการแก้ปัญหาที่เสนอโดยผู้สมัครในเวลาเชิงเส้นสำหรับการเพิ่มประสิทธิภาพหากมีการให้โซลูชั่นในโปรแกรมคู่ (โซลูชันทั้งสองสามารถแสดงเป็นจำนวนบิตแบบเส้นตรง)

เป็นการดีที่ฉันต้องการที่จะแก้ปัญหานี้ในรูปแบบที่ใช้การเปรียบเทียบระหว่างผลกระทบของเกรดเท่านั้นและไม่ถือว่ามีตัวเลข

ฉันมีสองวิธีในการแก้ไขปัญหานี้ - หนึ่งโดยใช้ treaps โดยใช้กำหนดเวลาและผลกระทบ 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

หากเรามีวิธีแก้ปัญหาผู้สมัครที่เสนอและรายการทั้งหมดที่เหลือเราสามารถตรวจสอบในเวลาเชิงเส้นว่าผู้สมัครที่ดีที่สุดหรือไม่ว่ามีรายการใด ๆ ในชุดซ้ายออกที่จะปรับปรุงการแก้ปัญหา เราเรียกรายการแสงเหล่านี้ซึ่งคล้ายคลึงกับคำศัพท์ในอัลกอริทึมขั้นต่ำ Spanning Tree

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(n2)O(nlogn)


1
ฉันไม่พบข้อโต้แย้งที่น่าเชื่อถือว่าปัญหานี้ไม่สามารถแก้ไขได้ในเวลาเชิงเส้น
Tom van der Zanden

ฉันก็เช่นกันประเด็นทั้งหมดคือการหลีกเลี่ยงการเรียงลำดับตามผลกระทบเนื่องจากคุณไม่ต้องการข้อมูลเกี่ยวกับการเปลี่ยนรูปแบบเต็มรูปแบบ .. (ความคิดเช่นเดียวกับใน QuickSelect.)
Matthias

@ Sheetal-U เพื่อชี้แจงฉันไม่ต้องการดำเนินการใด ๆ --- ฉันแค่ต้องการสร้างตาราง
Matthias
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.