Я також працював над цією проблемою. Як початківцю, так і класичному програмісту (тобто я не кажу про квантову механіку) важко зрозуміти поняття без повних прикладів. Я працював із зразком пошуку бази даних Microsoft Q # . Він просто шукає певний індекс / ключ у базі даних, що не дуже корисно. Я розширив цей зразок для пошуку списку значень у базі даних та повернення відповідного ключа.
Як і у вашому прикладі, для індексів існує один двокібітний «реєстр ключів» та окремий двохубітний регістр для значень. Існує також п'ятий "позначений кубіт", що надходить із зразка Microsoft, щоб вказати, коли знайдено потрібне значення. Ключі та значення пов'язані через заплутування. Це найкраще демонструється схемою. Клацніть тут, щоб побачити фактичну схему Quirk .
Зауважте, що ця схема містить лише оракул. Він не реалізує весь алгоритм Гровера.
- Два верхніх кубіта - це регістр ключів, наступні два - регістр значень, а нижній кубіт - позначений кубіт.
- У першому розділі реєстр ключів ставить у єдиний суперпозицію за допомогою воріт Харамарда, як того вимагає алгоритм Гровера.
- Другий розділ - це те, де ключі пов'язані зі значеннями за допомогою заплутування. Кожен ключ заплутується відповідним значенням у регістрі значень, застосовуючи (Анти-) керовані ворота X. Отже, коли реєстр ключів дорівнює 0, тоді регістр значень буде встановлений на 3. Коли ключ дорівнює 1, значення встановлюється на 2 тощо.
- Третій розділ схеми - це пошуковий оракул. Реєстр значень переплутаний позначеним кубітом. У цьому прикладі бажане значення дорівнює 2. Коли регістр значень містить 2, позначений кубіт буде встановлений у 1.
- Алгоритм Гровера переглядає реєстр ключів і позначений кубіт. Оракул пошуку розглядає регістр значень і встановлює позначений кубіт. Це призведе до посилення ключа 1, коли значення дорівнює 2.
Цікаво зазначити, що ключі та значення зберігаються не в кубітах, а в ланцюзі / програмі. Можна сказати, що це насправді не база даних. Це більше схоже на оператор switch / case, але такий, який може працювати на суперпозиції значень.
Детальніше, застереження та код Q # див. У моєму сховищі GitHub .
EDIT: Щось я краще розумію після відповіді ... ви повинні повернути / скасувати ланцюг як частину кожної ітерації. У коді Q # виклик суміжного стануPreparationOracle () в рамках операції ReflectStart () обробляє це, тому мені не довелося це робити явно. Я не знаю, чи має Qiskit подібну особливість. Якщо я зробив переклад належним чином, ось цілий контур для прикладу вище.