Ist dieser Sonderfall eines Planungsproblems in linearer Zeit lösbar?

12

Alice, eine Studentin, hat in den nächsten Wochen eine Menge Hausaufgaben. Jede Hausaufgabe dauert genau einen Tag. Jeder Punkt hat auch eine Frist und einen negativen Einfluss auf ihre Noten (eine reelle Zahl voraussetzen, Bonuspunkte nur für die Annahme der Vergleichbarkeit), wenn sie die Frist nicht einhält.

Schreiben Sie eine Funktion, die anhand einer Liste von (Stichtag, Notenauswirkung) Zeitplänen festlegt, welche Hausaufgaben an welchem ​​Tag zu erledigen sind, um die Summe der negativen Auswirkungen auf ihre Noten zu minimieren.

Alle Hausaufgaben müssen irgendwann erledigt werden, aber wenn sie eine Frist für einen Gegenstand versäumt, ist es egal, wie spät sie ihn abgibt.

In einer alternativen Formulierung:

Die ACME will die Kunden mit Wasser versorgen. Sie wohnen alle an einer Straße bergauf. ACME verfügt über mehrere Brunnen, die entlang der Straße verteilt sind. Jeder Brunnen hat genug Wasser für einen Kunden. Kunden bieten unterschiedliche Geldbeträge zur Lieferung an. Das Wasser fließt nur bergab. Maximieren Sie den Umsatz, indem Sie auswählen, welche Kunden beliefert werden sollen.

Wir können die Fristen nach Eimersortierung sortieren (oder einfach davon ausgehen, dass wir bereits nach Fristen sortiert haben).

Wir können das Problem leicht mit einem gierigen Algorithmus lösen, wenn wir zuerst nach absteigender Note sortieren. Diese Lösung ist nicht besser als O (n log n).

Inspiriert vom Median of Medians und randomisierten linearen Minimum-Spanning-Tree- Algorithmen vermute ich, dass wir mein einfaches Scheduling / Flow-Problem auch in (randomisierter?) Linearer Zeit lösen können.

Ich suche nach:

  • ein (potentiell randomisierter) linearer Zeitalgorithmus
  • oder alternativ ein Argument, dass lineare Zeit nicht möglich ist

Als Sprungbrett:

  • Ich habe bereits bewiesen, dass es ausreicht, nur zu wissen, welche Aufgaben vor Ablauf der Frist erledigt werden können, um den gesamten Zeitplan in linearer Zeit zu rekonstruieren. (Diese Einsicht liegt der zweiten Formulierung zugrunde, bei der ich nur nach dem Zertifikat frage.)
  • Ein einfaches (integrales!) Lineares Programm kann dieses Problem modellieren.
  • Unter Verwendung der Dualität dieses Programms kann man einen Lösungsvorschlag in linearer Zeit auf seine Optimalität überprüfen, wenn man auch die Lösung für das Dualprogramm erhält. (Beide Lösungen können in einer linearen Anzahl von Bits dargestellt werden.)

Im Idealfall möchte ich dieses Problem in einem Modell lösen, bei dem nur der Vergleich zwischen Gradeinschlägen verwendet wird und dort keine Zahlen angenommen werden.

Ich habe zwei Ansätze, um dieses Problem zu lösen: einen, der auf Treaps unter Verwendung von Deadline und Impact basiert, und einen QuickSelect-ähnlichen, der auf der Auswahl zufälliger Pivot-Elemente und der Aufteilung der Elemente nach Impact basiert. Beide haben schlechteste Fälle, die O (n log n) oder schlechtere Leistung erzwingen, aber ich war nicht in der Lage, einen einfachen Sonderfall zu konstruieren, der die Leistung beider verringert.

Matthias
quelle

Antworten:

1

Ein paar Dinge, die ich bisher herausgefunden habe.

Wir können uns darauf beschränken, das folgende verwandte Problem zu lösen:

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

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

Das heißt, Sie geben die Eingabedaten bereits nach dem Stichtag sortiert an, lassen jedoch eine beliebige, nicht negative Anzahl von Aufgaben pro Tag zu. Geben Sie die Ausgabe an, indem Sie die Elemente nur darauf markieren, ob sie rechtzeitig geplant werden können oder nicht.

Mit der folgenden Funktion kann geprüft werden, ob ein in diesem Format angegebener Zeitplan realisierbar ist, dh ob alle noch im Zeitplan enthaltenen Artikel vorzeitig terminiert werden können:

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

Wenn wir eine vorgeschlagene Kandidatenlösung haben und alle Elemente ausgelassen haben, können wir in linearer Zeit prüfen, ob der Kandidat optimal ist oder ob es im ausgelassenen Satz Elemente gibt, die die Lösung verbessern würden. Wir bezeichnen diese Light Items analog zur Terminologie des Minimum-Spanning-Tree-Algorithmus

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 Überprüft nicht nur die Optimalität eines vorgeschlagenen Zeitplans, sondern zeigt auch eine Liste von Elementen an, die einen nicht optimalen Zeitplan verbessern können.

Matthias
quelle
-4

Nein. Dies ist kein Sonderfall eines in linearer Zeit lösbaren Strömungsproblems. Da die Komplexität durch und während wir uns selbst sortieren, erhalten wir die Komplexität als und um alle anderen n Prozesse auszuführen, würde die Komplexität definitiv nicht linear bleiben.Ö(n2)Ö(nLogn)

Sheetal U
quelle
1
Ich finde das nicht sehr überzeugend, dass dieses Problem nicht in linearer Zeit lösbar ist.
Tom van der Zanden
Ich auch nicht. Der springende Punkt ist, das Sortieren nach Grad Auswirkungen zu vermeiden, da Sie nicht die Informationen über die vollständige Permutation benötigen. (Dieselbe Idee wie in QuickSelect.)
Matthias
@ Sheetal-U, Auch um zu verdeutlichen, ich möchte nichts ausführen --- Ich möchte nur den Zeitplan erstellen.
Matthias