Применение Алгоритма Гровера Для Поиска Гамильтоновых Циклов В Графе



1. Введение В этой статье представлено применение квантового алгоритма Гровера для решения задачи поиска гамильтоновых циклов в графе.

Сразу хочу отметить, что данное решение проблемы носит обучающий характер.

Это не даст так называемого «квантового превосходства», так как по мере увеличения количества вершин в графе нам потребуется большее количество кубитов, циклов Гровера и запусков самого алгоритма.

Однако я думаю, что этот вариант заслуживает внимания, возможно, кого-то он вдохновит на поиск более оптимального решения.



2. Постановка задачи

Представим, что имеется граф, состоящий из пяти вершин.

О , А , Б , С , Д , и восемь ребер.

Вершина О мы будем считать отправной точкой.



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

5-вершинный граф Некий путешественник, находящийся в какой-то точке О , хочет пройти все вершины графа, войти в каждую из них только один раз и снова вернуться в исходную точку О .

Необходимо найти все возможные маршруты передвижения, удовлетворяющие условиям задачи.

Решение этой проблемы легко найти самостоятельно.

Всего существует 4 варианта этого пути, несмотря на то, что два из них являются обратными последовательностями двух других:

  • ОКАДБО и ОБДАКО


Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Гамильтоновы циклы в графе (1)
  • ОДАКБО и ОБКАДО


Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Гамильтоновы циклы в графе (2) Путешественнику в отправной точке О , вам нужно сделать 5 шагов.

На каждом шаге путешественник движется по соединительному ребру от одной вершины к другой.

Все посещенные вершины должны быть уникальными для маршрута, за исключением точки О , путник попадает в нее дважды, так как последний 5-й шаг должен привести его в исходное положение.

Маршрутом будем называть последовательность вершин, через которые должен пройти путешественник, например: ОБКАДО .

Каким бы ни был маршрут (последовательность вершин), он должен удовлетворять следующим правилам:

  • вершины маршрута должны быть уникальными, путешественник не заходит в одну и ту же точку дважды;
  • Переход на любом шаге маршрута возможен только в ту вершину, которая соединена с текущей:
    • А соединяется с С И Д
    • Б соединяется с О , С И Д
    • С соединяется с О , А , Б , С , Д
    • Д соединяется с О , А , Б , С , Д
  • маршрут начинается и заканчивается в точке О , поэтому для простоты исключим ее из маршрута, оставив только меняющуюся часть — 4 вершины.

Как мы решим? Эту проблему можно решить в лоб, грубой силой.

Итак, мы будем перебирать 4 * 4 * 4 * 4 = 256 комбинаций вершин:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

При поиске нам необходимо определить, удовлетворяет ли рассматриваемый маршрут в конкретный момент условиям задачи.

Давайте посмотрим на несколько примеров.

Допустим, мы рассматриваем маршрут АДЦБ .

Для путешественника это невозможно, так как первый шаг должен быть из точки О к одной из вершин, соединенных с этой точкой.

Вертекс А не подключается к точке О , нам следует отказаться от такого маршрута.

Другой пример, маршрут СААБ - его тоже нужно выбросить, так как в нем путешественнику придется дважды подняться на вершину А .

Другой пример, маршрут БАКД , его тоже отбрасываем, путешественнику не выбраться из топа Б прямо наверх А (второй шаг), так как эти вершины не связаны.

Итак, нам нужно перебрать 256 комбинаций, из которых следует отбросить те, в которых:

  • хотя бы одна из вершин повторяется
  • любые две соседние вершины в комбинации не соединены ребром
  • первая вершина в комбинации не соединена с начальной точкой О
  • последняя вершина в комбинации не соединена с начальной точкой О
Эту задачу можно решить в цикле на обычном ПК, однако мы преследуем образовательные цели и хотим разработать решение для квантового компьютера.

Для этого воспользуемся квантовым алгоритмом Гровера.

Давайте выразим маршрут и вершины на языке кубитов.

Возьмем 8 кубитов и разделим их на 4 пары.

Первая пара соответствует первой вершине пути, вторая пара — второй вершине и т. д. В каждой паре кубитов возможна одна из 4-х комбинаций кубитов: 00, 01, 10, 11. Предположим, что каждая из этих комбинаций соответствует одна из возможных вершин: А , Б , С , Д :

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Ранее обсуждавшиеся комбинации АДЦБ , СААБ И БАКД будет соответствовать следующим комбинациям кубитов: 00111001, 10000001 и 01001011 соответственно.

Если применить к этим восьми кубитам оператор Адамара, то мы получим суперпозицию всех возможных вариантов движения путешественника, то есть всех 256 комбинаций.

Далее в оракуле нам необходимо реализовать процедуры, которые будут проверять эти комбинации на соответствие условиям задачи.

Однако еще до реализации оракула мы можем использовать один трюк, который позволит нам сократить количество комбинаций почти вдвое.



3. Суперпозиция

Самым первым шагом большинства квантовых алгоритмов является создание суперпозиции всех входных кубитов.

Однако здесь мы можем отступить от традиции и использовать небольшую хитрость, которую применили авторы.

Эта статья .

Суть трюка в следующем: если мы знаем невозможные комбинации кубитов, мы можем заранее исключить их из суперпозиции.

Так как 1-й шаг делается из точки О , и первая вершина должна быть соединена с этой точкой, а значит, она не может быть вершиной А , это могут быть только вершины Б , С или Д .

Аналогично делается последний 5-й шаг от 4-й вершины до точки О , и он должен быть соединен с точкой О , что означает, что это не может быть вершиной А .

Поскольку первой вершиной маршрута может быть только вершина Б , С или Д , то первая пара кубитов, соответствующая первой вершине маршрута путешественника, может принимать только следующие значения: 01, 10 и 11. То же самое справедливо и для последней пары кубитов, соответствующей четвертой вершине маршрута.

.

Таким образом мы исключим ненужную комбинацию 00 (вершина А ) для первой и четвертой вершин и благодаря этому нам больше не нужно проверять в оракуле связь этих вершин с точкой О , и сократим количество комбинаций до 3*4*4*3 = 144. Итак, давайте посмотрим, как эта техника работает для пары кубитов.

Начальное состояние системы двух кубитов запишем следующим образом:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Выполним ряд преобразований.

Шаг 1. Подействуем на первый кубит оператором

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

с этим углом

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

, в котором операторная матрица принимает следующий вид:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Мы не пойдем за угол

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

ищем «красивое» значение, установим его равным:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Посмотрим, как этот оператор повлияет на первый кубит

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

После того, как оператор воздействует на первый кубит пары, мы получаем следующую суперпозицию двух кубитов:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Шаг 2. Подействуем на второй кубит управляемым вентилем Адамара Управляемый вентиль Адамара изменяет второй кубит только тогда, когда первый кубит равен

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Шаг 3. Подействуем на второй кубит гейтом НЕТ Примените гейт ко второму кубиту НЕТ :

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Итак, мы имеем суперпозицию, в которой отсутствует комбинация 00. После того как мы подробно рассмотрели теоретическую часть, приступим к написанию соответствующей процедуры.

Библиотека кискит имеет в своем арсенале все клапаны, приведенные в теоретической части:

  • Однокубитный вентиль

    Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

    - Квантовая схема.

    рай (тета, целевой_кубит)

    • тэта - угол

      Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

    • целевой_кубит — кубит, на который действует ворота
  • Управляемый вентиль Адамара — QuantumCirquit. ч (control_qubit, target_qubit)
    • control_qubit — управляющий кубит
    • целевой_кубит — кубит, на который действует ворота
  • Однокубитный вентиль НЕТ - Квантовая схема.

    Икс (target_qubit)

    • целевой_кубит — кубит, на который действует ворота
Напишем процедуру, которая будет получать на вход пару кубитов и применять к ним последовательно все операторы, перечисленные в теоретической части:
  
  
  
  
  
   

import numpy as np theta = 2 * np.arccos(1 / np.sqrt(3)) def exclude_00(qc, pair, reverse=False): if not reverse: qc.ry(theta, pair[0]) qc.ch(pair[0], pair[1]) qc.x(pair[1]) else: qc.x(pair[1]) qc.ch(pair[0], pair[1]) qc.ry(-theta, pair[0])

Сразу отмечу, что должна быть возможность выполнить эту процедуру в обратном порядке, поэтому мы ввели дополнительный аргумент обеспечить регресс .

О необходимости этого я расскажу позже.

Исключить возможность получения опциона А мы будем с первой и четвёртой вершин маршрута.

Вторая и третья вершины должны иметь все возможные варианты в суперпозиции, поэтому действовать на них будем классически — вентилем Адамара.



4. Оракул

В алгоритме Гровера оракул должен инвертировать фазу «хорошей» комбинации входящих кубитов.

Если комбинация удовлетворяет условиям единственности и требованию связности вершин, то оракул должен изменить фазу такой комбинации.

В противном случае, если хотя бы одно из условий нарушено, оракул оставляет фазу неизменной.

Фазовая инверсия эквивалентна простой инверсии полученного кубита из

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

В

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

, который не является частью маршрута входного кубита.

Оракул должен быть построен таким образом, чтобы при «хорошей» комбинации результирующий кубит менял свое состояние.



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

за условие

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

.

По умолчанию комбинация объявляется «хорошей».

Однако если будет найдена хотя бы одна совпадающая вершина или один несвязный переход между ними, маршрут будет считаться «плохим» и полученный кубит не будет инвертирован.

На рисунке примерно показана схема алгоритма решения нашей задачи.



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Рассмотрим подробно содержание проверок на уникальность и связность вершин.



4.1. Контроль соответствия вершин

Задача этого блока — не дать оракулу инвертировать полученный кубит, если в комбинации вдруг появятся хотя бы две одинаковые вершины.

Чтобы проверить, есть ли в комбинации совпадающие вершины, нам нужно последовательно проверить все возможные пары вершин на равенство.

Для каждой пары вершин мы проверим, являются ли они обеими вершинами одновременно.

А , или Б , или С , или Д .



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Проверка совпадения вершин Представим, что на вход даны две вершины.

А , то все четыре входных кубита равны 0. После применения вентиля ко всем четырем кубитам НЕТ они становятся равными 1. Множественный вентиль Тоффоли инвертирует полученный кубит. Далее в схеме кубиты будут подвергаться преобразованию для проверки одновременного равенства вершин.

Б , С И Д .

Эти проверки завершатся неудачно и не изменят результирующий кубит; его значение останется инвертированным.

Если на вход подаются несовпадающие вершины, то результирующий кубит останется нетронутым на всех этапах схемы.

Процедура сопоставления вершин Напишем простую процедуру, на входе которой будут две пары кубитов, соответствующих двум вершинам маршрута, а также кубит, в который функция будет передавать результат проверки.

Если одинаковые вершины передаются парами, то процедура меняет полученный кубит на противоположный, сигнализируя о совпадении вершин.



def find_equality(qc, pair_1, pair_2, result_qubit): qc.x(pair_1 + pair_2) qc.mct(pair_1 + pair_2, result_qubit) qc.x([pair_1[1], pair_2[1]]) qc.mct(pair_1 + pair_2, result_qubit) qc.x(pair_1 + pair_2) qc.mct(pair_1 + pair_2, result_qubit) qc.x([pair_1[1], pair_2[1]]) qc.mct(pair_1 + pair_2, result_qubit)

Полная схема «детектора совпадений» будет выглядеть примерно так:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

В оракуле нам нужно будет применить эту процедуру ко всем парам вершин, а так как вершин у нас 4, то процедуру придется запустить 6 раз — это количество комбинаций 4 на 2:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Имея восемь вершин, нам уже нужно будет запустить эту функцию для 28 пар вершин.

Именно эта часть алгоритма является узким местом.



4.2. Проверка связности вершин

Задача этого блока оракула — определить для всех трёх пар соседних вершин, есть ли соединяющее их ребро.

Если хотя бы одна такая пара не имеет связи, то процедура не позволяет оракулу объявить комбинацию «хорошей» и изменить полученный кубит. Изменив полученный кубит на 0, процедура не позволит оракулу объявить такой маршрут «хорошим».

Общая логика должна быть следующей: результирующий кубит проверки на связность вершин должен измениться (1 → 0), если хотя бы одна пара соседних вершин не соединена ребром.



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Как мы решим эту проблему? Допустим, мы проверяем 3-ю и 4-ю вершины маршрута.

И допустим, третья вершина — это вершина А .

Но мы знаем это сверху А ты можешь добраться только до вершины С И Д .

Поэтому сначала нужно проверить, упала ли вершина на 3 шаге.

А , и если да, то проверяем, какая вершина следующая.

Нам необходимо выявить именно отрицательные случаи, когда следующая 4-я вершина не является вершиной.

С, ни один Д , и только в этом случае объявить комбинацию неудачной.

Мы можем проверить это наоборот, если 4-я вершина является вершиной А или Б (логически эквивалентно «ни С, ни один Д "), то считаем текущую комбинацию неудачной.

Такая "обратная" форма нам проще реализовать и уменьшит количество дополнительных кубитов.

Не забываем, что аналогичные проверки нам нужно провести и для всех остальных случаев, когда третья вершина Б , С или Д .

А также для всех возможных пар соседних вершин маршрута.

Приступим к реализации этой процедуры.

На вход мы дадим ему один кубит для результата и две пары кубитов двух вершин.

Первый назовем основным, второй соседним.

Будем последовательно проверять, какая вершина ( А , Б , С или Д ) — главная вершина.

Для этого нам понадобится клапан Тоффоли.

Далее для каждой из возможных ситуаций мы проверим соседнюю вершину, связана ли она с основной вершиной.

Логика процедуры следующая:

  • Проверка, является ли главная вершина вершиной А , если это правда, то проверьте:
    • Является ли соседняя вершина вершиной А или Б , если true, то инвертировать полученный кубит.
  • Проверка, является ли главная вершина вершиной Б , если это правда, то проверьте:
    • Является ли соседняя вершина вершиной А или Б , если true, то инвертировать полученный кубит.
  • Проверка, является ли главная вершина вершиной С , если это правда, то проверьте:
    • Если соседняя вершина какая-либо, то инвертируем полученный кубит (условие всегда выполняется).

  • Проверка, является ли главная вершина вершиной Д , если true, то логика ниже аналогична логике с вершиной С .

Рассмотрим подробнее алгоритм проверок, описанный выше.

Сначала проверяем, является ли главная вершина вершиной А .

Но как мы можем это проверить? Вертекс А в виде кубита имеет представление 00, мы можем применить гейт к обоим кубитам НЕТ , то пара станет равна 11. Далее мы отправляем эту пару в вентиль Тоффоли в качестве управляющего кубита, он инвертирует дополнительный кубит (0 → 1).

Если главная вершина не является вершиной А , то дополнительный кубит останется неизменным.

Если оно равно, то дополнительный кубит будет инвертирован.



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Далее нам нужно проверить соседнюю вершину на равенство с вершиной А или Б .

Для этого введем дополнительный кубит для хранения промежуточного результата проверки, применим кратный гейт Тоффоли к двум кубитам проверяемой вершины, а также в качестве управляющего кубита подадим в гейт с результатом дополнительный кубит проверки того, равна ли главная вершина вершине А .

В случае успеха вентиль Тоффоли инвертирует кубит промежуточного результата теста.

Теперь, когда мы закончили с теоретической частью, приступим к написанию процедуры.

Для начала составим общий список вершин, а заодно зафиксируем представления вершин в кубитах:

vertex_names = { 'A': '00', 'B': '01', 'C': '10', 'D': '11', }

Зафиксируем все соединения вершин (кроме точки О ).



connections = { 'A': ['C','D'], 'B': ['C','D'], 'C': ['A','B','D'], 'D': ['A','B','C'], }

Создадим каталог функции, который при подаче на вход вершины, соответствующей ключу в словаре, будет выдавать на выходе пару кубитов 11. Вместе с воротами Тоффоли этот каталог можно использовать как условный оператор.



vertex_to_11 = { 'A': lambda qc, pair: qc.x(pair), 'B': lambda qc, pair: qc.x(pair[0]), 'C': lambda qc, pair: qc.x(pair[1]), 'D': lambda qc, pair: None, }

Далее создадим процедуру, которая получает в качестве аргументов две пары кубитов — основную и соседнюю вершину — и проверяет наличие связи между ними.

Также передаем в процедуру полученный кубит, который заранее подготовлен в состоянии

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

.



def find_disconnection(qc, pair_1, pair_2, ancilla_qubit, result_qubit): for letter_1 in connections.keys(): vertex_to_find = [x for x in vertex_names.keys() if x not in connections[letter_1]] if len(vertex_to_find) > 0: vertex_to_11[letter_1](qc, pair_1) qc.toffoli(*pair_1, ancilla_qubit) for letter_2 in vertex_to_find: vertex_to_11[letter_2](qc, pair_2) qc.mct([*pair_2, ancilla_qubit], result_qubit) vertex_to_11[letter_2](qc, pair_2) qc.toffoli(*pair_1, ancilla_qubit) vertex_to_11[letter_1](qc, pair_1)

Эта процедура проверяет одну пару соседних вершин на наличие связи между ними.

Если такой связи нет, то он инвертирует полученный кубит (1 → 0) процедуры, что не позволит оракулу объявить эту комбинацию «хорошей».



5. Оператор диффузии

Оператор диффузии Гровера в матричном выражении представляет собой обычную единичную матрицу, все диагональные элементы которой равны -1, за исключением крайнего левого элемента, который равен 1. Оператор инвертирует фазу любого вектора, кроме вектора.



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

.



Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Пример действия оператора над вектором

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

: Пример действия оператора на любом другом векторе:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Нет необходимости «создавать» конфигурацию клапана для оператора диффузии; оно уже разработано.

Для набора н Оператор кубита будет выглядеть так:

Применение алгоритма Гровера для поиска гамильтоновых циклов в графе

Теги: #Квантовые технологии #Алгоритмы #графы #qiskit #Алгоритм Гровера #Гамильтонов цикл

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.