Eu acho que os artigos da Wikipedia
, e vs. são muito bons. Ainda aqui está o que eu diria: Parte I , Parte IIPNPPNP
[Usarei comentários entre colchetes para discutir alguns detalhes técnicos que você pode ignorar se desejar.]
Parte I
Problemas de decisão
Existem vários tipos de problemas computacionais. No entanto, em uma introdução ao curso da teoria da complexidade computacional, é mais fácil focar no problema de decisão , ou seja, problemas em que a resposta é SIM ou NÃO. Existem outros tipos de problemas computacionais, mas na maioria das vezes as perguntas sobre eles podem ser reduzidas a perguntas semelhantes sobre problemas de decisão. Além disso, os problemas de decisão são muito simples. Portanto, em uma introdução ao curso da teoria da complexidade computacional, concentramos nossa atenção no estudo de problemas de decisão.
Podemos identificar um problema de decisão com o subconjunto de entradas que responderam SIM. Isso simplifica a notação e permite escrever
no lugar de e
no no lugar de .x∈QQ(x)=YESx∉QQ(x)=NO
Outra perspectiva é que estamos falando sobre consultas de associação em um conjunto. Aqui está um exemplo:
Problema de decisão:
Entrada: Um número natural ,
Pergunta: é um número par?xx
x
Problema de associação:
Entrada: Um número natural ,
Pergunta: está em ?xx E v e n = { 0 , 2 , 4 , 6 , ⋯ }
xEven={0,2,4,6,⋯}
Nós nos referimos à resposta SIM em uma entrada como aceitando a entrada e à resposta NÃO em uma entrada como rejeitando a entrada.
Examinaremos os algoritmos em busca de problemas de decisão e discutiremos quão eficientes esses algoritmos são no uso de recursos computáveis . Vou confiar na sua intuição de programar em uma linguagem como C no lugar de definir formalmente o que queremos dizer com algoritmo e recursos computacionais.
[Observações: 1. Se quiséssemos fazer tudo formal e precisamente, precisaríamos consertar um modelo de computação como o modelo de máquina de Turing padrão para definir com precisão o que queremos dizer com algoritmo e seu uso de recursos computacionais. 2. Se quisermos falar sobre computação sobre objetos que o modelo não pode manipular diretamente, precisaríamos codificá-los como objetos que o modelo da máquina possa manipular; por exemplo, se estivermos usando máquinas de Turing, precisaremos codificar objetos como números e gráficos naturais como cadeias binárias.]
P = Problemas com algoritmos eficientes para encontrar soluções
Suponha que algoritmos eficientes significam algoritmos que usam a quantidade máxima de polinômios de recursos computacionais. O principal recurso com o qual nos preocupamos é o pior tempo de execução dos algoritmos em relação ao tamanho da entrada, ou seja, o número de etapas básicas que um algoritmo executa em uma entrada do tamanho . O tamanho de uma entrada é se forem necessários bits da memória do computador para armazenar ; nesse caso, escrevemos . Portanto, por algoritmos eficientes, entendemos algoritmos com tempo de execução polinomial no pior dos casos .nxnnx|x|=n
A suposição de que algoritmos de tempo polinomial capturam a noção intuitiva de algoritmos eficientes é conhecida como tese de Cobham . Neste momento, não discutirei se é o modelo certo para problemas eficientemente solucionáveis e se captura ou não o que pode ser computado com eficiência na prática e em questões relacionadas. Por enquanto, existem boas razões para fazer essa suposição; portanto, para nosso propósito, assumimos que este é o caso. Se você não aceita a tese de Cobham, ela não torna incorreto o que escrevo abaixo, a única coisa que perderemos é a intuiçãoPPsobre computação eficiente na prática. Eu acho que é uma suposição útil para alguém que está começando a aprender sobre a teoria da complexidade.
P é a classe de problemas de decisão que podem ser resolvidos com eficiência ,
ou seja, problemas de decisão que possuem algoritmos de tempo polinomial.
Mais formalmente, dizemos que um problema de decisão está em iffQP
existe um algoritmo eficiente tal que
para todas as entradas ,Ax
x
- se então , Q(x)=YESA(x)=YES
- se então .Q(x)=NOA(x)=NO
Eu posso simplesmente escrever mas escrevo desta maneira para que possamos compará-lo com a definição de .A(x)=Q(x)NP
NP = Problemas com algoritmos eficientes para verificação de provas / certificados / testemunhas
Às vezes, não conhecemos uma maneira eficiente de encontrar a resposta para um problema de decisão; no entanto, se alguém nos diz a resposta e nos dá uma prova
, podemos verificar com eficiência se a resposta está correta, verificando a prova para ver se é uma prova válida. . Essa é a idéia por trás da classe de complexidade .NP
Se a prova for muito longa, não é realmente útil, pode levar muito tempo para apenas ler a prova e muito menos verificar se é válida. Queremos que o tempo necessário para a verificação seja razoável no tamanho da entrada original, não no tamanho da prova fornecida! Isso significa que o que realmente queremos não são provas longas arbitrárias, mas provas curtas . Observe que, se o tempo de execução do verificador for polinomial no tamanho da entrada original, ele poderá ler apenas uma parte polinomial da prova. Então, resumidamente, queremos dizer o tamanho polinomial .
Forme esse ponto sempre que eu usar a palavra "prova", quero dizer "prova curta".
Aqui está um exemplo de um problema que não sabemos como resolver com eficiência, mas podemos verificar provas com eficiência:
Entrada da Partição : um conjunto finito de números naturais , Pergunta: é possível particionar em dois conjuntos e
( e ) de
forma que a soma dos números em é igual à soma do número em ( )?SS A B A ∪ B = S A ∩ B = ∅ A B ∑ x ∈ A x = ∑ x ∈ B x
SABA∪B=SA∩B=∅
AB∑x∈Ax=∑x∈Bx
Se eu lhe der e perguntar se podemos particioná-lo em dois conjuntos, de forma que suas somas sejam iguais, você não conhece nenhum algoritmo eficiente para resolvê-lo. Você provavelmente tentará todas as maneiras possíveis de particionar os números em dois conjuntos até encontrar uma partição em que as somas sejam iguais ou até que você tenha tentado todas as partições possíveis e nenhuma tenha funcionado. Se algum deles funcionasse, você diria SIM, caso contrário, diria NÃO.S
Mas existem exponencialmente muitas partições possíveis, portanto isso levará muito tempo. No entanto, se eu dou-lhe dois conjuntos e , você pode facilmente verificar se as somas são iguais e se e é uma partição de . Observe que podemos calcular somas com eficiência.ABABS
Aqui o par de e que eu lhe dou é uma prova para uma resposta SIM. Você pode verificar minha reivindicação com eficiência, analisando minha prova e verificando se é uma prova válida . Se a resposta for SIM, existe uma prova válida, e eu posso dar a você e você pode verificar com eficiência. Se a resposta for NÃO, não há prova válida. Portanto, o que quer que eu lhe dê, você pode verificar e ver que não é uma prova válida. Não posso enganá-lo com uma prova inválida de que a resposta é SIM. Lembre-se de que, se a prova for muito grande, levará muito tempo para verificá-la, não queremos que isso aconteça, portanto, nos preocupamos apenas com provas eficientes , ou seja, com tamanho polinomial.AB
Às vezes, as pessoas usam " certificado " ou " testemunha " no lugar de "prova".
Observe que estou fornecendo informações suficientes sobre a resposta para uma determinada entrada
para que você possa encontrar e verificar a resposta com eficiência. Por exemplo, em nosso exemplo de partição, eu não digo a resposta, apenas apresento uma partição e você pode verificar se é válida ou não. Observe que você tem que verificar a resposta você mesmo, não pode confiar em mim sobre o que eu digo. Além disso, você só pode verificar a exatidão da minha prova. Se minha prova for válida, significa que a resposta é SIM. Mas se minha prova for inválida, isso não significa que a resposta seja NÃO. Você viu que uma prova é inválida, não que não haja provas válidas. Estamos falando de provas para SIM. Não estamos falando de provas para NÃO.x
Vejamos um exemplo:
e é uma prova de que
pode ser particionado em dois conjuntos com somas iguais. Nós apenas precisamos de somar os números em e os números em e ver se os resultados são iguais, e verificar se , é partição de .A={2,4}B={1,5}S={1,2,4,5}ABABS
Se eu lhe der e , você verificará e verá que minha prova é inválida. Isso não significa que a resposta seja NÃO, apenas significa que essa prova específica é inválida. Sua tarefa aqui não é encontrar a resposta, mas apenas verificar se a prova fornecida é válida.A={2,5}B={1,4}
É como um aluno resolvendo uma pergunta em um exame e um professor verificando se a resposta está correta. :) (infelizmente, muitas vezes os alunos não fornecem informações suficientes para verificar a exatidão de suas respostas e os professores precisam adivinhar o restante de suas respostas parciais e decidir a nota que devem dar aos alunos por suas respostas parciais, de fato uma tarefa bastante difícil. tarefa).
O surpreendente é que a mesma situação se aplica a muitos outros problemas naturais que queremos resolver:
podemos verificar com eficiência se uma determinada prova curta é válida, mas não conhecemos nenhuma maneira eficiente de encontrar a resposta . Essa é a motivação pela qual a classe de complexidade é extremamente interessante
(embora essa não tenha sido a motivação original para defini-la). Tudo o que você faz (não apenas em ciências da computação, mas também em matemática, biologia, física, química, economia, administração, sociologia, negócios, ...) você enfrentará problemas computacionais que se enquadram nessa classe. Para ter uma idéia de quantos problemas em confira
NPN P N PNPum compêndio de problemas de otimização de NP . De fato, você terá dificuldade em encontrar problemas naturais que não estão no . É simplesmente incrível.NP
NP é a classe de problemas que possuem verificadores eficientes , ou seja,
existe um algoritmo de tempo polinomial que pode verificar se uma determinada solução está correta.
Mais formalmente, dizemos que um problema de decisão está em iffQNP
existe um algoritmo eficiente chamado verificador, de modo que,
para todas as entradas , Vx
x
- se , existe uma prova tal que ,Q(x)=YESyV(x,y)=YES
- se , para todas as provas , .Q(x)=NOyV(x,y)=NO
Dizemos que um verificador é válido
se não aceitar nenhuma prova quando a resposta for NÃO. Em outras palavras, um verificador de som não pode ser enganado para aceitar uma prova se a resposta for realmente NÃO. Sem falsos positivos.
Da mesma forma, dizemos que um verificador está completo
se aceitar pelo menos uma prova quando a resposta for SIM. Em outras palavras, um verificador completo pode ser convencido de que a resposta é SIM.
A terminologia vem de sistemas lógicos e de prova . Não podemos usar um sistema à prova de som para provar quaisquer declarações falsas. Podemos usar um sistema completo de provas para provar todas as afirmações verdadeiras.
O verificador recebe duas entradas,V
- x : a entrada original para eQ
- y : uma prova sugerida para .Q(x)=YES
Note que queremos que seja eficiente no tamanho de . Se é uma grande prova, o verificador poderá ler apenas uma parte polinomial de . É por isso que exigimos que as provas sejam curtas. Se é pequeno, dizer que é eficiente em
é o mesmo que dizer que é eficiente em e
(porque o tamanho de é limitado por um polinômio fixo no tamanho de ).Vxyy y V x V x y y xyyVxVxyyx
Em resumo, para mostrar que um problema de decisão está em
, precisamos fornecer um algoritmo verificador eficiente, sólido e completo .QNP
Nota histórica: historicamente, essa não é a definição original de . A definição original usa o que é chamado de máquinas de Turing não determinísticas . Essas máquinas não correspondem a nenhum modelo de máquina real e são difíceis de se acostumar (pelo menos quando você está começando a aprender sobre a teoria da complexidade). Eu li que muitos especialistas acham que teriam usado a definição de verificador como definição principal e até teriam nomeado a classe
(para verificação em tempo polinomial) no lugar deNPV P N P N PVPNP
se eles voltarem ao início da teoria da complexidade computacional. A definição do verificador é mais natural, mais fácil de entender conceitualmente e mais fácil de usar para mostrar problemas em .NP
P⊆NP
Portanto, temos
= solucionável eficiente e = verificável com eficiência . Portanto, se os problemas que puderem ser verificados com eficiência forem iguais aos problemas que podem ser resolvidos com eficiência.PNPP=NP
Observe que qualquer problema em também está em , ou seja, se você puder resolver o problema, também poderá verificar se uma determinada prova está correta: o verificador simplesmente ignorará a prova!PNP
Isso ocorre porque não precisamos dela, o verificador pode calcular a resposta por si só, pode decidir se a resposta é SIM ou NÃO sem ajuda. Se a resposta for NÃO, sabemos que não deve haver provas e nosso verificador rejeitará todas as provas sugeridas. Se a resposta for SIM, deve haver uma prova e, de fato, aceitaremos qualquer coisa como prova.
[Poderíamos ter feito nosso verificador aceitar apenas alguns deles, o que também é bom, desde que nosso verificador aceite pelo menos uma prova de que o verificador funciona corretamente para o problema.]
Aqui está um exemplo:
Entrada de soma : uma lista de números naturais e , Pergunta: is ?n+1a1,⋯,ansΣ n i = 1 a i = s
Σni=1ai=s
O problema está em porque podemos resumir os números e compará-los com , retornamos YES se forem iguais e NO se não forem.Ps
O problema também está em . Considere um verificador que obtém uma prova mais a entrada para Sum. Ele age da mesma maneira que o algoritmo em que descrevemos acima. Este é um verificador eficiente para Sum.NPVP
Observe que existem outros verificadores eficientes para Sum, e alguns deles podem usar a prova fornecida. No entanto, o que projetamos não é e também é bom. Como fornecemos um verificador eficiente para Sum, o problema está em . O mesmo truque funciona para todos os outros problemas em então
.NPPP⊆NP
Algoritmos de pesquisa de força bruta / exaustiva para eNPNP⊆ExpTime
Os melhores algoritmos que conhecemos para resolver um problema arbitrário em são
algoritmos de pesquisa de força bruta / pesquisa exaustiva . Escolha um verificador eficiente para o problema (ele tem um pressuposto de que ele está em ) e verifique todas as provas possíveis uma por uma. Se o verificador aceitar um deles, a resposta é SIM. Caso contrário, a resposta é NÃO.NPNP
No nosso exemplo de partição, tentamos todas as partições possíveis e verificamos se as somas são iguais em alguma delas.
Observe que o algoritmo de força bruta é executado no pior momento exponencial. O tamanho das provas é polinomial no tamanho da entrada. Se o tamanho das provas for , existem provas possíveis. A verificação de cada um deles levará tempo polinomial pelo verificador. Portanto, no total, o algoritmo de força bruta leva tempo exponencial.m2m
Isso mostra que qualquer problema pode ser resolvido em tempo exponencial, ou seja,
. (Além disso, o algoritmo de força bruta usará apenas uma quantidade polinomial de espaço, por exemplo,
mas isso é uma história para outro dia).NPNP⊆ExpTimeNP⊆PSpace
Um problema em pode ter algoritmos muito mais rápidos, por exemplo, qualquer problema em possui um algoritmo de tempo polinomial. No entanto, para um problema arbitrário no
, não conhecemos algoritmos que podem fazer muito melhor. Em outras palavras, se você me disser que seu problema está em
(e nada mais sobre o problema), o algoritmo mais rápido que conhecemos para resolvê-lo leva um tempo exponencial.NPPNPNP
No entanto, isso não significa que não existem algoritmos melhores,
não sabemos disso . Até onde sabemos, ainda é possível (embora seja quase improvável para quase todos os teóricos da complexidade) que
e todos os problemas de possam ser resolvidos em tempo polinomial.NP=PNP
Além disso, alguns especialistas conjeturam que não podemos fazer muito melhor, ou seja, existem problemas no que não podem ser resolvidos com muito mais eficiência do que algoritmos de busca por força bruta que levam tempo exponencial. Consulte a Hipótese de tempo exponencial
para obter mais informações. Mas isso não está provado, é apenas uma conjectura . Apenas mostra a que distância estamos de encontrar algoritmos de tempo polinomial para problemas arbitrários .NPNP
Esta associação com o tempo exponencial confunde algumas pessoas: elas pensam incorretamente que
problemas requerem tempo exponencial para resolver (ou pior ainda há nenhum algoritmo para eles em tudo). Afirmar que um problema está em
não significa que seja difícil resolvê-lo, apenas significa que é fácil verificar, é um limite superior na dificuldade de resolver o problema e muitos problemas são fáceis de resolver, pois .NPNPNPP⊆NP
No entanto, existem problemas que parecem difíceis de resolver. Voltarei a isso quando discutirmos a dureza .NPNP
Limites inferiores parecem difíceis de provar
OK, agora sabemos que existem
muitos problemas naturais em e não conhecemos nenhuma maneira eficiente de resolvê-los e suspeitamos que eles realmente exijam tempo exponencial para serem resolvidos. Podemos provar isso?NP
Infelizmente, a tarefa de provar limites inferiores é muito difícil. Não podemos nem provar que esses problemas exigem mais do que tempo linear ! Muito menos exigindo tempo exponencial.
Provar limites inferiores de tempo linear é bastante fácil: afinal, o algoritmo precisa ler a entrada. Provar limites inferiores super-lineares é uma história completamente diferente. Podemos provar limites inferiores super-lineares com mais restrições sobre o tipo de algoritmos que estamos considerando, por exemplo, ordenando algoritmos usando comparação, mas não sabemos limites inferiores sem essas restrições.
Para provar um limite superior para um problema, precisamos apenas projetar um algoritmo suficientemente bom. Muitas vezes, é necessário conhecimento, pensamento criativo e até engenhosidade para criar esse algoritmo.
No entanto, a tarefa é consideravelmente mais simples em comparação com a comprovação de um limite inferior. Temos que mostrar que não existem bons algoritmos . Não que não conheçamos algoritmos bons o suficiente no momento, mas que não existam algoritmos bons , que ninguém jamais venha com um bom algoritmo . Pense nisso por um minuto, se você ainda não o fez, como podemos mostrar um resultado tão impossível ?
Este é outro lugar onde as pessoas ficam confusas. Aqui "impossibilidade" é uma impossibilidade matemática , ou seja, não é uma curta vinda de nossa parte que algum gênio possa corrigir no futuro. Quando dizemos impossível, queremos dizer que é absolutamente impossível, tão impossível quanto . Nenhum avanço científico pode tornar isso possível. É isso que estamos fazendo quando estamos demonstrando limites mais baixos.1=0
Provar um limite inferior, isto é, mostrar que um problema requer uma certa quantidade de tempo para ser resolvido, significa que temos que provar que qualqueralgoritmo, mesmo os muito ingênuos que ainda não sabem, não podem resolver o problema mais rapidamente. Existem muitas idéias inteligentes que conhecemos (programação gananciosa, correspondente, dinâmica, programação linear, programação semidefinida, programação de soma de quadrados e muitas outras idéias inteligentes) e muitas outras ainda não sabemos. Descartar um algoritmo ou uma idéia específica de projetar algoritmos não é suficiente, precisamos excluir todos eles, mesmo aqueles que ainda não conhecemos, mesmo que nem todos conheçam! E podemos combinar tudo isso em um algoritmo, por isso precisamos descartar suas combinações também. Houve algum progresso no sentido de mostrar que algumas idéias não podem resolver dificuldadesNPproblemas, por exemplo, ganancioso e suas extensões não podem funcionar, e há algum trabalho relacionado a algoritmos de programação dinâmica, e há algumas maneiras particulares de usar a programação linear. Mas eles nem sequer estão perto de excluir as idéias inteligentes que conhecemos (procure limites inferiores em modelos restritos de computação, se você estiver interessado).
Barreiras: limites mais baixos são difíceis de provar
Por outro lado, temos resultados matemáticos chamados
barreiras
que dizem que uma prova de limite inferior não pode ser tal e tal, e tal e tal quase cobre todas as técnicas que usamos para provar limites inferiores! De fato, muitos pesquisadores desistiram de provar limites inferiores após o resultado da barreira de provas naturais de Alexander Razbarov e Steven Rudich
. Acontece que a existência de um tipo particular de provas de limite inferior implicaria a insegurança de geradores de números pseudoaleatórios criptográficos e muitas outras ferramentas criptográficas.
Digo quase porque nos últimos anos houve algum progresso principalmente por Ryan Williams
que foi capaz de contornar os resultados da barreira de maneira inteligente, ainda os resultados até agora são para modelos de computação muito fracos e muito longe de descartar algoritmos gerais de tempo polinomial .
Mas estou divergindo. O ponto principal que eu queria enfatizar era que provar limites inferiores é difícil e não temos limites inferiores fortes para algoritmos gerais que resolvem problemas de .NP
[Por outro lado, o trabalho de Ryan Williams mostra que existem conexões estreitas entre provar limites inferiores e provar limites superiores. Veja a palestra dele no ICM 2014, se você estiver interessado.]
Reduções: Resolvendo um problema usando outro problema como sub-rotina / Oracle / Black Box
A ideia de uma redução é muito simples: para resolver um problema, use um algoritmo para outro problema.
Aqui está um exemplo simples: suponha que queremos calcular a soma de uma lista de números naturais e que temos um algoritmo que retorna a soma de dois números fornecidos. Podemos usar para somar os números da lista? Claro!nSumSum
Problema:
Entrada: uma lista de números naturais ,
Saída: return . nx1,…,xn
∑ni=1xi
Algoritmo de redução:
- s=0
- para de a
2.1. i1n
s=Sum(s,xi)
- retornos
Aqui estamos usando em nosso algoritmo como uma sub - rotina . Observe que não nos importamos com o modo como o funciona, ele age como uma caixa preta para nós, não nos importamos com o que está acontecendo dentro do . Costumamos nos referir à subrotina como oráculo . É como o oráculo de Delfos na mitologia grega, fazemos perguntas e o oráculo as responde e usamos as respostas.SumSumSumSum
Isso é essencialmente o que é uma redução: assuma que temos um algoritmo para um problema e o use como um oráculo para resolver outro problema. Aqui eficiente significa eficiente assumindo que o oráculo responde em uma unidade de tempo, ou seja, contamos cada execução do oráculo em um único passo.
Se o oráculo retorna uma resposta grande é preciso lê-lo e que pode demorar algum tempo, por isso, devemos contar o tempo que leva -nos a ler a resposta que a Oracle tem dado para nós. Da mesma forma, para escrever / fazer a pergunta do oráculo. Mas o oracle funciona instantaneamente, ou seja, assim que fazemos a pergunta do oracle, o oracle escreve a resposta para nós em uma única unidade de tempo. Todo o trabalho que a Oracle realiza conta um único passo, mas isso exclui o tempo que leva para escrever a pergunta e ler a resposta.
Como não nos importamos com o funcionamento do oracle, mas apenas com as respostas que ele retorna, podemos simplificar e considerar o oracle como o próprio problema no lugar de um algoritmo para ele. Em outras palavras, não nos importamos se o oráculo não é um algoritmo, não nos importamos como o oráculo apresenta suas respostas.
Por exemplo,
na pergunta acima é a própria função de adição (não um algoritmo para calcular a adição).Sum
Podemos fazer várias perguntas de um oráculo, e as perguntas não precisam ser predeterminadas: podemos fazer uma pergunta e, com base na resposta que o oracle retorna, realizamos alguns cálculos por nós mesmos e depois fazemos outra pergunta com base na resposta que obtivemos para a pergunta anterior.
Outra maneira de encarar isso é pensar nisso como uma computação interativa . A computação interativa por si só é um tópico amplo, por isso não abordarei aqui, mas acho que mencionar essa perspectiva de reduções pode ser útil.
Um algoritmo que usa um oracle / caixa preta normalmente é indicado como .AOAO
A redução que discutimos acima é a forma mais geral de redução e é conhecida como redução de caixa preta
(também conhecida como redução de oráculo , redução de Turing ).
Mais formalmente:
Dizemos que o problema é uma caixa preta redutível ao problema e escrevemos se
houver um algoritmo tal que, para todas as entradas , .QOQ≤TO
Ax
Q(x)=AO(x)
Em outras palavras, se existe um algoritmo que utiliza o oráculo como uma sub-rotina e resolve o problema .AOQ
Se o nosso algoritmo de redução é executado em tempo polinomial, chamamos de redução de caixa-preta de tempo polinomial ou simplesmente uma redução Cozinhe
(em homenagem a
Stephen A. Cook ) e escrever . (O subscrito significa "Turing" em homenagem a
Alan Turing ).AQ≤PTOT
No entanto, podemos querer colocar algumas restrições na maneira como o algoritmo de redução interage com o oráculo. Há várias restrições que são estudadas, mas a restrição mais útil é o chamado muitos e um reduções
(aka reduções de mapeamento ).
A idéia aqui é que, em uma dada entrada , realizamos alguma computação em tempo polinomial e geramos um
que é uma instância do problema que o oráculo resolve. Depois pedimos ao oráculo e devolvemos a resposta que ele nos retorna. Estamos autorizados a fazer uma única pergunta do oráculo e as respostas do oráculo são o que será retornado.xy
Mais formalmente,
Dizemos que o problema é muitos redutível ao problema e escrevemos se
houver um algoritmo tal que, para todas as entradas , .QOQ≤mO
Ax
Q(x)=O(A(x))
Quando o algoritmo de redução é tempo polinomial chamamos isso
polinomial-time redução por mapeamento ou simplesmente redução Karp (em homenagem a
Richard M. Karp ) e denotam que por .Q≤PmO
A principal razão para o interesse nessa redução não interativa específica é que ela preserva os problemas de : se houver uma redução de muitos polinômios de um problema para um problema , então também está em .NPANPBANP
A noção simples de redução é uma das noções mais fundamentais na teoria da complexidade, juntamente com o , e (que discutiremos abaixo).PNPNP
A postagem ficou muito longa e excede o limite de uma resposta (30000 caracteres). Continuarei a resposta na Parte II .