Квантовый оракул слабой раскраски всего графа
Входы:
1. Число вершин V, V≤6.
2. Массив edges из E пар целых индексов начала и конца ребра, E≤12. Вершины имеют номера от 0 до V−1.
3. Регистр x из 2V кубитов в произвольном состоянии, задающий четыре возможных цвета (nBits=2). Цвет вершины i хранится в x[2i],x[2i+1] со старшим разрядом первым: 00,01,10,11 означают 0,1,2,3.
4. Целевой кубит y в произвольном состоянии.
Напишите на языке Q# оракул, инвертирующий y, если слабая раскраска графа правильная: каждая вершина либо изолирована, либо соединена ребром хотя бы с одной вершиной другого цвета.
Восстановите исходные значения регистра x после вычисления. Решение должно работать на суперпозициях; измерения запрещены. Полные вспомогательные операции из предыдущих упражнений даны в заготовке.
Заготовка Q#:
namespace Kata {
import Std.Arrays.*;
operation Oracle_WeakColoring(
V : Int,
edges : (Int, Int)[],
x : Qubit[],
y : Qubit
) : Unit is Adj + Ctl {
// Implement your solution here...
}
// You might find these helper operations from earlier tasks useful.
operation Oracle_WeakColoring_OneVertex(
V : Int,
edges : (Int, Int)[],
x : Qubit[],
y : Qubit,
vertex : Int
) : Unit is Adj + Ctl {
let neighborEdges = Filtered((a, b) -> a == vertex or b == vertex, edges);
let nNeighbors = Length(neighborEdges);
use sameColorChecks = Qubit[nNeighbors];
within {
for ((a, b), checkQubit) in Zipped(neighborEdges, sameColorChecks) {
Oracle_ColorEquality(
x[a * 2 .. a * 2 + 1],
x[b * 2 .. b * 2 + 1],
checkQubit
);
}
} apply {
X(y);
if nNeighbors > 0 {
Controlled X(sameColorChecks, y);
}
}
}
operation Oracle_ColorEquality(x0 : Qubit[], x1 : Qubit[], y : Qubit) : Unit is Adj + Ctl {
within {
for i in 0..Length(x0) - 1 {
CNOT(x0[i], x1[i]);
}
} apply {
ApplyControlledOnInt(0, X, x1, y);
}
}
}