Por que não usar a representação unária de números em algoritmos numéricos?


15

Um algoritmo de tempo pseudo-polinomial é um algoritmo que possui tempo de execução polinomial no valor de entrada (magnitude), mas tempo de execução exponencial no tamanho da entrada (número de bits).

Por exemplo, testando se um número é primo ou não, requer um loop através de números de 2 a n - 1 e verifique se n mod i é zero ou não. Se o mod demorar O (1), a complexidade geral do tempo será O (n).nn1n i

Mas se deixarmos ser o número de bits necessários para gravar a entrada, x = log n (binário), então n = 2 x, e o tempo de execução do problema será O ( 2 xxx=lognn=2x2x ), que é exponencial.

Minha pergunta é, se considerarmos a representação unária da entrada , sempre x = nnx=n tempo pseudo-polinomial será igual à complexidade do tempo polinomial. Então, por que nunca fazemos isso?

Além disso, como existe um algoritmo de tempo pseudo-polinomial para a mochila, tomando , a mochila será polinomial como resultado P = NPx=n


3
Na verdade, fazemos isso, mas não com muita frequência. Pelas mesmas razões, geralmente não lidamos com idiomas unários, mas há muitos resultados interessantes relacionados a esses animais. Você já olhou para isso?
André Souza Lemos

2
Sim, se você tirar a diferença entre tamanho e magnitude, perderá todos os conceitos previstos nessa diferença.
André Souza Lemos

7
Porque está colocando o demônio em um belo vestido. Não torna nada mais rápido, apenas torna sem sentido a "complexidade do tempo de execução".
Raphael

4
@Drupalist O problema da mochila unária na verdade não é conhecido por ser NP-completo, porque a redução normal ao problema da mochila pressupõe que os números sejam gravados em binário. Se você tentar fazer a redução padrão, mas escrever os números em unário, a redução não poderá ser calculada em tempo polinomial. Como resultado, o problema unário da mochila sendo solucionável no tempo polinomial não significaria que P = NP.
templatetypedef

2
Convém verificar outras respostas com a tag pseudo-polinomial , em particular esta .
Raphael

Respostas:


17

O que isto significa é que a mochila unária está em P. Isso não significa que a mochila (com números codificados em binário) está em P.

Sabe-se que a mochila é NP-completa. Se você mostrasse que a mochila está em P, isso mostraria que P = NP.

Mas você não mostrou que a mochila está em P. Você mostrou que a mochila unária está em P. No entanto, a mochila unária não é conhecida por ser NP-completa (na verdade, a suspeita padrão é que ela provavelmente não é NP-completa ) Portanto, colocar mochila unária em P não implica que P = NP.


Então, com qual problema devemos nos preocupar mais, mochila ou mochila unária? Se sua motivação é baseada em preocupações práticas, a resposta dependerá do tamanho dos números para os quais você deseja resolver o problema da mochila: se eles forem grandes, certamente você se preocupa mais com a mochila do que com a mochila unária. Se sua motivação é baseada em preocupações teóricas, a mochila é sem dúvida mais interessante, porque nos permite uma compreensão mais profunda - nos permite fazer a distinção entre tamanho e magnitude - enquanto a mochila unária nos impede de fazer essa distinção.


Para responder à pergunta de acompanhamento sobre o algoritmo de programação dinâmica para o problema da mochila:

Sim, o mesmo algoritmo de programação dinâmica pode ser aplicado às mochilas e à mochila unária. Seu tempo de execução é polinomial na magnitude dos números, mas exponencial (não polinomial) no comprimento dos números quando codificado em binário. Assim, seu tempo de execução é polinomial no comprimento da entrada quando a entrada é codificada em unária, mas não é polinomial no comprimento da entrada quando a entrada é codificada em binário. É por isso que consideramos esse algoritmo de programação dinâmica um algoritmo de tempo polinomial para mochila unária, mas não consideramos que seja um algoritmo de tempo polinomial para mochila (codificada em binário).

Lembre-se de que dizemos que um algoritmo é executado em tempo polinomial se seu tempo de execução é no máximo algum polinômio do comprimento da entrada, em bits .


1
Muito obrigado, eu não sabia que a classe de complexidade de unário e não unário do mesmo algoritmo pode ser diferente. Por que a solução de programação dinâmica da mochila padrão não pode ser aplicada à mochila unária e levou a diferentes classes de complexidade? Estou tendo problemas para entender a versão unária dos problemas.
M AMA D

@ Drupalist, editei minha resposta para adicionar dois parágrafos no final para responder a essa pergunta.
DW

Muito obrigado, pelo que entendi, a diferença entre o tamanho da entrada e sua magnitude é o motivo da distinção entre polinômio e pseudo-polinomial. Usando a representação unária, tentei eliminar essa diferença. Se esquecermos a mochila e voltarmos ao número algoritmos, gostaria de saber definindo qual será a interpretação de polinômio e pseudo-polinômio? Obrigado novamentex=n
M ama D

@ Drupalist, não sei bem o que você quer dizer com definir , então não sei bem como responder. Nesse ponto, eu sugeriria que seria melhor fazer uma nova pergunta (independente) (e definir todas as suas variáveis ​​nessa pergunta). Essa plataforma não é tão boa para perguntas de acompanhamento ou para trás e para trás: a melhor maneira de lidar com isso é fazer uma nova pergunta, com base no que você aprendeu com as respostas a essa pergunta. x=n
DW

1
@ NikosM., OK, entendi. Obrigado pelo feedback. Pessoalmente, não acredito que essa afirmação esteja incorreta, então vou deixar como está. (Meu raciocínio: o tamanho da entrada depende da escolha da representação, por isso não acredito que contradiga tudo o que você escreveu.) No entanto, é inteiramente possível que minha perspectiva seja muito estreita ou que uma explicação ou explicação mais detalhada uma perspectiva diferente pode agregar valor. Sinta-se à vontade para escrever uma resposta adicional ou sugerir uma edição se achar que esse ponto pode ser mais claro.
DW

6

Eu acrescentaria uma pequena coisa à resposta da DW:

Vi pessoas que pensam que, porque o Knapsack unário está em P, portanto, podemos usá-lo no lugar do Knapsack, que melhores algoritmos atuais têm tempo exponencial.

W={w1,,wn}kO(nk)

O(nk)

Se você se importa com um problema isolado, pode fazê-lo. Na verdade, é isso que as pessoas nos algoritmos costumam fazer. A complexidade dos algoritmos de gráfico é frequentemente expressa em termos dos vértices numéricos e do número de arestas, não do tamanho da string que os codifica.

Mas isso é apenas quando estamos lidando com um problema isolado. Não é útil quando estamos lidando com problemas com diferentes tipos de entradas. Para gráficos, podemos falar sobre o tempo de execução por número de vértices e arestas. Para a mochila, podemos falar sobre o número de itens e o tamanho da mochila. Mas e se queremos conversar sobre os dois? Por exemplo, quando queremos reduções entre problemas ou discutimos classes de problemas que incluem problemas arbitrários, não apenas aqueles com um gráfico como entrada. Precisamos de um parâmetro universal de entradas. Uma entrada em geral é apenas uma cadeia, somos nós que interpretamos seus símbolos como números unários, números binários, gráficos etc. Para desenvolver uma teoria geral da complexidade do algoritmo e dos problemas, precisamos de um parâmetro geral de entradas. O tamanho da entrada é uma escolha óbvia e acaba sendo robusto o suficiente para que possamos construir uma teoria razoável sobre ela. Não é a única possibilidade. Para um artificial, podemos construir uma teoria baseada em2

k100100k21001kk21001

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

nk


Muito obrigado, mais uma pergunta, convertendo a entrada em sua representação unária, o que acontecerá com o problema de determinar se um número é primo ou não? Esse problema é polinomial com base na magnitude da entrada, mas exponencial com base nos bits de entrada (como apontei na pergunta). Essa conversão tornará algo melhor?
M AMA D

nO(n)nb=210241210241210241
Kaveh

bom esclarecimento, no entanto, ter um olhar para o meu comentário sob a resposta de DW que está relacionado com este post
Nikos M.

2

Em resumo e simples, mostrarei o porquê.

Suponha que você tenha um algoritmo de fatoração. Exceto pela pequena diferença de que um aceita números inteiros para entrada e o outroTumaeueuy. Como você pode ver, os dois trechos de código são semelhantes.

x = input integer

factors = [];

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

 print(factors)

Observe que o algoritmo acima é polinomial do valor numérico de x. Vai levarxquantidade de etapas no loop. Mas quando se trata de tamanho de bit, na verdadeO(2n).

Suponha que eu faça uma pequena edição no código que incluirá Tumaeueuy/vocênumary. Agora seráO(n) tempo no valor e no comprimento da entrada x.

x = input tallies

factors = [];

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

 print(factors)

A representação de entrada não torna o código mais rápido. Mesmo que o segundo algoritmo seja verdadeiramente poli-tempo. Não é muito prático encontrar os fatores para a RSA.


Bom exemplo, obrigado #
ama D
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.