Если ты живешь среди сумасшедших, тебе придется самому научиться быть сумасшедшим.
Вы когда-нибудь пробовали «научиться быть сумасшедшим»? Нетривиальная проблема.
Даже нормального метода не найдешь, потому что каждый сходит с ума по-своему.
Моя первая попытка: теория заговора.
Теория не предполагает практики, а значит, вам не придется усердно работать.
Опять же, в любом случае никто не пострадает. Как создавать теории заговора? Создать теорию заговора относительно легко.
Нам нужна идея, которая будет достаточно простой, чтобы ее могли принять 90% населения.
Оно должно быть спорным, чтобы 5% населения могли объяснить 90%, какие они идиоты.
Наконец, нам нужно какое-то исследование, которое эти 95% людей не понимают, но которое используется 90% как аргумент «люди умнее нас доказали…».
Квантовые вычисления — отличная область для таких исследований.
Вы можете набросать простую диаграмму, но слово «квант» придаст вес результатам.
Объектом исследования является игра, поскольку объект должен быть простым и знакомым подросткам.
Кто занимается квантовыми вычислениями и играми? Google. Итак, еретическая теория: через 5 лет Пейдж и Грин будут решать, кто будет руководить Google, и сделают это через игру.
В каждом из них есть группа исследователей.
Команда AlphaGo своими боевыми нейронными сетями привлекла соперников в Го.
Противники были вынуждены искать новые методы и, наконец, обнаружили инструмент тотального превосходства: квантовые вычисления.
Можно ли использовать квантовые вычисления для игр? Легко.
Покажем, например, что игру «Охотник на лис» можно «разгадать» за 6 ходов.
Для правдоподобия ограничимся 15 кубитами (онлайн-редактор причуд не эмулирует более пятнадцати); для простоты мы будем игнорировать ограничения архитектуры процессора и исправления ошибок.
Правила
Чрезвычайно просто.В ряд расположены пять лунок (нумеруем их 0-1-2-3-4).
В одном из них сидит лиса.
Каждую ночь лиса перебирается в следующую нору слева или справа.
Каждое утро охотник может проверить одну лунку по своему выбору.
Задача охотника – поймать лису.
Задача лисы – выжить.
Теоретически лиса может вечно убегать от охотника.
На практике есть выигрышная стратегия: проверить лунки 1-2-3-1-2-3. Это единственная стратегия, которую я буду тестировать.
Построение схемы
Начнем с инициации кубитов 0-1-2-3-4 (5 дырок).
Вы можете редактировать здесь
Фактически, после инициации мы имеем систему, в которой после измерения ровно один кубит будет единицей.
Вероятности «единицы» для каждого кубита различны, но в нашем случае это не критично.
Надо оставить место для обсуждения схемы (и заодно нашей теории).
В Q# мы получим такой код:
TestStrategy проверит нашу стратегию 1-2-3-1-2-3, InitFoxHoles() отвечает только за создание лисьих нор.operation TestStrategy () : (Result) { let res = Zero; using(qubits=Qubit[16]) { // 0.4 - holes // 5 - current movement direction. Zero means "go down", One means "go up" // 6 - Game status. 1 means "fox is free, go further" // 7,8,9,10, 11 - movements history InitFoxHoles(qubits); ResetAll(qubits); // ALWAYS clean after yourself } return Zero; } // Inits fox holes, with almost equal probabilities operation InitFoxHoles(register: Qubit[]) : Unit { body { ResetAll(register); // Step 1 H(register[0]); H(register[2]); // Step 2 (Controlled (X))([register[0],register[2]], register[3]); // Step 3 X(register[0]); X(register[2]); (Controlled (X))([register[0],register[2]], register[3]); X(register[0]); X(register[2]); // Step 4 CNOT(register[3], register[0]); CNOT(register[3], register[2]); // Step 5 (Controlled (H))([register[3]], register[4]); // Step 6 CNOT(register[4], register[3]); } }
Проверим инициацию.
Давайте скопируем TestStrategy, запустим инициацию, измерим первые 5 кубитов и вернем их значения.
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])
{
// 0.4 - holes
// 5 - current movement direction. Zero means "go down", One means "go up"
// 6 - Game status. 1 means "fox is free, go further"
// 7,8,9,10, 11 - movements history
InitFoxHoles(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]);
ResetAll(qubits); // ALWAYS clean after yourself
}
return (res0, res1, res2, res3, res4);
}
}
Мы проведем тест тысячу раз (несколько прогонов характерны для квантовых алгоритмов, а кое-где они даже необходимы).
Код вызова под спойлером, результаты на скриншоте ниже.
Давайте быстро проверим инициацию 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]}");
}
}
Что-то пошло не так.
Ожидалось почти равномерное распределение.
Причина проста: на шаге 3 я инвертировал третий кубит вместо первого: (Controlled (X))([register[0],register[2]], Register[3]); старый плохой копипаст.
Исправляем код и запускаем тест: Исправлено инициирование // Inits fox holes, with almost equal probabilities
operation InitFoxHoles(register: Qubit[]) : Unit
{
body
{
ResetAll(register);
// Step 1
H(register[0]);
H(register[2]);
// Step 2
(Controlled (X))([register[0],register[2]], register[3]);
// Step 3
X(register[0]);
X(register[2]);
(Controlled (X))([register[0],register[2]], register[1]);
X(register[0]);
X(register[2]);
// Step 4
CNOT(register[3], register[0]);
CNOT(register[3], register[2]);
// Step 5
(Controlled (H))([register[3]], register[4]);
// Step 6
CNOT(register[4], register[3]);
}
}
}
Уже лучше.
Код можно найти в репе, версия Зафиксировать 1 .
Куда бежать лисе?
Выделим пятый кубит (нумерация начинается сверху) для текущего направления движения лисы.Договоримся, что ноль означает движение вниз, единица – движение вверх.
Очевидно, что если лиса уже находится в нулевой норе, она должна двигаться вниз.
Если лиса находится в четвертой норе, она движется вверх.
В остальных случаях лисица может двигаться как вниз, так и вверх.
Используя эти простые правила, вы можете установить «кубит текущего направления» на 0, 1 или суперпозицию нуля и единицы.
Смотрим код в репозитории, Коммит 2 .
Код и тест // Select next Fox movement direction, updating qubit 5
// 1 means go up (4 -> 3, 3 -> 2, .
1 -> 0) // 0 means go down (0 -> 1, 1 -> 2, .
3 -> 4)
operation SetupMovementDirection(qubits: Qubit[]) : Unit
{
body
{
// Step 1
CNOT(qubits[4], qubits[5]);
// Step 2
(Controlled (H))([qubits[3]], qubits[5]);
// Step 3
(Controlled (H))([qubits[2]], qubits[5]);
// Step 4
(Controlled (H))([qubits[1]], qubits[5]);
}
}
operation TestMovementDirectionSetup(): (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);
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); // ALWAYS clean after yourself
}
return (res0, res1, res2, res3, res4, res5);
}
}
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()}");
}
}
Движение
Реализовано посредством управляемого SWAP. Если управляющий кубит один, мы меняем местами вниз.Если управляющий кубит обнулён, мы меняем местами.
оператор Q# // Makes a movement based on the 5'th qubit value
// 1 means go up (4 -> 3, 3 -> 2, .
1 -> 0) // 0 means go down (0 -> 1, 1 -> 2, .
3 -> 4)
operation MakeMovement(qubits: Qubit[]) : Unit
{
body
{
// Code movement Up
// Step 1
mutable qubitsToSwap = [qubits[0], qubits[1]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
// Step 2
set qubitsToSwap = [qubits[1], qubits[2]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
// Step 3
set qubitsToSwap = [qubits[2], qubits[3]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
// Step 4
set qubitsToSwap = [qubits[3], qubits[4]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
// COde movement down
X(qubits[5]); // Invert direction qubit for the ZeroControlled operations
// Step 5
set qubitsToSwap = [qubits[3], qubits[4]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
// Step 6
set qubitsToSwap = [qubits[2], qubits[3]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
// Step 7
set qubitsToSwap = [qubits[1], qubits[2]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
// Step 8
set qubitsToSwap = [qubits[0], qubits[1]];
(Controlled(SwapReverseRegister))([qubits[5]],qubitsToSwap);
X(qubits[5]); // Back-invert for the direction qubit
}
}
Вопрос#: оператор для тестов 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); // ALWAYS clean after yourself
}
return (res0, res1, res2, res3, res4, res5);
}
}
код С# 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}"); } // Holes measurements foreach (var group in results .
GroupBy(result => result[0]) .
OrderBy(group => group.Key)) { Console.WriteLine($"{group.Key} hole was measured {group.Count()} times"); } // Directions measuremetns foreach (var group in results .
GroupBy(result => result[1]) .
OrderBy(group => group.Key))
{
Console.WriteLine($"{group.Key} direction was measured {group.Count()} times");
}
Console.WriteLine($"\r\nTotal measures: {results.Count()}");
}
}
Код можно посмотреть в Коммит 3 .
Делаем 6 ходов
Наконец, мы выделяем шестой кубит для статуса игры (лиса свободна/лиса не свободна).Один соответствует свободной лисе.
Дальнейшие ходы мы будем делать только с одним статусным кубитом.
Кубиты 7,8,9,10,11 будут хранить историю ходов.
После каждого хода мы будем сопоставлять один из них с кубитом текущего направления (это позволит нам хранить историю ходов и сбрасывать кубит текущего направления перед каждым ходом).
Q# оператор /// Make 6 movements. Every movement is controlled by the 6'th qubit.
/// After the every qubit we check if the fox has been captured and invert the 6'th qubit
/// Reminder: 6'th qubit equal to One means "Fox is free, go further"
operation MakeSixMovements(qubits: Qubit[]) : Unit
{
body
{
// Move 1
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[1], qubits[6]); // Reverse Fox State if it's shot
// Move 2
SwapReverseRegister([qubits[5], qubits[7]]); // Move the first move direction to the qubit 7, qubit 5 is Zero again
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[2], qubits[6]);
// Move 3
SwapReverseRegister([qubits[5], qubits[8]]);
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[3], qubits[6]);
// Move 4
SwapReverseRegister([qubits[5], qubits[9]]);
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[1], qubits[6]);
// Move 5
SwapReverseRegister([qubits[5], qubits[10]]);
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[2], qubits[6]);
// Move 6
SwapReverseRegister([qubits[5], qubits[11]]);
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[3], qubits[6]);
}
}
Q#: оператор для тестов operation TestSixMovements(): (Result)
{
body
{
mutable res = Zero;
using(qubits=Qubit[16])
{
ResetAll(qubits);
InitFoxHoles(qubits);
X(qubits[6]); // At the beginning of the game our fox is alive
MakeSixMovements(qubits);
set res = M(qubits[6]);
ResetAll(qubits); // ALWAYS clean after yourself
}
return (res);
}
}
С#: тестирование 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}");
}
}
Давайте посмотрим Коммит 4 .
Последние штрихи
У нас ошибка в схеме.Поскольку мы тестируем стратегию 1-2-3-1-2-3, то каждую лунку мы тестируем дважды.
Соответственно, поймав лису на первом ходу, мы пройдем статусный кубит дважды (на первом ходу и четвертом).
Чтобы избежать такой ситуации, мы используем кубит 12 для фиксации статуса после ходов 4-5-6. Кроме того, мы добавим определение победы: если хотя бы один из статусных кубитов обращается в ноль, мы победили.
Q#: исправить движения оператора 6 operation MakeSixMovements(qubits: Qubit[]) : Unit
{
body
{
// Move 1
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[1], qubits[6]); // Reverse Fox State if it's shot
// Move 2
SwapReverseRegister([qubits[5], qubits[7]]); // Move the first move direction to the qubit 7, qubit 5 is Zero again
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[2], qubits[6]);
// Move 3
SwapReverseRegister([qubits[5], qubits[8]]);
(Controlled(SetupMovementDirection))([qubits[6]],(qubits));
(Controlled(MakeMovement))([qubits[6]],(qubits));
CNOT(qubits[3], qubits[6]);
// Move 4
SwapReverseRegister([qubits[5], qubits[9]]);
(Controlled(SetupMovementDirection))([qubits[6], qubits[12]],(qubits));
(Controlled(MakeMovement))([qubits[6], qubits[12
Теги: #Квантовые технологии #Разработка игр #Логические игры #.
NET #будущее близко #Q #безумие #far Cry 3 #квантовые схемы
-
Худшая Реклама 2015 Года.
19 Oct, 24 -
Выпущен Windows Server 2012 Essentials
19 Oct, 24 -
Транспортные Магнаты
19 Oct, 24