<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Microsoft on kenji.blog</title><link>http://kenji.blog/ru/tags/microsoft/</link><description>Recent content in Microsoft on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ru</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 00:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ru/tags/microsoft/index.xml" rel="self" type="application/rss+xml"/><item><title>Опыт использования языка программирования для квантовых компьютеров "Q#"</title><link>http://kenji.blog/ru/p/qsharp-quantum-programming-language-intro/</link><pubDate>Sat, 12 Sep 2026 00:00:00 +0900</pubDate><guid>http://kenji.blog/ru/p/qsharp-quantum-programming-language-intro/</guid><description>&lt;img src="http://kenji.blog/p/qsharp-quantum-programming-language-intro/img/eyecatch.jpg" alt="Featured image of post Опыт использования языка программирования для квантовых компьютеров "Q#"" />&lt;h2 id="1-введение-рассвет-квантовых-вычислений-и-новая-парадигма-программирования">1. Введение: Рассвет квантовых вычислений и новая парадигма программирования
&lt;/h2>&lt;p>В последние годы мы наблюдаем поразительные технологические инновации в области квантовых вычислений как в аппаратном, так и в программном обеспечении. В то время как классические компьютеры (ПК, смартфоны, суперкомпьютеры, которыми мы повседневно пользуемся) обрабатывают информацию с помощью комбинаций определенных битов — «0» или «1», квантовые компьютеры напрямую используют такие специфические физические явления квантовой механики, как «суперпозиция» (Superposition) и «квантовая запутанность» (Entanglement), в качестве основы для обработки информации. Это открывает перспективы для достижения таких скоростей вычислений для определенных классов задач, которые были бы недостижимы для классических компьютеров даже за время, равное возрасту Вселенной. Это называется «квантовым превосходством» (Quantum Supremacy) или «квантовым преимуществом» (Quantum Advantage). Например, ожидается радикальное сокращение вычислительных затрат в таких задачах, как факторизация больших чисел (алгоритм Шора), быстрый поиск в базах данных (алгоритм Гровера), симуляция квантовой химии (алгоритм VQE), задачи комбинаторной оптимизации и даже некоторые процессы машинного обучения (Quantum Machine Learning).&lt;/p>
&lt;p>Однако для реализации этого невероятного потенциала квантовых компьютеров в виде реальных приложений недостаточно лишь прогресса в аппаратном обеспечении (сверхпроводящих кубитах, ионных ловушках и т.д.). Крайне необходим «язык квантового программирования», позволяющий точно проектировать квантовые схемы и писать квантовые алгоритмы эффективно и без ошибок, а также надежная среда разработки, выполнения и отладки, поддерживающая его. Классические языки программирования (C++, Python, Java и др.) отлично справляются с абстракцией работы классической процессорной архитектуры, но они не предназначены для естественного описания манипуляций с квантовыми состояниями, которые носят недетерминированный характер и имеют комплексные амплитуды.&lt;/p>
&lt;p>В этой статье из множества сред квантового программирования мы сосредоточимся на Quantum Development Kit (QDK) — наборе инструментов, активно продвигаемом компанией Microsoft и разрабатываемом с открытым исходным кодом, а также на его ядре — специализированном языке программирования Q# (Кью-шарп).&lt;/p>
&lt;p>Q# был спроектирован с нуля как предметно-ориентированный язык (Domain Specific Language: DSL), специализирующийся на описании квантовых алгоритмов, и вобрал в себя лучшие черты C#, F# и Python. Он обладает мощными возможностями для бесшовной интеграции классического управления потоком (такими как инструкции if и циклы for) с квантовыми операциями (применение вентилей и измерения). В этой статье мы подробно, начиная с самых основ, разберем базовые математические модели квантовых вычислений, языковые особенности Q#, сравним его философию дизайна с такими инструментами, как Qiskit на Python, покажем создание и измерение «состояния Белла» (квантовой запутанности) с помощью реального кода и, наконец, методы интеграции с классическими языками (Python и C#). К концу этой статьи вы поймете основы квантового программирования и будете готовы начать писать свой собственный Q#-код в своей среде разработки.&lt;/p>
&lt;h2 id="2-математические-основы-квантовых-вычислений-состояния-суперпозиция-и-запутанность">2. Математические основы квантовых вычислений: состояния, суперпозиция и запутанность
&lt;/h2>&lt;p>Чтобы глубоко понять синтаксис и функции Q# и эффективно писать квантовые программы, сначала необходимо структурировать базовые математические знания (особенно линейную алгебру), лежащие в основе квантовых состояний и операций квантовых вентилей. Здесь мы рассмотрим основные математические модели, необходимые для квантового программирования.&lt;/p>
&lt;h3 id="21-кубит-qubit-и-состояние-суперпозиции">2.1 Кубит (Qubit) и состояние суперпозиции
&lt;/h3>&lt;p>В то время как классический бит (Classical Bit) может находиться только в одном из двух состояний — $0$ или $1$, квантовый бит (кубит, Qubit) выражается как линейная комбинация (Linear Combination) состояний $|0\rangle$ и $|1\rangle$, то есть как «суперпозиция». Это состояние описывается с использованием бра-кет нотации (нотации Дирака) и комплексных коэффициентов $\alpha$ и $\beta$ следующим образом:&lt;/p>
$$ |\psi\rangle = \alpha|0\rangle + \beta|1\rangle $$
&lt;p>Здесь $\alpha$ и $\beta$ — это комплексные числа (Complex Numbers), называемые амплитудами вероятности (Probability Amplitude). Вероятность того, что при измерении этого кубита мы обнаружим состояние $|0\rangle$, равна $|\alpha|^2$, а вероятность состояния $|1\rangle$ равна $|\beta|^2$. Из-за физических ограничений сумма вероятностей наблюдения всех возможных состояний всегда должна быть равна $1$, поэтому должно выполняться следующее условие нормировки (Normalization Condition):&lt;/p>
$$ |\alpha|^2 + |\beta|^2 = 1 $$
&lt;p>Состояние кубита часто визуализируется как точка на поверхности единичной сферы в трехмерном пространстве, называемой «сферой Блоха» (Bloch Sphere). Северный полюс соответствует $|0\rangle$, южный полюс — $|1\rangle$, а точки на экваторе представляют собой состояния суперпозиции, где $|0\rangle$ и $|1\rangle$ накладываются друг на друга с равной вероятностью (например, состояние с нулевой фазой $|+\rangle = \frac{1}{\sqrt{2}}(|0\rangle + |1\rangle)$ или состояние с фазой $\pi/2$: $|i\rangle = \frac{1}{\sqrt{2}}(|0\rangle + i|1\rangle)$). Операции квантовых вентилей можно геометрически понимать как операции вращения на этой сфере Блоха.&lt;/p>
&lt;h3 id="22-несколько-кубитов-тензорное-произведение-и-квантовая-запутанность">2.2 Несколько кубитов, тензорное произведение и квантовая запутанность
&lt;/h3>&lt;p>Истинная мощь квантовых вычислений проявляется при комбинировании нескольких кубитов. Состояние системы, состоящей из нескольких кубитов, описывается через «тензорное произведение» (Tensor Product) пространств состояний отдельных кубитов. Например, состояние всей системы из двух кубитов выглядит так:&lt;/p>
$$ |\psi\rangle = \alpha_{00}|00\rangle + \alpha_{01}|01\rangle + \alpha_{10}|10\rangle + \alpha_{11}|11\rangle $$
&lt;p>Здесь также выполняется условие нормировки $\sum_{i,j} |\alpha_{ij}|^2 = 1$. Важно отметить, что для полного описания системы из n кубитов требуется $2^n$ комплексных амплитуд. Например, для описания состояния системы всего из 50 кубитов потребуется около $2^{50} \approx 10^{15}$ комплексных чисел, что намного превышает объем памяти самых быстрых в мире современных суперкомпьютеров. Это одна из причин, по которой квантовые компьютеры обладают экспоненциальным преимуществом над классическими.&lt;/p>
&lt;p>«Квантовая запутанность» (Entanglement) означает такое состояние нескольких кубитов, которое не может быть просто разложено (факторизовано) как тензорное произведение состояний отдельных кубитов. Одним из самых известных и важных запутанных состояний является следующее «состояние Белла» (Bell State):&lt;/p>
$$ |\Phi^+\rangle = \frac{1}{\sqrt{2}}(|00\rangle + |11\rangle) $$
&lt;p>В этом состоянии, как только вы измеряете один кубит и получаете $0$ (или $1$), состояние второго кубита мгновенно, независимо от расстояния между ними, фиксируется как $0$ (или $1$). Эта нелокальная корреляция, которую Эйнштейн называл «жутким дальнодействием», является фундаментальным ресурсом для квантовой телепортации, сверхплотного кодирования, квантовой криптографии, а также эффективного выполнения многих квантовых алгоритмов. В последующих разделах мы фактически создадим это состояние Белла с помощью Q#.&lt;/p>
&lt;h3 id="23-операции-квантовых-вентилей-и-унитарные-матрицы">2.3 Операции квантовых вентилей и унитарные матрицы
&lt;/h3>&lt;p>Операции, изменяющие квантовые состояния (эквиваленты вентилей AND, OR, NOT в классических логических схемах), называются квантовыми вентилями. Математически квантовые вентили представляются комплексными матрицами и действуют на вектор квантового состояния путем матричного умножения. Согласно аксиомам квантовой механики, эти матрицы всегда должны быть унитарными (унитарная матрица — матрица, удовлетворяющая условию $U^\dagger U = I$, где $U^\dagger$ — сопряженно-транспонированная матрица, а $I$ — единичная матрица). Благодаря этому все квантовые операции, кроме измерения, являются обратимыми (Reversible).&lt;/p>
&lt;p>Типичные однокубитные вентили:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Вентиль Паули-X (вентиль NOT)&lt;/strong>: Переворачивает $|0\rangle$ в $|1\rangle$, а $|1\rangle$ в $|0\rangle$.
$$ X = \begin{pmatrix} 0 &amp; 1 \\ 1 &amp; 0 \end{pmatrix} $$&lt;/li>
&lt;li>&lt;strong>Вентиль Паули-Z (вентиль сдвига фазы)&lt;/strong>: Оставляет $|0\rangle$ как есть, но меняет знак у $|1\rangle$ (добавляет фазу $\pi$).
$$ Z = \begin{pmatrix} 1 &amp; 0 \\ 0 &amp; -1 \end{pmatrix} $$&lt;/li>
&lt;li>&lt;strong>Вентиль Адамара (H-вентиль)&lt;/strong>: Преобразует детерминированное состояние в состояние суперпозиции.
$$ H = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 &amp; 1 \\ 1 &amp; -1 \end{pmatrix} $$&lt;/li>
&lt;/ul>
&lt;p>Типичные двухкубитные вентили:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Вентиль CNOT (управляемый NOT)&lt;/strong>: Применяет вентиль X (операцию NOT) к целевому кубиту (Target Qubit) только тогда, когда управляющий кубит (Control Qubit) находится в состоянии $|1\rangle$.
$$ CNOT = \begin{pmatrix} 1 &amp; 0 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 1 \\ 0 &amp; 0 &amp; 1 &amp; 0 \end{pmatrix} $$&lt;/li>
&lt;/ul>
&lt;p>Квантовый алгоритм можно рассматривать как процесс комбинирования этих базовых унитарных матриц для реализации желаемых вычислений.&lt;/p>
&lt;h2 id="3-что-такое-microsoft-quantum-development-kit-qdk">3. Что такое Microsoft Quantum Development Kit (QDK)?
&lt;/h2>&lt;p>Quantum Development Kit (QDK), предоставляемый Microsoft, представляет собой комплексный набор инструментов, помогающий в разработке программного обеспечения для квантовых вычислений. Он поддерживает весь жизненный цикл разработки: от проектирования алгоритмов, отладки и оптимизации до запуска на симуляторах и реальном квантовом оборудовании.&lt;/p>
&lt;p>В QDK включены следующие основные компоненты:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Компилятор Q# и среда выполнения&lt;/strong>: Тщательно анализирует и оптимизирует код, написанный на языке Q#, преобразуя его в формат (например, QIR), который может быть выполнен на симуляторах или реальном квантовом оборудовании (через Azure Quantum). Компилятор Q# выполняет статический анализ, специфичный для квантовых вычислений, например, проверку чистоты функций и управление жизненным циклом кубитов.&lt;/li>
&lt;li>&lt;strong>Квантовый симулятор&lt;/strong>: Включает симулятор полного состояния (Full State Simulator), который моделирует эволюцию квантового состояния на локальном компьютере разработчика. Это позволяет разработчикам быстро тестировать и отлаживать небольшие алгоритмы масштабом в несколько десятков кубитов на своих машинах. Также предоставляется средство оценки ресурсов (Resource Estimator) для оценки необходимых ресурсов при работе с крупными схемами (от тысяч до миллионов кубитов).&lt;/li>
&lt;li>&lt;strong>Обширные библиотеки&lt;/strong>: Стандартная библиотека Q# (Standard Library) предлагает разнообразные высокоуровневые строительные блоки: от базовых квантовых вентилей (H, X, Y, Z, CNOT и др.) до сложных арифметических операций (например, квантовые сумматоры), алгоритмов усиления амплитуды (Amplitude Amplification) и оценки квантовой фазы (Quantum Phase Estimation). Это позволяет разработчикам не &amp;ldquo;изобретать велосипед&amp;rdquo;.&lt;/li>
&lt;li>&lt;strong>Интеграция с интегрированными средами разработки (IDE)&lt;/strong>: Доступны расширения для Visual Studio и Visual Studio Code. Они предлагают такие функции, как подсветка синтаксиса, автодополнение кода (IntelliSense), мощные возможности отладки и интеграция с фреймворками для тестирования — всё необходимое для современной разработки программного обеспечения.&lt;/li>
&lt;/ol>
&lt;p>Ниже представлена диаграмма Mermaid, показывающая рабочий процесс от написания программы на Q# до ее выполнения на аппаратном уровне.&lt;/p>
&lt;div class="mermaid">graph TD
A["Исходный код Q# (.qs)"] --> B["Компилятор Q#"]
B --> C["Квантовое промежуточное представление (QIR)"]
C --> D["Локальный квантовый симулятор"]
C --> E["Сервис Azure Quantum"]
E --> F["Оборудование IonQ"]
E --> G["Оборудование Quantinuum"]
E --> H["Оборудование Rigetti"]
D --> I["Результат / Выходные данные"]
F --> I
G --> I
H --> I
style A fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px;
style B fill:#fff3e0,stroke:#ff9800,stroke-width:2px;
style C fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px;&lt;/div>
&lt;p>Выдающейся особенностью этой архитектуры является то, что использование промежуточного представления на базе LLVM, известного как QIR (Quantum Intermediate Representation), позволяет полностью абстрагироваться от различий в базовой аппаратной архитектуре (будь то сверхпроводящие кубиты, ионные ловушки, топологические кубиты или оптические квантовые системы). Разработчики могут сосредоточиться на чисто логическом проектировании алгоритмов, не беспокоясь о физических деталях оборудования (таких как топология и наборы нативных вентилей, специфичные для каждого устройства). Процессы компиляции, следующие за уровнем QIR, автоматически выполняют транспиляцию вентилей, оптимизируя их для целевого оборудования.&lt;/p>
&lt;h2 id="4-q-против-pythonqiskit-зачем-нужен-новый-язык">4. Q# против Python/Qiskit: Зачем нужен новый язык?
&lt;/h2>&lt;p>Когда люди начинают изучать квантовое программирование, многие первым делом знакомятся с платформой Qiskit на базе Python, разработанной IBM, благодаря ее доступности и широкой популярности Python. Qiskit — тоже очень мощный и широко используемый инструмент, но у него с Q# от Microsoft кардинально разная философия проектирования (парадигма).&lt;/p>
&lt;h3 id="подход-qiskit-построение-объектов-схем-с-помощью-python">Подход Qiskit (Построение объектов схем с помощью Python)
&lt;/h3>&lt;p>По своей сути Qiskit является «библиотекой API на Python для построения квантовых схем». Когда разработчик выполняет Python-скрипт, в памяти постепенно собирается последовательность квантовых вентилей (объект схемы). И только после того, как все вентили добавлены, этот огромный объект схемы отправляется (Submit) на бэкенд (локальный симулятор или реальную машину в облаке) для выполнения.
Этот подход метапрограммирования имеет огромное преимущество: его очень легко интегрировать с существующей экосистемой Python (библиотеками машинного обучения, такими как NumPy, SciPy, PyTorch, и инструментами визуализации). Однако, когда возникает необходимость реализовать сложный поток управления, где смешаны классические и квантовые вычисления — например, «измерить определенный кубит и, только если результат равен 1, применить конкретную сложную унитарную операцию к группе других кубитов, а затем прокрутить цикл while» (так называемые динамические схемы (Dynamic Circuits)) — вы не можете использовать стандартные инструкции if или for в Python (потому что они оцениваются «во время построения схемы»). Вместо этого приходится использовать специальные управляющие инструкции Qiskit, из-за чего код часто становится очень сложным и неочевидным.&lt;/p>
&lt;h3 id="подход-q-доменно-ориентированный-язык-с-приоритетом-квантовых-вычислений">Подход Q# (Доменно-ориентированный язык с приоритетом квантовых вычислений)
&lt;/h3>&lt;p>С другой стороны, Q# — это отдельный компилируемый язык, спроектированный с нуля, в котором квантовые вычисления являются «объектами первого класса» (First-class citizen). В Q# выделение кубитов, операции над вентилями и измерения могут быть записаны естественно и органично в рамках одной базы кода, точно так же, как вы работаете с классическими переменными, инструкциями if и циклами.
Компилятор Q# статически анализирует весь код и определяет, какие его части должны выполняться на классическом вычислительном устройстве (хост-процессоре или управляющей электронике), а какие — на квантовом сопроцессоре (QPU), выполняя высокоуровневую оптимизацию. Это обеспечивает высокую модульность, читаемость, удобство сопровождения и безопасность типов (Type Safety) при реализации сложных масштабных квантовых алгоритмов. Q# — это язык для «написания алгоритмов», а не просто для «написания схем».&lt;/p>
&lt;h2 id="5-глубокое-погружение-в-базовый-синтаксис-и-характерные-концепции-q">5. Глубокое погружение в базовый синтаксис и характерные концепции Q#
&lt;/h2>&lt;p>Синтаксис Q# представляет собой элегантную конструкцию, объединяющую блочную структуру с фигурными скобками &lt;code>{}&lt;/code> из C#, элементы функционального программирования из F# и мощный вывод типов. Здесь мы подробно разберем ключевые слова и концепции, важные для глубокого понимания Q#.&lt;/p>
&lt;h3 id="51-operation-と-function-の厳格な区別-строгое-различие-между-operation-и-function">5.1 &lt;code>operation&lt;/code> と &lt;code>function&lt;/code> の厳格な区別 (Строгое различие между &lt;code>operation&lt;/code> и &lt;code>function&lt;/code>)
&lt;/h3>&lt;p>В Q# четко различают два типа блоков обработки (подпрограмм): &lt;code>operation&lt;/code> и &lt;code>function&lt;/code>. Это проистекает из концепции «чистоты» (Purity) в функциональном программировании.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;code>function&lt;/code>&lt;/strong>: Чистая функция, выполняющая только детерминированные (Deterministic) классические вычисления. Если передать одни и те же входные параметры, она всегда будет возвращать один и тот же результат, независимо от того, сколько раз выполняется. Внутри &lt;code>function&lt;/code> квантовые операции (операции с побочными эффектами), такие как выделение кубитов, применение вентилей и измерения, приведут к ошибке компиляции. Функции используются для математических расчетов, преобразования данных и т.д.&lt;/li>
&lt;li>&lt;strong>&lt;code>operation&lt;/code>&lt;/strong>: Недетерминированная (Non-deterministic) процедура, которая включает в себя квантовые вычисления. Она может содержать манипуляции с кубитами и измерения. Даже при одинаковых входных данных результат может различаться из-за вероятностной природы квантовой механики (например, коллапса волновой функции при измерении). Все основные части квантовых алгоритмов определяются как &lt;code>operation&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h3 id="52-тип-qubit-и-управление-жизненным-циклом-с-помощью-ключевого-слова-use">5.2 Тип &lt;code>Qubit&lt;/code> и управление жизненным циклом с помощью ключевого слова &lt;code>use&lt;/code>
&lt;/h3>&lt;p>В Q# кубиты рассматриваются как «непрозрачные» (Opaque) объекты типа &lt;code>Qubit&lt;/code>. Разработчикам намеренно запрещено напрямую читать или перезаписывать амплитуды вероятности их внутреннего состояния (например, значения $\alpha$ или $\beta$) в программе (это согласуется с «проблемой измерения» в физических квантовых системах). Единственный способ взаимодействия с кубитами — вызов предоставленных операций квантовых вентилей или функций измерения.&lt;/p>
&lt;p>Для выделения (аллокации) новых кубитов в программе используется ключевое слово &lt;code>use&lt;/code> (в старых версиях Q# оно называлось &lt;code>using&lt;/code>). Блок &lt;code>use&lt;/code> четко определяет область видимости и жизненный цикл кубитов.
Важное правило: при выходе из блока &lt;code>use&lt;/code> все кубиты, выделенные внутри него, должны обязательно быть полностью возвращены в состояние $|0\rangle$ (в противном случае возникнет ошибка времени выполнения). Это мощный механизм безопасности Q#, гарантирующий повторное использование кубитов и предотвращающий утечки памяти.&lt;/p>
&lt;h3 id="53-измерение-m-и-удобная-операция-mresetz">5.3 Измерение &lt;code>M&lt;/code> и удобная операция &lt;code>MResetZ&lt;/code>
&lt;/h3>&lt;p>Операция измерения (Measurement) для преобразования квантового состояния в классическую информацию (0 или 1) выполняется базовой операцией &lt;code>M&lt;/code>. Результат измерения в Z-базисе (стандартном базисе) возвращается как тип перечисления &lt;code>Result&lt;/code> (со значениями &lt;code>Zero&lt;/code> или &lt;code>One&lt;/code>).
Однако, как упоминалось выше, при освобождении кубитов требуется, чтобы они находились в состоянии $|0\rangle$. Если вы просто выполните измерение &lt;code>M&lt;/code>, и результат окажется &lt;code>One&lt;/code>, кубит уже коллапсирует в состояние $|1\rangle$. По этой причине в практическом коде очень часто используется удобная стандартная операция &lt;code>MResetZ&lt;/code>, которая надежно сбрасывает состояние кубита в $|0\rangle$ сразу после измерения.&lt;/p>
&lt;h3 id="54-неизменяемость-переменных-immutability-и-ключевое-слово-mutable">5.4 Неизменяемость переменных (Immutability) и ключевое слово &lt;code>mutable&lt;/code>
&lt;/h3>&lt;p>В Q#, находящемся под сильным влиянием функционального программирования, все переменные по умолчанию являются неизменяемыми (Immutable). Переменная, однажды связанная с помощью ключевого слова &lt;code>let&lt;/code>, впоследствии не может быть изменена. Это помогает уменьшить непредвиденные побочные эффекты при параллельной обработке и в квантовых алгоритмах.
Если вам необходимо объявить переменную, значение которой нужно обновлять (например, счетчик цикла или накопительное вычисление), следует явно использовать ключевое слово &lt;code>mutable&lt;/code>, а для обновления значения применять ключевое слово &lt;code>set&lt;/code>.&lt;/p>
&lt;h2 id="6-практика-создание-и-измерение-состояния-белла-квантовой-запутанности-на-q">6. Практика: Создание и измерение состояния Белла (квантовой запутанности) на Q#
&lt;/h2>&lt;p>Теперь, используя полученные знания, давайте напишем программу на Q#, которая создаст «состояние Белла» (Bell State), о котором мы говорили в математическом разделе, и измерит его. Это важнейший шаг, который можно назвать «Hello World» квантового программирования.&lt;/p>
&lt;h3 id="проектирование-и-объяснение-квантовой-схемы">Проектирование и объяснение квантовой схемы
&lt;/h3>&lt;p>Стандартная процедура создания состояния Белла $\frac{1}{\sqrt{2}}(|00\rangle + |11\rangle)$ с помощью квантовой схемы выглядит следующим образом:&lt;/p>
&lt;ol>
&lt;li>Подготовить два кубита $q_0$ и $q_1$ в начальном состоянии $|00\rangle$.&lt;/li>
&lt;li>Применить вентиль Адамара (вентиль $H$) к $q_0$. Это переведет $q_0$ в состояние равновероятной суперпозиции $|0\rangle$ и $|1\rangle$: $\frac{1}{\sqrt{2}}(|0\rangle + |1\rangle)$. Состояние всей системы в этот момент будет $\frac{1}{\sqrt{2}}(|0\rangle + |1\rangle) \otimes |0\rangle = \frac{1}{\sqrt{2}}(|00\rangle + |10\rangle)$.&lt;/li>
&lt;li>Применить вентиль CNOT (управляемый NOT), используя $q_0$ в качестве управляющего кубита (Control) и $q_1$ в качестве целевого кубита (Target). Это инвертирует $q_1$ только в том случае, если $q_0$ равно $|1\rangle$. В результате состояние $|00\rangle$ остается $|00\rangle$, а $|10\rangle$ меняется на $|11\rangle$. Итоговое состояние всей системы станет $\frac{1}{\sqrt{2}}(|00\rangle + |11\rangle)$. Это завершает создание запутанного состояния с идеальной корреляцией.&lt;/li>
&lt;/ol>
&lt;h3 id="код-реализации-на-q">Код реализации на Q#
&lt;/h3>&lt;p>Ниже приведен пример практической реализации на Q#, которая генерирует состояние Белла и многократно выполняет эксперименты с измерениями для получения статистики (распределения вероятностей).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">namespace Quantum.BellState {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Импорт необходимых пространств имен
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> open Microsoft.Quantum.Intrinsic;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> open Microsoft.Quantum.Canon;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> open Microsoft.Quantum.Measurement;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> open Microsoft.Quantum.Diagnostics;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// # Summary
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// Генерирует одиночное состояние Белла и измеряет два кубита в базисе Z.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ///
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// # Output
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// (Result, Result): результаты измерения qubit1 и qubit2. В состоянии Белла они всегда совпадают.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> operation GenerateAndMeasureBellState() : (Result, Result) {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Выделение двух кубитов (начальное состояние автоматически устанавливается в |00&amp;gt;)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> use (q1, q2) = (Qubit(), Qubit());
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Применение вентиля Адамара к q1 для создания состояния суперпозиции
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> H(q1);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Применение вентиля CNOT: q1 выступает в роли управляющего кубита, а q2 - целевого
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Это создает квантовую запутанность между q1 и q2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> CNOT(q1, q2);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Для отладки во время разработки можно вывести вектор состояния в симуляторе
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // DumpMachine(); // Раскомментируйте при необходимости
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Выполнение измерения и одновременный сброс состояния в |0&amp;gt; для безопасного освобождения кубитов
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> let res1 = MResetZ(q1);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> let res2 = MResetZ(q2);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Возврат пары результатов измерения
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> return (res1, res2);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// # Summary
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// Главная процедура, которая многократно выполняет эксперимент по генерации и измерению состояния Белла и собирает статистику результатов.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ///
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// # Input
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// ## count
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// Количество повторений эксперимента (например, 1000 раз)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ///
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// # Output
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> /// (Int, Int, Int, Int): количество наблюдений для (00, 01, 10, 11) соответственно
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> @EntryPoint()
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> operation RunBellStateExperiment(count: Int) : (Int, Int, Int, Int) {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Инициализация изменяемых переменных (mutable) для подсчета количества наблюдений
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> mutable num00 = 0;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> mutable num01 = 0;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> mutable num10 = 0;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> mutable num11 = 0;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Цикл проведения эксперимента заданное количество раз
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> for _ in 1..count {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Генерация состояния Белла и получение результатов измерения
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> let (r1, r2) = GenerateAndMeasureBellState();
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Подсчет шаблонов результатов
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> if r1 == Zero and r2 == Zero {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> set num00 += 1;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> } elif r1 == Zero and r2 == One {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> set num01 += 1;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> } elif r1 == One and r2 == Zero {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> set num10 += 1;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> } else { // случай r1 == One and r2 == One
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> set num11 += 1;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Вывод собранной статистики в консоль в виде сообщений
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Message($&amp;#34;--- Experiment Results ---&amp;#34;);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Message($&amp;#34;Total runs: {count}&amp;#34;);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Message($&amp;#34;00 observed: {num00}&amp;#34;);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Message($&amp;#34;01 observed: {num01}&amp;#34;);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Message($&amp;#34;10 observed: {num10}&amp;#34;);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Message($&amp;#34;11 observed: {num11}&amp;#34;);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> return (num00, num01, num10, num11);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="объяснение-кода-и-проверка-работы">Объяснение кода и проверка работы
&lt;/h3>&lt;ul>
&lt;li>&lt;code>namespace&lt;/code>: Как и в Java или C#, это объявление пространства имен, используемое для логической организации программы и предотвращения конфликтов имен.&lt;/li>
&lt;li>&lt;code>open&lt;/code>: Импортирует необходимые библиотеки (модули). В &lt;code>Microsoft.Quantum.Intrinsic&lt;/code> содержатся базовые квантовые вентили (H, X, Y, Z, CNOT и др.), а в &lt;code>Microsoft.Quantum.Measurement&lt;/code> — удобные функции, связанные с измерениями, такие как &lt;code>MResetZ&lt;/code>.&lt;/li>
&lt;li>&lt;code>use (q1, q2) = (Qubit(), Qubit());&lt;/code>: Динамически выделяет два кубита.&lt;/li>
&lt;li>&lt;code>H(q1); CNOT(q1, q2);&lt;/code>: Эти две строки являются ядром для создания квантовой запутанности. Они пишутся очень просто и интуитивно понятно.&lt;/li>
&lt;li>&lt;code>let res1 = MResetZ(q1);&lt;/code>: Как уже упоминалось, &lt;code>MResetZ&lt;/code> связывает результат измерения с переменной и одновременно принудительно сбрасывает состояние кубита в $|0\rangle$. Это позволяет безопасно освободить кубит в конце блока &lt;code>use&lt;/code>.&lt;/li>
&lt;li>&lt;code>@EntryPoint()&lt;/code>: Этот атрибут сообщает компилятору, что данная операция является отправной точкой выполнения программы (подобно функции main в языке C).&lt;/li>
&lt;/ul>
&lt;p>Теоретически сгенерированное состояние является состоянием Белла $\frac{1}{\sqrt{2}}(|00\rangle + |11\rangle)$. Поэтому, если запустить эту программу достаточное количество раз (например, 10 000 раз), &lt;code>00&lt;/code> и &lt;code>11&lt;/code> должны наблюдаться примерно в 50% случаев (около 5000 раз каждое), а &lt;code>01&lt;/code> и &lt;code>10&lt;/code> — 0 раз (они не должны наблюдаться вообще при отсутствии теоретической ошибки). Это и доказывает, что два кубита имеют сильную корреляцию (являются запутанными).&lt;/p>
&lt;h2 id="7-бесшовная-интеграция-с-хост-языками-python--c">7. Бесшовная интеграция с хост-языками (Python / C#)
&lt;/h2>&lt;p>Q# может работать автономно, если указать атрибут &lt;code>@EntryPoint()&lt;/code>, как показано в предыдущем примере (автономное приложение на Q#). Однако в реальной корпоративной разработке и исследовательских сценариях Q# часто тесно интегрируют с классическими процессами, такими как графические интерфейсы пользователя, получение данных из больших баз данных или циклы оптимизации машинного обучения (например, обновление параметров VQE). По этой причине Q# обеспечивает превосходную совместимость (Interoperability), что позволяет легко вызывать и выполнять Q#-код напрямую из хост-языков, таких как Python или C# (.NET).&lt;/p>
&lt;h3 id="71-пример-вызова-из-python-для-дата-сайентистов">7.1 Пример вызова из Python: для дата-сайентистов
&lt;/h3>&lt;p>Для вызова Q# из Python, который занимает доминирующее положение в мире науки о данных, машинного обучения и физических исследований, используется пакет &lt;code>qsharp&lt;/code> для Python. Он также отлично интегрируется с Jupyter Notebook, что делает его идеальным выбором для интерактивной разработки и визуализации данных.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. Импорт необходимого модуля для интеграции с Q#&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">qsharp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. Прямой импорт операции Q#, как если бы это была функция Python&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># (компилятор автоматически выполняет связывание и компиляцию в фоновом режиме)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">Quantum.BellState&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RunBellStateExperiment&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Вызов и выполнение из скрипта Python (используется симулятор)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">count&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Starting quantum simulation for &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> iterations...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Вызов метода simulate() выполняет код на локальном симуляторе&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RunBellStateExperiment&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">simulate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Получение кортежа результатов, форматирование и вывод на стороне Python&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">--- Simulation Results ---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;|00&amp;gt; : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> (Expected ~500)&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;|01&amp;gt; : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> (Expected 0)&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;|10&amp;gt; : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> (Expected 0)&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;|11&amp;gt; : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> (Expected ~500)&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Поскольку компилятор и интерпретатор Q# в фоновом режиме прозрачно и динамически генерируют привязки (bindings) через C API, код на Python может работать с квантовым алгоритмом просто как с функцией «черного ящика». Это позволяет с невероятной легкостью создавать гибридные алгоритмы, объединяющие классические и квантовые вычисления.&lt;/p>
&lt;h3 id="72-пример-вызова-из-c-для-корпоративной-разработки">7.2 Пример вызова из C#: для корпоративной разработки
&lt;/h3>&lt;p>Q#-код также можно без проблем интегрировать в C#, который часто используется при разработке масштабируемых бэкенд-систем и корпоративных приложений. Поместив проект Q# (.csproj) и проект C# в одно решение и установив между ними зависимость, классы-обертки для C# будут автоматически сгенерированы во время сборки.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System.Threading.Tasks&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">Microsoft.Quantum.Simulation.Simulators&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Пространство имен квантового симулятора&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">Quantum.BellState&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Пространство имен, определенное в Q#&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">namespace&lt;/span> &lt;span class="nn">QuantumRunner&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">class&lt;/span> &lt;span class="nc">Program&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">static&lt;/span> &lt;span class="kd">async&lt;/span> &lt;span class="n">Task&lt;/span> &lt;span class="n">Main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">string&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="n">args&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Создание экземпляра квантового симулятора полного состояния&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Поскольку он реализует IDisposable, используется оператор using для правильного управления ресурсами&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">using&lt;/span> &lt;span class="nn">var&lt;/span> &lt;span class="n">sim&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">QuantumSimulator&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="n">count&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="m">1000&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;Running {count} iterations of Bell State generation...&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Асинхронное выполнение операции Q#. Метод Run генерируется автоматически.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Передаем sim в качестве целевого объекта для выполнения и count в качестве аргумента.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">var&lt;/span> &lt;span class="n">result&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">RunBellStateExperiment&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sim&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">count&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Результат возвращается в виде C# ValueTuple&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;|00&amp;gt;: {result.Item1}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;|01&amp;gt;: {result.Item2}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;|10&amp;gt;: {result.Item3}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;|11&amp;gt;: {result.Item4}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Здесь в целях разработки используется класс локального симулятора &lt;code>QuantumSimulator&lt;/code>. Но при переходе в производственную среду достаточно заменить часть, создающую экземпляр симулятора, на целевого поставщика облачных услуг, указывающего на рабочую область Azure Quantum (например, объект реальной машины IonQ или Quantinuum). Вы сможете запускать свои алгоритмы на реальном квантовом оборудовании в облаке без малейших изменений в коде Q# или бизнес-логике. В этом и заключается истинная сила QDK.&lt;/p>
&lt;h2 id="8-продвинутые-темы-функции-воплощающие-философию-дизайна-q">8. Продвинутые темы: Функции, воплощающие философию дизайна Q#
&lt;/h2>&lt;p>Мы рассмотрели базовое использование Q#. Теперь давайте подробнее разберем некоторые из наиболее продвинутых функций Q# и его философию дизайна. Именно эти возможности делают Q# не просто «альтернативой Python», а по-настоящему специализированным квантовым языком программирования.&lt;/p>
&lt;h3 id="81-автоматическая-генерация-обратных-операций-adjoint-и-управляемых-операций-controlled">8.1 Автоматическая генерация обратных операций (Adjoint) и управляемых операций (Controlled)
&lt;/h3>&lt;p>Одной из главных особенностей квантовых вычислений является «обратимость» (Reversibility), обусловленная унитарностью (Unitarity). Все базовые операции, кроме измерений, являются унитарными матрицами, а значит, всегда имеют обратную матрицу (обратную операцию) и могут быть отменены. Q# поддерживает это как первоклассную функцию на уровне языка, предоставляя мощные модификаторы-функторы &lt;code>Adjoint&lt;/code> (сопряженная/обратная операция) и &lt;code>Controlled&lt;/code> (управляемая операция).&lt;/p>
&lt;p>Вам не нужно вычислять матрицы вручную или переворачивать порядок вентилей, чтобы реализовать обратную операцию для некоторой квантовой операции &lt;code>Op&lt;/code>. Достаточно добавить определенные ключевые слова в сигнатуру функции, и компилятор Q# автоматически сгенерирует операцию &lt;code>Adjoint Op&lt;/code>. Аналогичным образом может быть автоматически сгенерирована условная операция &lt;code>Controlled Op&lt;/code>, которая выполняет &lt;code>Op&lt;/code> только в том случае, если все кубиты из группы управляющих кубитов находятся в состоянии $|1\rangle$.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">// Добавление is Adj + Ctl указывает компилятору автоматически генерировать обратную и управляемую операции
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">operation MyComplexSubroutine(qubits: Qubit[]) : Unit is Adj + Ctl {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Здесь описывается очень сложная последовательность квантовых вентилей
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Пример: комбинации H, T, CNOT, произвольные сдвиги фазы и т.д.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // ...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">// Пример на стороне вызывающего кода
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">operation UseMyOp(controlQubit: Qubit, targetQubits: Qubit[]) : Unit {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Обычный вызов
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> MyComplexSubroutine(targetQubits);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Выполнение обратной операции: полностью возвращает исходное состояние (очень удобно для обратных вычислений)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Adjoint MyComplexSubroutine(targetQubits);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Выполнение управляемой операции: сложная подпрограмма выполняется только тогда, когда controlQubit находится в состоянии |1&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Controlled MyComplexSubroutine([controlQubit], targetQubits);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> // Кроме того, возможны комбинации, такие как обратная управляемая операция!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Controlled Adjoint MyComplexSubroutine([controlQubit], targetQubits);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Эта функция значительно упрощает реализацию сложных алгоритмов, таких как оракул в алгоритме поиска Гровера или алгоритм факторизации Шора, которые часто используют сложные подпрограммы и обратные им операции (обратные вычисления, или Uncomputation, для распутывания ненужных связей). Она радикально снижает вероятность человеческих ошибок и багов. По сравнению с Qiskit, который использует модель построения схем, это одно из самых больших преимуществ Q# как языка для описания алгоритмов.&lt;/p>
&lt;h3 id="82-оценка-ресурсов-resource-estimation-и-подготовка-к-будущему">8.2 Оценка ресурсов (Resource Estimation) и подготовка к будущему
&lt;/h3>&lt;p>Современные квантовые компьютеры находятся на стадии развития, известной как «NISQ» (Noisy Intermediate-Scale Quantum). Количество доступных кубитов невелико (от нескольких десятков до сотен), а уровень ошибок высок. Однако в преддверии эры отказоустойчивых квантовых компьютеров (FTQC: Fault-Tolerant Quantum Computer) критически важно иметь возможность заранее точно оценить: «Сколько логических кубитов потребуется для выполнения нового алгоритма?», «Сколько раз будут использованы вентили T или Тоффоли, которые очень затратны при исправлении ошибок?», «Каково будет время выполнения?».&lt;/p>
&lt;p>В QDK встроена среда выполнения «Оценщик ресурсов» (Resource Estimator). Используя этот инструмент, можно мгновенно рассчитать и вывести требуемые ресурсы крупномасштабного алгоритма путем анализа логических путей кода, даже не запуская его на реальном оборудовании или ресурсоемком симуляторе полного состояния. Это позволяет разработчикам и исследователям алгоритмов быстро оптимизировать не только теоретическую сложность, но и количество вентилей на практическом уровне, даже для будущих алгоритмов, которым потребуются тысячи или десятки тысяч кубитов.&lt;/p>
&lt;h2 id="9-заключение-ожидания-от-инженеров-программистов-следующего-поколения">9. Заключение: Ожидания от инженеров-программистов следующего поколения
&lt;/h2>&lt;p>Квантовые вычисления стремительно переходят из области чистых теоретических концепций в головах таких физиков, как Эйнштейн, Шрёдингер и Фейнман, в практическую инженерную плоскость, доступную каждому пользователю в мире через браузер или командную строку благодаря облачной инфраструктуре (Azure Quantum, AWS Braket, IBM Quantum и др.). Скорость развития аппаратного обеспечения поражает, и многие эксперты ожидают, что в ближайшие несколько лет наступит день, когда будет доказано «практически полезное» квантовое преимущество.&lt;/p>
&lt;p>Язык Q# от Microsoft, представленный в этой статье, красиво перенес в совершенно новый мир квантового программирования лучшие практики, нарабатываемые десятилетиями в мире классического программирования: строгую типизацию, элементы функционального программирования, модульность, инкапсуляцию и мощную поддержку со стороны IDE. Изучая Q# и реализуя квантовые алгоритмы, мы можем получить глубокое понимание основ информатики и физики: «Что такое состояние?», «Что такое измерение?», «Как информация распространяется в пространстве?». Это не просто повышение квалификации, но и захватывающий интеллектуальный опыт.&lt;/p>
&lt;p>В недалеком будущем, точно так же, как сегодняшние инженеры по машинному обучению привычно используют PyTorch или TensorFlow для извлечения максимальной пользы из параллельных вычислений на GPU, следующее поколение «инженеров квантового программного обеспечения» будет использовать Q# и Qiskit для раскрытия колоссальной вычислительной мощности QPU (Quantum Processing Unit). Наверняка наступит эпоха, когда мы бросим вызов масштабным проблемам человечества, таким как открытие новых материалов, молекулярное моделирование в разработке лекарств, моделирование изменения климата и оптимизация рисков в финансах.&lt;/p>
&lt;p>Даже если вы сегодня занимаетесь в основном разработкой классических веб-приложений, мобильных приложений или анализом данных, обязательно воспользуйтесь этой возможностью и погрузитесь в мир квантового программирования. Поначалу контринтуитивные квантовомеханические явления (суперпозиция, запутанность, вероятностное поведение) могут сбивать с толку. Однако специализированный язык Q# и мощный набор инструментов QDK обязательно станут вашей надежной опорой на пути обучения.&lt;/p>
&lt;h2 id="10-ссылки-на-полезные-ресурсы-для-дальнейшего-изучения">10. Ссылки на полезные ресурсы для дальнейшего изучения
&lt;/h2>&lt;p>Вот несколько отличных ресурсов для продолжения вашего путешествия в мир квантового программирования:&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://learn.microsoft.com/azure/quantum/" target="_blank" rel="noopener"
>Официальная документация Microsoft Azure Quantum&lt;/a> : Полный портал документации по QDK и Azure Quantum.&lt;/li>
&lt;li>&lt;a class="link" href="https://learn.microsoft.com/azure/quantum/user-guide/" target="_blank" rel="noopener"
>Руководство пользователя и справочник по Q#&lt;/a> : Полный справочник по синтаксису, системе типов и стандартной библиотеке Q#.&lt;/li>
&lt;li>&lt;a class="link" href="https://quantum.microsoft.com/en-us/experience/quantum-katas" target="_blank" rel="noopener"
>Quantum Katas&lt;/a> : Набор руководств с открытым исходным кодом от Microsoft. Это отличный ресурс в формате разработки через тестирование (TDD) для интерактивного самостоятельного изучения базовых концепций квантовых вычислений (квантовых вентилей, измерений, построения алгоритмов) с написанием реального кода на Q#.&lt;/li>
&lt;li>&lt;a class="link" href="https://github.com/microsoft/qsharp-compiler" target="_blank" rel="noopener"
>Репозиторий Q# на GitHub&lt;/a> : Компилятор языка Q# и стандартная библиотека также активно разрабатываются как проекты с открытым исходным кодом. Обязательно к просмотру, если вам интересно внутреннее устройство компилятора.&lt;/li>
&lt;/ul>
&lt;p>Будущее квантовых вычислений только начинается и полно безграничных возможностей. Дерзайте писать код на Q# и получайте удовольствие от новой парадигмы программирования!&lt;/p></description></item></channel></rss>