Gleiche Stöcke aus verschiedenen Stöcken schneiden

10

Sie haben Sticks beliebiger Länge, die nicht unbedingt ganzzahlig sind.n

Wenn Sie einige Sticks schneiden (ein Schnitt schneidet einen Stick, aber wir können so oft schneiden, wie wir möchten), möchten Sie Sticks erhalten, so dass:k<n

  • Alle diese Stöcke haben die gleiche Länge;k
  • Alle Sticks sind mindestens so lang wie alle anderen Sticks.k

Beachten Sie, dass wir nach dem Durchführen von Schnitten Sticks erhalten .C.n+CC

Welchen Algorithmus würden Sie verwenden, damit die Anzahl der erforderlichen Schnitte minimal ist? Und wie lautet diese Nummer?

Nehmen Sie als Beispiel und jedes . Der folgende Algorithmus kann verwendet werden:k=2n2

  • die Sticks in absteigender Reihenfolge der Länge so an, dass .L1L2Ln
  • Wenn dann schneide Stick # 1 in zwei gleiche Stücke. Es gibt jetzt zwei Sticks der Länge , die mindestens so lang sind wie die verbleibenden Sticks .L12L2L1/22n
  • Andernfalls ( ) den Stab Nr. 1 in zwei ungleiche Stücke der Größen und . Es gibt jetzt zwei Sticks der Länge , die länger als und die anderen Sticks .L1<2L2L2L1L2L2L1L23n

In beiden Fällen ist ein einziger Schnitt ausreichend.

Ich habe versucht, dies auf ein größeres zu verallgemeinern , aber es scheint viele Fälle zu geben, die berücksichtigt werden müssen. Können Sie eine elegante Lösung finden?k

Erel Segal-Halevi
quelle

Antworten:

6

Die erste Kernbeobachtung zur Lösung dieses Problems ist, dass die Machbarkeit einer Schnittlänge ,l

Feasible(l)=[i=1nLilk] ,

ist stückweise konstant, linkskontinuierlich und nimmt in . Da sich die Anzahl der erforderlichen Schnitte ähnlich verhält, ist das Finden der optimalen Länge gerechtl

l=max{lFeasible(l)} .

Darüber hinaus haben, wie die anderen Antworten vorgeschlagen haben, alle Sprungdiskontinuitäten die Form . Dies führt zu einem diskreten, eindimensionalen Suchproblem, das der binären Suche zugänglich ist (nach dem Sortieren einer endlichen Menge von Kandidaten).Li/j

Beachten Sie außerdem, dass wir nur das berücksichtigen müssen, das kürzer als das größte ist, da dieses immer machbar ist.Lik

Dann führen unterschiedliche Grenzen für zu Algorithmen mit unterschiedlicher Effizienz.j

  • 1jk ergibt einen Suchraum von quadratischer Größe (in ),k
  • 1jk/i in einer linearithmischen (vorausgesetzt, die sind nach abnehmender Größe sortiert) undLi
  • etwas mehr involvierte Grenzen in einer linearen.

Auf diese Weise können wir das vorgeschlagene Problem in Zeit und Raum lösen .Θ(n+klogk)Θ(n+k)

Eine weitere Beobachtung ist, dass die Summe in für jeden Kandidaten "bestanden" wurde, in um wächst , wobei Duplikate gezählt werden. Auf diese Weise können wir die Rangauswahl anstelle der binären Suche verwenden und einen Algorithmus erhalten, der in Zeit und Raum , was optimal ist.Feasiblel1Li/jΘ(n)

Details finden Sie in unserem Artikel Effiziente Algorithmen für die beneidungsfreie Stick-Division mit wenigen Schnitten (von Reitzig und Wild, 2015).

Raphael
quelle
Wie sich herausstellt, übertragen sich die Ideen aus unserem Ansatz zum Schneiden von Stöcken auf das allgemeinere Problem oder die (proportionale) Aufteilung , ein Problem von praktischer Relevanz. siehe dazu unseren kurzen Artikel .
Raphael
4

Wie von @randomA vorgeschlagen, werden wir in zwei Phasen fortfahren: Wir finden zuerst den Satz Stöcke, die geschnitten werden sollen, und minimieren dann die Anzahl der Schnitte.

Wie im speziellen Fall in der Frage sortieren / benennen wir die Sticks so, dass . Dies dauert .L1L2LnO(nlogn)

Wie @ user1990169 hervorhob, müssen wir niemals ein Stück schneiden .ik

In der ersten Phase verwenden wir eine binäre Suche, um die Zahl , , so dass die Sticks in mindestens Stücke der Größe (plus einige kleinere Stücke) geschnitten werden können. , aber die Sticks können nicht in Stücke der Größe geschnitten werden . Dies dauert .s1sk1,,skLs1,,s1kLs1O(klogk)

Wenn , ist dieser Wert die optimale Größe und wir können Phase zwei überspringen.Ls1=Ls

Ansonsten wissen wir , dass die optimale Größe erfüllt und wenn dann Ergebnisse aus mindestens einer der Stäbe in gleich große Stücke schneiden. Phase zwei bestimmt :oLs1>oLso>Lsoo

Bestimmen Sie für jeden Stick , einen Satz von Kandidatengrößen wie folgt: Wenn das Schneiden in Stücke der Größe den Stick in Stücke (einschließlich des kürzeren, falls vorhanden) verwandelt , dann die Kandidaten dafür Stick sind alle Werte , wobei und . ( In der Antwort von @ user1990169 erfahren Sie, warum dies die einzigen Kandidatengrößen sind.)i1isLsriLijjriLij<Ls1

Behalten Sie für jede Kandidatengröße bei, wie oft sie aufgetreten ist. Bei Verwendung eines ausgeglichenen Suchbaums kann dies in , da die Gesamtzahl der Kandidatengrößen durch gebunden ist .O(klogk)iri2k

Die Kandidatengröße, die am häufigsten auftrat und zu einem gültigen Schnitt führte, gibt uns die optimale Lösung. Wenn eine Kandidatengröße zu einem gültigen Schnitt führt, führt eine kleinere Größe auch zu einem gültigen Schnitt.

Wir können also wieder die binäre Suche verwenden, um die größte Kandidatenlänge zu finden, die zu einem gültigen Schnitt in . Dann iterieren wir über die Menge der Kandidatenlängen bis zu diesem Schwellenwert und finden diejenige mit der größten Menge unter ihnen in .O(klogk)O(k)

Insgesamt erhalten wir eine Laufzeit in oder , wenn wir die anfängliche Sortierung ignorieren (oder nicht tun müssen).O(nlogn)O(klogk)

FrankW
quelle
Wie genau prüfen Sie im binären Suchschritt, ob "die Sticks in mindestens Stücke der Größe "? 1,,skLs
Erel Segal-Halevi
Berechnen Sie für . Die Summe dieser Werte ist die Anzahl der Teile, die Sie erhalten können. 1isLi/Ls
FrankW
"Die Kandidatengröße, die am häufigsten auftrat ... ist diejenige, die uns die optimale Lösung bietet" - warum?
Erel Segal-Halevi
Denn jedes Mal, wenn es auftritt, haben wir einen Stock, der Stücke mit Schnitten gibt. tt1
FrankW
1
Die Gesamtzahl der Schnitte ist im besten Fall ( - Sticks gleich lang, alle anderen Sticks höchstens halb so lang wie diese und soweit ich sehen kann , wird nie als mehr sein . (Es wird definitiv nie mehr als , da jeder Schnitt einen Stock der richtigen Länge und einen Rest ergibt. Aber es scheint, wir können immer eine Größe wählen, so dass mindestens ein Schnitt einen Rest der richtigen Länge hinterlässt. Ich nicht habe aber einen Beweis dafür.)k2k2k1k
FrankW
1

Nachdem Sie die Sticks in absteigender Reihenfolge ihrer Länge bestellt haben, wird ein Stick nur geschnitten, wenn alle Sticks geschnitten wurden.LiL1,L2,...Li1

Da nun , werden wir ab den Stöcken keinen Schnitt mehr machen , da wir immer Stöcke mit der Länge .k<nLkkLk

Anstelle von handelt es sich nun also nur um Sticks (möglicherweise um den ten Stick als Ganzes) und die maximale Anzahl von Schnitten, die im schlimmsten Fall erforderlich sein sollen .nk1k=k1

Wenn die optimale Anzahl von Schnitten , muss sich mindestens ein Satz Stöcke unter diesen Stöcken befinden, die als Ganzes von 1 Originalstab genommen werden sollen<k1k1 (entweder in Teilen oder in 1 Stück). Das heißt, kein Teil dieses Originalsticks darf "nicht genommen" werden. Dies liegt daran, dass nach dem Pigeon-Hole- Prinzip mindestens 1 Schnitt vorhanden sein muss, der mehr als 1 gültigen Stock produzieren muss.

Sie können dann zwei verschachtelte for-Schleifen durchführen (beide bis ). Die äußere Schlaufe bezeichnet die Stabnummer deren alle Teile entnommen werden müssen, und die innere Schlaufe bezeichnet die Anzahl der Teile die aus diesem Stab bestehen. Überprüfen Sie für jede Größe , ob Sie machbare k-Sticks erhalten können, indem Sie die Sticks nacheinander abschneiden. Wenn möglich, aktualisieren Sie die bisher erforderlichen Mindestschnitte, wenn die aktuell erforderliche Anzahl geringer ist.kij
LijL1

Die Gesamtkomplexität des obigen Algorithmus istO(nlog(n)+k3)

Abhishek Bansal
quelle
1

Die Idee auf hoher Ebene wäre die binäre Suche.

Die Größe jedes der angeforderten k-Sticks ist mindestens der kleinste und höchstens der größte. Aus diesem Grund verwenden wir die binäre Suche für die Größe des mittleren Sticks. Sehen Sie, welche Zahl wir erhalten können. Wenn dieses größer als das angegebene ist, wissen wir, dass wir eine neue Referenzkandidatengröße auswählen müssen. Also wechseln wir mit einem neuen Referenzstick zum Größeren oder Kleinen. Wir hören auf, wenn kleiner alskkkkk

Sobald wir den geeigneten Referenzstick gefunden haben, gibt es einen Eckfall, in dem wir die Größe weiter verfeinern müssten. Wir können alle geschnittenen Sticks nach der Anzahl der Schnitte und der Größe des Sticks sortieren. Wählen Sie den mit der geringsten Anzahl von Schnitten und der geringsten Größe. Reduzieren Sie die Anzahl der Schnitte auf diesem Stick um 1 und machen Sie alle Substicks dieses Sticks gleich groß. Dies ist die neue Referenzgröße. Überprüfen Sie, ob diese neue Größe zu einem akzeptablen . Ich gebe zu, ich weiß nicht, wie ich die Laufzeit in diesem Fall begrenzen soll.k

Hoffentlich kann ich aus anderen Antworten etwas Nützliches erkennen.

InformiertA
quelle
2
Ich denke, die Grundidee Ihres Ansatzes wird funktionieren. Ihre Beschreibung des Algorithmus ist jedoch nicht klar genug, um sicher zu sein. Könnten Sie einen detaillierteren Pseudocode hinzufügen?
FrankW
@FrankW Ich bin mir allerdings nicht sicher über die Laufzeit. Ich werde sehen, was andere Leute haben, das ist eine ziemlich interessante Frage.
Informiert