Teilen Sie den Text gleichmäßig in eine bestimmte Anzahl von Zeilen auf

12

Es gibt einen linearen Zeitalgorithmus zum gleichmäßigen Aufteilen von Text in Zeilen maximaler Breite. Es verwendet SMAWK (oder Knuth & Plass) und bedeutet "gleichmäßig": http://en.wikipedia.org/wiki/Word_wrap#Minimum_raggedness

Gibt es einen Algorithmus oder eine Konkavkostenfunktion für den obigen Algorithmus, die anstelle der maximalen Zeilenbreite die Anzahl der Zeilen berücksichtigt, in die der Text eingebrochen werden soll? Auch in linearer Zeit?

Mit anderen Worten, ich suche nach einem Algorithmus zum Brechen von Zeilen (oder zum Bilden von Absätzen oder zum Umbrechen von Wörtern), bei dem die Eingabe die gewünschte Anzahl von Zeilen und nicht die gewünschte Linienbreite ist.

Nur um einen praktisch unbrauchbaren Ansatz zu beschreiben: Es gibt N Wörter und N-1 Leerzeichen zwischen jedem Wortpaar, M ist die gewünschte Anzahl von Zeilen (M <= N). Nach jedem Leerzeichen darf es höchstens einen (möglicherweise null) Zeilenumbruch geben. Nun würde der Algorithmus versuchen, die Pausen in jede mögliche Kombination zu setzen, die "Unregelmäßigkeit" zu berechnen und die beste zurückzugeben. Wie geht das viel schneller?

Hat ein solches Problem auch einen Namen? Zu welcher "Familie" von Problemen gehört es? (ZB "Mülleimer packen") Wenn ich nicht die perfekt optimale Lösung brauche, nur eine sehr gute, ist es möglich, sie viel schneller zu lösen? (Eine Art von Heuristik könnte verwendet werden, wenn es für eine bestimmte Eingabe immer die gleiche, möglicherweise nicht optimale Lösung gäbe.)

Aktualisieren

Chandra Chekuri schlug unten "ein Problem in Kleinberg und Tardos Kapitel über dynamische Programmierung" vor. Es war eine gute Lektüre, befasst sich aber mit Zeilenumbrüchen basierend auf der Breite und nicht der Zeilenanzahl. Es könnte an dieses Problem anpassbar sein, was ich jetzt herauszufinden versuche. Hier ist ein guter Link zu der Lösung, sie behauptet sogar, sie in linearer Zeit zu lösen: http://web.media.mit.edu/~dlanman/courses/cs157/HW5.pdf

Außerdem gibt es ein Kapitel "8.5 Das Partitionsproblem" im Algorithm Design Manual von Skiena, das genau zum Thema zu gehören scheint. Ich lese es immer noch. (Leider hat es nach meinem Verständnis eine quadratische zeitliche Komplexität.)

Ecir Hana
quelle
5
Schönes dynamisches Programmierproblem! Ich könnte es als Hausaufgabe in meiner Klasse im nächsten Semester verwenden.
Jeffs
3
@ Jɛ ɛ E Wenn Sie es für ein Hausaufgabenproblem verwenden möchten, schließen Sie die Frage besser, bevor die Antwort im Web veröffentlicht wird.
Joe
1
@Joe: Als jemand, der wirklich an der Antwort interessiert ist, würde ich es vorziehen, die Frage zu beantworten, anstatt sie zu schließen.
Ecir Hana
2
@ Joe: Es ist keine Hausaufgabe, ich lerne nicht einmal CS. Was die "Hausaufgabenebene" angeht, finde ich es sehr interessant, dass sich manche Leute nicht einmal vorstellen können, wie man ein Problem löst, während andere Leute es als "Hausaufgabenebene" betrachten. Das heißt, die Antwort könnte in einer Woche gelöscht oder zum Beispiel an meine E-Mail gesendet werden. Und ich wäre auch dankbar für die nicht so "vollständige Antwort".
Ecir Hana
3
In Kleinberg und Tardos gibt es ein Problem mit der dynamischen Programmierung, die so zu formatieren ist, dass die Summe der Lücken in den Zeilen minimiert wird.
Chandra Chekuri

Antworten:

4

MO(NlogU)UN2O(logMloglogN)M=Ω(logN)

MM

Jouni Sirén
quelle
Es tut mir sehr leid, aber ich glaube nicht, dass ich folge. Ist "Kantengewicht" die Länge eines Wortes? Wie sieht der "Graph" aus? Ist es nur ein linearer Graph, bei dem Knoten die Haltepunkte und Kanten die Wortlängen sind? Und dieser "M-Link-Pfad" bricht es auf, so dass die resultierenden Segmente eine minimale Summe von Kanten haben? Am wichtigsten ist jedoch, dass ich im ersten Satz nicht sicher bin, ob ich die Unregelmäßigkeiten unabhängig berechnen kann. Es ist ungefähr der Unterschied zwischen der längsten Linie und der tatsächlichen Linie, also muss ich etwas über die anderen Linien wissen, nein? Weitere Informationen zur letzten Zeile finden Sie im 15. Kommentar oben.
Ecir Hana
M1N+1(ich,j)ichj-1
@Ecir: Grundsätzlich erfordern alle Algorithmen, die auf dynamischer Programmierung basieren, dass Sie die Zackigkeit einer Linie unabhängig berechnen können. Wenn dies nicht der Fall ist, möchten Sie möglicherweise etwas wie meine zweite Idee verwenden: Erraten Sie eine Linienbreite, berechnen Sie eine Lösung basierend auf dieser Breite und iterieren Sie, um bessere Lösungen zu finden.
Jouni Sirén
Vielen Dank für die Erklärung. Bitte, ich habe noch zwei Fragen: Kann ich bei Verwendung der Option "Binäre Suche" irgendetwas tun, um die Anzahl M der Zeilen zu garantieren? Wenn ich zu jeder Linienbreite ein kleines zufälliges Epsilon hinzufüge, sodass es keine Linien mit der gleichen Breite gibt, kann ich mehr Auflösung beim Platzieren von Unterbrechungen erzielen.
Ecir Hana
Und im Fall des "M-Link-Pfades" erwähnen beide Artikel, dass "es einfach ist zu zeigen, dass der minimale K-Link-Pfad in O (nK) berechnet werden kann" - wissen Sie vielleicht, was sie bedeuten? Ich konnte keine weiteren Informationen dazu finden. Das Problem ist, dass diese Papiere für meinen kleinen Kopf ein bisschen zu kompliziert sind, also versuche ich, mehr Informationen zu finden, vielleicht eine Implementierung, ...
Ecir Hana
-3

Ich weiß nicht, ob das hilft, aber gegen Ende dieses Kommentars implementiert jemand, was Sie in PHP wollen. Vielleicht können Sie den Algorithmus herausfinden.

adrianp
quelle
4
Im Kommentar werden die verbleibenden Zeilen nach der gewünschten Anzahl von Zeilen abgeschnitten. Sie verwenden PHPs wordwrap(), die wiederum den gierigen (dh keinen "gleichmäßigen") Algorithmus für das Wrapping verwenden. Auch dann bleibt die Frage, wie das $widthArgument von "erraten" werden kann wordwrap(). Aber trotzdem danke für die Antwort!
Ecir Hana