Suddividi uniformemente il testo in un determinato numero di righe


12

Esiste un algoritmo di tempo lineare per suddividere il testo in modo uniforme in righe di larghezza massima. Utilizza SMAWK (o Knuth & Plass) e "equamente" significa: http://en.wikipedia.org/wiki/Word_wrap#Minimum_raggedness

Esiste un algoritmo o una funzione di costo concavo per l'algoritmo sopra che tenga conto del numero di righe in cui vorrei che il testo si spezzasse, anziché la larghezza massima della riga? Anche in tempo lineare?

In altre parole, sto cercando un algoritmo di interruzione di riga (o formazione di paragrafo o a capo automatico) in cui l'input è il numero desiderato di righe, non la larghezza desiderata.

Giusto per descrivere un approccio praticamente inutilizzabile: ci sono N parole e spazi N-1 tra ogni coppia di parole, M è il numero desiderato di linee (M <= N). Dopo ogni spazio potrebbe esserci al massimo un'interruzione di linea (possibilmente zero). Ora, l'algoritmo proverebbe a posizionare le interruzioni in ogni possibile combinazione, calcolando il "raggedness" e restituendo il migliore. Come farlo molto più velocemente?

Inoltre, un tale problema ha un nome? A quale "famiglia" di problemi appartiene? (Ad es. "Cestino") Se non avessi bisogno della soluzione perfettamente ottimale, solo un'ottima soluzione, è possibile risolverla molto più velocemente? (una qualche forma di euristica potrebbe essere utilizzabile, se per un dato input ci fosse sempre la stessa soluzione, possibilmente non ottimale).

Aggiornare

Chandra Chekuri ha suggerito a muggito "un problema nel capitolo di Kleinberg e Tardos sulla programmazione dinamica". È stata una buona lettura ma si occupa dell'interruzione di riga in base alla larghezza anziché al conteggio delle righe. Potrebbe essere adattabile a questo problema che è qualcosa che sto cercando di capire ora. Ecco un buon collegamento alla soluzione, sostengono addirittura di risolverlo in tempo lineare: http://web.media.mit.edu/~dlanman/courses/cs157/HW5.pdf

Inoltre, c'è un capitolo "8.5 Il problema della partizione" in The Algorithm Design Manual di Skiena che sembra essere esattamente in tema, lo sto ancora leggendo, duro. (Sfortunatamente, da quello che ho capito, ha una complessità temporale quadratica)


5
Bel problema di programmazione dinamica! Potrei usarlo come compiti a casa nella mia classe il prossimo semestre.
Jeffε,

3
@ Jɛ ff E se vuoi usarlo per un problema con i compiti, chiudi meglio la domanda prima che la risposta venga pubblicata sul web.
Joe,

1
@Joe: come qualcuno veramente interessato alla risposta preferirei rispondere alla domanda, piuttosto che chiusa.
Ecir Hana,

2
@Joe: non è un compito, non studio nemmeno CS. Qual è il "livello di compiti a casa", trovo molto interessante che alcune persone non riescano nemmeno a immaginare come risolvere un problema, mentre altre lo considerano "livello di compiti a casa". Detto questo, la risposta potrebbe essere cancellata in una settimana o inviata alla mia e-mail, ad esempio. E sarei grato anche per la non "risposta completa".
Ecir Hana,

3
C'è un problema nel capitolo di Kleinberg e Tardos sulla programmazione dinamica che è quello di formattare in modo tale da ridurre al minimo la somma degli slots nelle linee.
Chandra Chekuri

Risposte:


4

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

MM


Mi dispiace molto ma non credo di seguirlo. "Edge edge" è la lunghezza di una parola? Come appare il "grafico"? È solo un grafico lineare in cui i nodi sono i punti di interruzione e gli spigoli sono le lunghezze delle parole? E questo "percorso M-link" lo spezza in modo che i segmenti risultanti abbiano una somma minima di spigoli? Ma soprattutto, nella primissima frase - non sono sicuro di poter calcolare indipendentemente il logorio. È approssimativamente la differenza tra la linea più lunga e quella reale, quindi devo sapere qualcosa sulle altre linee, no? Ancora di più per l'ultima riga, vedere il 15 ° commento sopra.
Ecir Hana

M1N+1(i,j)ij1

@Ecir: essenzialmente tutti gli algoritmi basati sulla programmazione dinamica richiedono che sia possibile calcolare indipendentemente lo sfilacciamento di una linea. Se così non fosse, potresti voler usare qualcosa come la mia seconda idea: indovina una larghezza di linea, calcola una soluzione basata su quella larghezza e provi a trovare soluzioni migliori.
Jouni Sirén

grazie per la spiegazione. Per favore, ho altre due domande: quando si utilizza l'opzione "ricerca binaria", c'è qualcosa che posso fare per garantire il numero M di righe? Se aggiungessi piccoli epsilon casuali per ogni larghezza di linea in modo che non ci fossero linee con la stessa larghezza, potrei ottenere una maggiore risoluzione sul posizionamento delle interruzioni.
Ecir Hana,

E nel caso del "percorso M-link", entrambi gli articoli menzionano che "è facile dimostrare che il percorso minimo del collegamento K può essere calcolato nel tempo O (nK)" - sai forse cosa significano? Non sono riuscito a trovare ulteriori informazioni al riguardo. Il problema è che quei documenti sono un po 'troppo complicati per la mia testolina, quindi sto cercando di trovare ulteriori informazioni, un'implementazione forse, ...
Ecir Hana

-3

Non so se questo aiuta, ma verso la fine di questo commento qualcuno implementa ciò che vuoi in PHP; forse puoi capire l'algoritmo.


4
Nel commento hanno semplicemente tagliato le righe rimanenti dopo il numero desiderato di righe. Usano i PHP wordwrap(), che a loro volta usano l'algoritmo avido (cioè non "uniformemente") per il wrapping. Anche allora, la domanda rimane come "indovinare" l' $widthargomento di wordwrap(). Ma grazie per la risposta, comunque!
Ecir Hana
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.