Se você mora entre os loucos, precisa aprender a ser loucoVocê já tentou "aprender a ser louco"? Tarefa não trivial. Você nem encontra uma técnica normal, porque todo mundo enlouquece à sua maneira. Minha primeira tentativa: teoria da conspiração. A teoria não envolve prática, o que significa que você não precisa trabalhar duro. Novamente, em qualquer situação, ninguém sofrerá.
Como criar teorias da conspiração?Criar uma teoria da conspiração é relativamente simples. Precisamos de uma idéia que seja simples o suficiente para ser aceita por 90% da população. Deve ser controverso, para que 5% da população possa explicar 90% de quais são os idiotas. Por fim, precisamos de algumas pesquisas que essas 95% das pessoas não entendem, mas que são usadas por 90% como argumento "as pessoas se mostraram mais inteligentes que nós ...".
A computação quântica é uma ótima área para esse estudo. Você pode criar um esquema simples, mas a palavra "quantum" adicionará peso aos resultados.
O objeto de estudo é um jogo, pois se deve à juventude simples e familiar. Quem está envolvido na computação quântica e nos jogos? Google
Então, teoria herética: depois de 5 anos, Page e Green decidirão quem será o principal no Google e farão isso com a ajuda do jogo. Cada um deles tem um grupo de pesquisadores. A equipe AlphaGo, com suas redes neurais de
combate , puxou rivais em Go. Os opositores foram forçados a procurar novos métodos e ainda encontraram um instrumento de
total superioridade: a computação quântica.
Posso usar a Quantum Computing para jogos? Fácil. Vamos mostrar, por exemplo, que o jogo "caçador de raposas" pode ser "resolvido" em 6 movimentos. Por uma questão de credibilidade, nos restringimos a 15 qubits (a quirk do editor on-line não emula por mais de quinze), por uma questão de simplicidade, ignoramos as limitações da arquitetura do processador e correção de erros.
As regras
Extremamente simples.
Existem cinco orifícios dispostos em uma fila (nós os numeramos como 0-1-2-3-4). Em um deles é uma raposa. Toda noite, a raposa passa para a próxima marta, esquerda ou direita. Todas as manhãs, o caçador pode verificar um buraco para escolher. A tarefa do caçador é pegar a raposa. A tarefa da raposa é sobreviver. Em teoria, uma raposa pode fugir de um caçador para sempre. Na prática, existe uma estratégia vencedora: verifique os buracos 1-2-3-1-2-3. Somente essa estratégia vou testar.
Construindo um esquema
Vamos começar com o início dos qubits 0-1-2-3-4 (5 orifícios).
Aqui você pode editar
De fato, após a iniciação, temos um sistema no qual, após a medição, estritamente um qubit será único. As probabilidades de "unidade" diferem para cada qubit, mas no nosso caso isso não é crítico. Devemos deixar espaço para discussão sobre o esquema (e nossa teoria ao mesmo tempo).
No Q #, obtemos código como este:
operation TestStrategy () : (Result) { let res = Zero; using(qubits=Qubit[16]) {
O TestStrategy testará nossa estratégia 1-2-3-1-2-3, InitFoxHoles () é responsável apenas pelo início de buracos de raposa. Vamos verificar a iniciação. Copie o TestStrategy, inicie a iniciação, meça os 5 primeiros qubits e retorne seus valores.
operation TestInit(): (Result, Result, Result, Result, Result) { body { mutable res0 = Zero; mutable res1 = Zero; mutable res2 = Zero; mutable res3 = Zero; mutable res4 = Zero; using(qubits=Qubit[16]) {
Executaremos o teste mil vezes (várias execuções são típicas de algoritmos quânticos, em alguns locais até necessários). Código de chamada - no spoiler, resultados: na tela abaixo.
Teste rapidamente a iniciação static void TestInitiation() { using (var sim = new QuantumSimulator()) { var initedQubitsValues = Enumerable.Range(0, 5) .ToDictionary(qubitIndex => qubitIndex, oneMesaured => 0); for (int i = 0; i < 1000; i++) { (Result, Result, Result, Result, Result) result = TestInit.Run(sim).Result; if (result.Item1 == Result.One) { initedQubitsValues[0]++; } if (result.Item2 == Result.One) { initedQubitsValues[1]++; } if (result.Item3 == Result.One) { initedQubitsValues[2]++; } if (result.Item4 == Result.One) { initedQubitsValues[3]++; } if (result.Item5 == Result.One) { initedQubitsValues[4]++; } } Console.WriteLine($"Qubit-0 initiations: {initedQubitsValues[0]}"); Console.WriteLine($"Qubit-1 initiations: {initedQubitsValues[1]}"); Console.WriteLine($"Qubit-2 initiations: {initedQubitsValues[2]}"); Console.WriteLine($"Qubit-3 initiations: {initedQubitsValues[3]}"); Console.WriteLine($"Qubit-4 initiations: {initedQubitsValues[4]}"); } }

Algo deu errado. Uma distribuição quase uniforme era esperada. O motivo é simples: no passo 3, inverti o terceiro qubit, em vez do primeiro: (Controlado (X)) ([registrador [0], registrador [2]], registrador [3]);
não é bom copiar e colar velho.
Nós corrigimos o código, executamos o teste:

Já está melhor. O código pode ser visto no nabo, versão
Commit 1 .
Onde correr a raposa?
Selecione o qubit qubit (a numeração começa de cima) sob a direção atual da raposa. Concordamos que zero significa movimento descendente, uma unidade significa movimento ascendente. Obviamente, se a raposa já estiver no buraco zero - ela deve descer. Se a raposa estiver no quarto buraco, ela se move para cima. Em outros casos, a raposa pode se mover para cima e para baixo. De acordo com essas regras simples, podemos definir o “qubit da direção atual” para 0, 1 ou uma superposição de zero e um. Examinamos o código no repositório,
Commit 2 .
Esquema no editor.Código e teste
static void TestMovementDirectionSetup() { using (var sim = new QuantumSimulator()) { List<string> results = new List<string>(); string initedCubit = null; string moveDirection = null; for (int i = 0; i < 1000; i++) { (Result, Result, Result, Result, Result, Result) result = Quantum.FoxHunter.TestMovementDirectionSetup.Run(sim).Result; if (result.Item1 == Result.One) { initedCubit = "0"; } if (result.Item2 == Result.One) { initedCubit = "1"; } if (result.Item3 == Result.One) { initedCubit = "2"; } if (result.Item4 == Result.One) { initedCubit = "3"; } if (result.Item5 == Result.One) { initedCubit = "4"; } if (result.Item6 == Result.One) { moveDirection = "1"; } else { moveDirection = "0"; } results.Add($"{initedCubit}{moveDirection}"); } foreach(var group in results .GroupBy(result => result) .OrderBy(group => group.Key)) { Console.WriteLine($"{group.Key} was measured {group.Count()} times"); } Console.WriteLine($"\r\nTotal measures: {results.Count()}"); } }

Movimento
Implementado por SWAP controlado. Se o qubit de controle for único - troque para baixo. Se o qubit de controle for zero, trocamos.
Esquema no editor .
Q #: declaração para testes operation TestFirstMovement(): (Result, Result, Result, Result, Result, Result) { body { mutable res0 = Zero; mutable res1 = Zero; mutable res2 = Zero; mutable res3 = Zero; mutable res4 = Zero; mutable res5 = Zero; using(qubits=Qubit[16]) { InitFoxHoles(qubits); SetupMovementDirection(qubits); MakeMovement(qubits); set res0 = M(qubits[0]); set res1 = M(qubits[1]); set res2 = M(qubits[2]); set res3 = M(qubits[3]); set res4 = M(qubits[4]); set res5 = M(qubits[5]); ResetAll(qubits);
Código c # static void TestFirstMove() { using (var sim = new QuantumSimulator()) { List<string> results = new List<string>(); string initedCubit = null; string moveDirection = null; for (int i = 0; i < 1000; i++) { (Result, Result, Result, Result, Result, Result) result = Quantum.FoxHunter.TestFirstMovement.Run(sim).Result; if (result.Item1 == Result.One) { initedCubit = "0"; } if (result.Item2 == Result.One) { initedCubit = "1"; } if (result.Item3 == Result.One) { initedCubit = "2"; } if (result.Item4 == Result.One) { initedCubit = "3"; } if (result.Item5 == Result.One) { initedCubit = "4"; } if (result.Item6 == Result.One) { moveDirection = "1"; } else { moveDirection = "0"; } results.Add($"{initedCubit}{moveDirection}"); }
O código pode ser exibido no
Commit 3 .
Nós fazemos 6 movimentos
Finalmente, selecionamos o sexto qubit para o status do jogo (a raposa é livre / a raposa não é livre). A unidade corresponde a uma raposa livre. Nós faremos outros movimentos apenas com um único qubit de status.
Os qubits 7,8,9,10,11 manterão um histórico de jogadas. Após cada movimento, vamos trocar um deles com um qubit da direção atual (isso nos permitirá armazenar o histórico de movimentos e redefinir o qubit da direção atual antes de cada movimento).
Esquema em anexo .
Q #: declaração para testes operation TestSixMovements(): (Result) { body { mutable res = Zero; using(qubits=Qubit[16]) { ResetAll(qubits); InitFoxHoles(qubits); X(qubits[6]);
C #: teste static void TestMovements() { using (var sim = new QuantumSimulator()) { int zerosCount = 0; for (int i = 0; i < 1000; i++) { Result result = Quantum.FoxHunter.TestSixMovements.Run(sim).Result; if(result == Result.Zero) { zerosCount++; } } Console.WriteLine($"\r\nTotal zeroes: {zerosCount}"); } }
Observamos o
Commit 4 .
Toques finais
Temos um erro no circuito. Como testamos a estratégia 1-2-3-1-2-3, verificamos cada buraco duas vezes. Assim, tendo capturado a raposa no primeiro movimento, passaremos pelo qubit de status duas vezes (no primeiro e no quarto).
Para evitar essa situação, usamos 12 qubits para corrigir o status após os movimentos 4-5-6. Além disso, adicionamos a definição de vitória: se pelo menos um dos qubits de status virar zero, vencemos.
O esquema final .
Q #: corrija o operador 6 move operation MakeSixMovements(qubits: Qubit[]) : Unit { body {
P #: corrija a estratégia de teste do operador 1-2-3-1-2-3 operation TestStrategy () : (Result) {
C #: executar verificação final static void RunFoxHunt() { Stopwatch sw = new Stopwatch(); sw.Start(); using (var sim = new QuantumSimulator()) { var foxSurvives = 0; var hunterWins = 0; for (int i = 0; i < 1000; i++) { var result = (Result)(TestStrategy.Run(sim).Result); if (result == Result.Zero) { foxSurvives++; } else { hunterWins++; } } Console.WriteLine($"Fox survives: \t{foxSurvives}"); Console.WriteLine($"Hunter wins: \t{hunterWins}"); } sw.Stop(); Console.WriteLine($"Experiment finished. " + $"Time spent: {sw.ElapsedMilliseconds / 1000} seconds"); }
Confirme 5 .
O que se segue
Em princípio, o esquema pode ser otimizado tanto no número de qubits quanto no número de operações. A otimização trivial para o número de qubits é livrar-se do qubit-13, retornando apenas 6 e 12. Otimização para operações - para dar o primeiro tiro imediatamente após o início. No entanto, vamos deixar esse trabalho para os engenheiros do Google.
Como você pode ver, qualquer pessoa que esteja familiarizada superficialmente com a computação quântica pode interpretar com segurança o "caçador de raposas". Se tivéssemos um pouco mais de qubits, poderíamos encontrar a solução ideal e não verificar a existente. É inteiramente possível que o jogo da velha (e sua versão quântica), damas, xadrez, Go caiam a seguir.
Ao mesmo tempo, a questão da "solvabilidade" de jogos como DotA, Starcraft e Doom permanece em aberto. Para a computação quântica, o armazenamento de todo o histórico de cliques é característico. Tomamos APM (Ações por minuto) de 500, multiplicamos pelo número de jogadores, multiplicamos pelo número de minutos, adicionamos a aleatoriedade do jogo em si - o número de qubits necessários para armazenar todas as informações cresce muito rapidamente.
Portanto, escolher um jogo em uma pequena competição entre Brin e Page pode desempenhar um papel decisivo. No entanto, a geração de um jogo "igualmente difícil" para computadores clássicos e quânticos merece sua própria teoria.