Perché non prendere la rappresentazione unaria dei numeri negli algoritmi numerici?


15

Un algoritmo di tempo pseudo-polinomiale è un algoritmo che ha tempo di esecuzione polinomiale sul valore di input (magnitudine) ma tempo di esecuzione esponenziale sulla dimensione di input (numero di bit).

Ad esempio, per verificare se un numero è primo o no, richiede un ciclo tra i numeri da 2 a e verificare se mod è zero o meno. Se la mod impiega il tempo O (1), la complessità temporale complessiva sarà O (n).nn1n i

Ma se lasciamo che sia il numero di bit richiesti per scrivere l'input, allora (binario) quindi e il tempo di esecuzione del problema sarà O ( ) che è esponenziale.xx=lognn=2x2x

La mia domanda è, se consideriamo la rappresentazione unaria dell'input , allora sempre e quindi il tempo pseudo-polinomiale sarà uguale alla complessità del tempo polinomiale. Quindi perché non lo facciamo mai?nx=n

Inoltre, poiché esiste un algoritmo di tempo pseudo-polinomiale per lo zaino, prendendo , lo zaino sarà polinomiale come risultato P = NPx=n


3
In realtà, lo facciamo, ma non abbastanza spesso. Per le stesse ragioni, di solito non ci occupiamo di lingue unarie, ma ci sono molti risultati interessanti relativi a queste bestie. Ci hai guardato dentro?
André Souza Lemos,

2
Sì, se togli la differenza tra dimensione e grandezza, perdi tutti i concetti basati su tale differenza.
André Souza Lemos,

7
Perché sta mettendo il demone in un bel vestito. Non rende nulla più veloce, rende insignificante solo la "complessità del tempo di esecuzione".
Raffaello

4
@Drupalist In realtà il problema dello zaino unario non è noto per essere NP-completo perché la normale riduzione al problema dello zaino presuppone che i numeri siano scritti in binario. Se si tenta di eseguire la riduzione standard ma si scrivono i numeri in modo unario, la riduzione non può essere calcolata in tempo polinomiale. Di conseguenza, il problema dello zaino unario essendo risolvibile in tempo polinomiale non significherebbe che P = NP.
templatetypedef

2
Potresti voler dare un'occhiata ad altre risposte taggate pseudo-polinomiali , in particolare questa .
Raffaello

Risposte:


17

Ciò significa che lo zaino unario è in P. Non significa che lo zaino (con numeri con codifica binaria) sia in P.

Lo zaino è noto per essere NP-completo. Se mostrassi che lo zaino è in P, ciò mostrerebbe che P = NP.

Ma non hai dimostrato che lo zaino è in P. Hai dimostrato che lo zaino unario è in P. Tuttavia, lo zaino unario non è noto per essere NP-completo (in effetti, il sospetto standard è che molto probabilmente non è NP-completo ). Pertanto, mettere uno zaino unario in P non implica che P = NP.


Quindi quale problema dovremmo preoccuparci di più, zaino o zaino unario? Se la tua motivazione si basa su preoccupazioni pratiche, la risposta dipenderà dalla dimensione dei numeri per cui vuoi risolvere il problema dello zaino: se sono grandi, allora ti preoccupi più dello zaino che dello zaino unario. Se la tua motivazione si basa su preoccupazioni teoriche, allora lo zaino è probabilmente più interessante, perché ci consente di ottenere una comprensione più profonda - ci permette di fare una distinzione tra dimensione e grandezza - mentre lo zaino unario ci impedisce di fare tale distinzione.


Per rispondere alla domanda di follow-up sull'algoritmo di programmazione dinamica per il problema dello zaino:

Sì, lo stesso algoritmo di programmazione dinamica può essere applicato sia allo zaino che allo zaino unario. Il suo tempo di esecuzione è polinomiale nella grandezza dei numeri, ma esponenziale (non polinomiale) nella lunghezza dei numeri quando codificato in binario. Pertanto, il suo tempo di esecuzione è polinomiale nella lunghezza dell'ingresso quando l'ingresso è codificato in unario ma non è polinomiale nella lunghezza dell'ingresso quando l'ingresso è codificato in binario. È per questo che facciamo prendere in considerazione questo algoritmo di programmazione dinamica per essere un algoritmo polinomiale per lo zaino unario, ma non lo considerano un algoritmo polinomiale per lo zaino (con codifica binaria).

Ricordiamo che diciamo che un algoritmo viene eseguito nel tempo polinomiale se il suo tempo di esecuzione è al massimo un polinomio della lunghezza dell'input, in bit .


1
Grazie mille, non sapevo che la classe di complessità unaria e non unaria dello stesso algoritmo potrebbe essere diversa. Perché la soluzione di programmazione dinamica dello zaino standard non può essere applicata allo zaino unario e ha portato a diverse classi di complessità? Sto riscontrando problemi con la comprensione della versione unaria dei problemi.
M ama D,

@Drupalist, ho modificato la mia risposta per aggiungere due paragrafi alla fine per rispondere a quella domanda.
DW

Grazie mille, da quello che capisco la differenza tra la dimensione dell'input e la sua grandezza è il motivo della distinzione tra polinomio e pseudo-polinomiale, usando la rappresentazione unaria ho cercato di eliminare questa differenza, Se dimentichiamo lo zaino e torniamo al numerico algoritmi, vorrei sapere impostando quale sarà l'interpretazione del polinomio e dello pseudo-polinomio? Grazie ancorax=n
M ama D

@Drupalist, non sono del tutto sicuro di cosa intendi impostando , quindi non sono sicuro di come rispondere. A questo punto suggerirei che potrebbe essere meglio porre una nuova domanda (autonoma) (e definire tutte le variabili in quella domanda). Questa piattaforma non è così buona per domande di follow-up o avanti e indietro: il modo migliore che dobbiamo gestire è quello di porre una nuova domanda, in base a ciò che hai imparato dalle risposte a questa domanda. x=n
DW

1
@NikosM., OK, capito. Grazie per il feedback. Personalmente, non credo che questa affermazione sia errata, quindi la lascerò così com'è. (Il mio ragionamento: la lunghezza dell'input dipende dalla scelta della rappresentazione, quindi non credo che contraddica tutto ciò che hai scritto.) Tuttavia è del tutto possibile che la mia prospettiva potrebbe essere troppo ristretta, o che una spiegazione o spiegazione più dettagliata da una prospettiva diversa potrebbe aggiungere valore. Sentiti libero di scrivere una risposta aggiuntiva o di suggerire una modifica se ritieni che questo punto possa essere più chiaro.
DW

6

Aggiungerei una piccola cosa alla risposta di DW:

Ho visto persone che pensano che, poiché lo zaino unario è in P, quindi possiamo usarlo al posto dello zaino che i migliori algoritmi attuali hanno tempo esponenziale.

Lasciare che l'ingresso sia e k e considerare l'algoritmo di programmazione dinamica per Knapsack e unario zaino. Il tempo di esecuzione per entrambi è O ( n k ) . È lo stesso tempo di esecuzione. Ad esempio, se si dispone di un input, non importa se si utilizza la programmazione dinamica per Zaino unario o la programmazione dinamica per Zaino. Entrambi impiegheranno (approssimativamente) lo stesso tempo per risolvere l'istanza del problema. Teoricamente ovunque tu usi uno puoi usare anche l'altro. Hai solo bisogno di convertire i numeri da unari a binari e viceversa.W={w1,,wn}kO(nk)

Allora, qual è il punto di definire la complessità degli algoritmi rispetto alla dimensione degli input? Perché non indicarli sempre in termini di parametri come ?O(nk)

Se ti preoccupi di un problema in isolamento puoi farlo. In realtà è quello che fanno spesso le persone negli algoritmi. La complessità degli algoritmi grafici è spesso espressa in termini di numero vertici e numero di spigoli, non della dimensione della stringa che li codifica.

Ma questo è solo quando abbiamo a che fare con un problema isolato. Non è utile quando abbiamo a che fare con problemi con diversi tipi di input. Per i grafici possiamo parlare del tempo di esecuzione rispetto al numero di vertici e bordi. Per lo zaino possiamo parlare del numero di articoli e delle dimensioni dello zaino. E se volessimo parlare di entrambi? Ad esempio quando vogliamo riduzioni tra i problemi o discutiamo di una classe di problemi che include problemi arbitrari, non solo quelli con un grafico come input. Abbiamo bisogno di un parametro universale di input. Un input in generale è solo una stringa, siamo noi che interpretiamo i suoi simboli come numeri unari, numeri binari, grafici, ecc. Per sviluppare una teoria generale della complessità dell'algoritmo e dei problemi abbiamo bisogno di un parametro generale degli input. La dimensione dell'input è una scelta ovvia e risulta essere abbastanza robusta da poter costruire una teoria ragionevole su di essa. Non è l'unica possibilità. Per uno artificiale possiamo costruire una teoria basata su2

k100100k21001kk21001

nnp(n)kp(n)k2p(n)1kk

nk


Grazie mille, un'altra domanda, convertendo l'input nella sua rappresentazione unaria cosa accadrà al problema di determinare se un numero è primo o no? Questo problema è polinomiale basato sulla grandezza di input ma esponenziale sulla base di bit di input (come ho sottolineato nella domanda), questa conversione migliorerà qualcosa?
M ama D

nO(n)nb=210241210241210241
Kaveh,

bel chiarimento, comunque dai un'occhiata al mio commento sotto la risposta di DW che è legato a questo post
Nikos M.

2

In breve e semplice, ti mostrerò perché.

Tally

x = input integer

factors = [];

for i in range(1, x + 1):
    if x % i == 0:
     factors.append(i)

 print(factors)

xxO(2n)

Tally/UnaryO(n)x

x = input tallies

factors = [];

for i in range(1, x + 1):
    if x % i == 0:
     factors.append(i)

 print(factors)

La rappresentazione di input non rende il codice più veloce. Anche se il 2 ° algoritmo è veramente poli-tempo. Non è molto pratico nel trovare i fattori per RSA.


Un bell'esempio, grazie
M ama D
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.