होम/ब्लॉग/QAOA की व्याख्या: Max-Cut को चरण दर चरण हल करना
AlgorithmsQAOAQiskitPennyLane

QAOA की व्याख्या: Max-Cut को चरण दर चरण हल करना

Max-Cut ग्राफ़ समस्या पर लागू Quantum Approximate Optimization Algorithm का एक व्यावहारिक अवलोकन — Qiskit, PennyLane, और HLQuantum का उपयोग करते हुए पूर्ण Python कोड के साथ।

FreeQuantumComputing
·· 11 min read

QAOA (Quantum Approximate Optimization Algorithm) निकट-अवधि के सबसे अधिक चर्चित क्वांटम एल्गोरिदम में से एक है — और सही कारणों से। यह संयोजनात्मक अनुकूलन समस्याओं पर क्वांटम लाभ का एक वास्तविक उम्मीदवार है, यह आज के NISQ हार्डवेयर पर चलता है, और यह एक दोपहर में लागू करने के लिए पर्याप्त सुलभ है।

यह मार्गदर्शिका उदाहरण समस्या के रूप में Max-Cut का उपयोग करते हुए, शुरू से पूरी QAOA पाइपलाइन बनाती है। अंत तक आप समझ जाएंगे कि QAOA वास्तव में क्या करता है, इसे कैसे लागू करें, और इसका उपयोग करना कब सार्थक है।

Max-Cut क्या है?

Max-Cut एक ग्राफ़ विभाजन समस्या है: एक ग्राफ़ दिए जाने पर, नोड्स को दो समूहों (0 और 1) में विभाजित करें ताकि समूहों के बीच से गुजरने वाले किनारों (edges) की संख्या अधिकतम हो। यह सामान्यतः NP-hard है, VLSI चिप डिज़ाइन, क्लस्टरिंग, और नेटवर्क विश्लेषण में दिखाई देती है, और क्वांटम हार्डवेयर पर सफाई से मैप हो जाती है।

यहाँ एक सरल 4-नोड ग्राफ़ है:

0 --- 1
|   \ |
3 --- 2

इस ग्राफ़ का अधिकतम कट 4 है (किनारे 0-1, 1-2, 2-3, 3-0 सभी पार करते हैं)। हमारा लक्ष्य: वह बिट स्ट्रिंग 0101 या 1010 खोजना जो इसे प्राप्त करती है।

QAOA का विचार

QAOA एक वैरिएशनल हाइब्रिड एल्गोरिदम है। यह दो पैरामीटरीकृत संक्रियाओं के बीच बारी-बारी करता है:

  1. समस्या यूनिटरी (Problem unitary) U_C(γ) — लागत फ़ंक्शन (किनारा पार करना) को फ़ेज़ किकबैक के रूप में एनकोड करता है
  2. मिक्सर यूनिटरी (Mixer unitary) U_B(β) — समाधानों के बीच मिश्रण करता है (X रोटेशन)

इन बारी-बारी की यूनिटरीज़ की p परतों के साथ, QAOA एक क्वांटम अवस्था तैयार करता है जिसका माप संभवतः एक अच्छा समाधान होता है। एक क्लासिकल ऑप्टिमाइज़र अपेक्षित कट मान को अधिकतम करने के लिए 2p कोणों (γ, β) को ट्यून करता है।

PennyLane के साथ QAOA बनाना

import pennylane as qml
import numpy as np
from scipy.optimize import minimize

# Graph edges
edges = [(0, 1), (1, 2), (2, 3), (3, 0)]
n_qubits = 4

dev = qml.device("default.qubit", wires=n_qubits)

def cost_unitary(gamma):
    """Encode the Max-Cut cost into phases."""
    for u, v in edges:
        qml.CNOT(wires=[u, v])
        qml.RZ(2 * gamma, wires=v)
        qml.CNOT(wires=[u, v])

def mixer_unitary(beta):
    """Apply X-rotation mixer to all qubits."""
    for i in range(n_qubits):
        qml.RX(2 * beta, wires=i)

@qml.qnode(dev)
def qaoa_circuit(params, p=1):
    gammas = params[:p]
    betas = params[p:]
    # Start in uniform superposition
    for i in range(n_qubits):
        qml.Hadamard(wires=i)
    # Alternate p layers
    for layer in range(p):
        cost_unitary(gammas[layer])
        mixer_unitary(betas[layer])
    return qml.probs(wires=range(n_qubits))

def expected_cut(params, p=1):
    """Classical cost function: expected number of cut edges."""
    probs = qaoa_circuit(params, p)
    total = 0.0
    for bitstring_idx, prob in enumerate(probs):
        bits = format(bitstring_idx, f'0{n_qubits}b')
        cut = sum(1 for u, v in edges if bits[u] != bits[v])
        total += prob * cut
    return -total  # Minimize negative cut

# Optimize p=1 QAOA
p = 1
init_params = np.random.uniform(0, np.pi, 2 * p)
result = minimize(expected_cut, init_params, method='COBYLA',
                  options={'maxiter': 200})

print(f"Optimized params: {result.x}")
print(f"Expected cut: {-result.fun:.3f} / 4.0 maximum")

इसे चलाने पर आमतौर पर p=1 के साथ expected_cut ≈ 3.5 प्राप्त होता है — अधिकतम कट का 87.5%।

सर्वोत्तम समाधान का सैंपलिंग

अनुकूलन के बाद, सबसे संभावित अच्छे समाधान खोजने के लिए सर्किट का सैंपल लें:

@qml.qnode(dev)
def sample_circuit(params, p=1, shots=1000):
    gammas = params[:p]
    betas = params[p:]
    for i in range(n_qubits):
        qml.Hadamard(wires=i)
    for layer in range(p):
        cost_unitary(gammas[layer])
        mixer_unitary(betas[layer])
    return qml.sample(wires=range(n_qubits))

samples = sample_circuit(result.x, shots=1000)

# Count cut values for each bitstring
from collections import Counter
cut_counts = Counter()
for bits in samples:
    key = ''.join(str(b) for b in bits)
    cut = sum(1 for u, v in edges if bits[u] != bits[v])
    cut_counts[(key, cut)] += 1

# Show top 5 most frequent bitstrings
for (bits, cut), count in sorted(cut_counts.items(), key=lambda x: -x[1])[:5]:
    print(f"{bits}  cut={cut}  frequency={count/10:.1f}%")

अपेक्षित आउटपुट:

0101  cut=4  frequency=28.3%
1010  cut=4  frequency=27.1%
0110  cut=3  frequency=8.4%
...

इष्टतम समाधान (0101 और 1010) हावी रहते हैं — QAOA ने उनकी प्रायिकता को बढ़ा दिया।

वही समस्या HLQuantum के साथ

HLQuantum का अंतर्निहित QAOA आपको सर्किट निर्माण को पूरी तरह छोड़ देने की अनुमति देता है:

import hlquantum as hlq

graph = [(0, 1), (1, 2), (2, 3), (3, 0)]

result = hlq.algorithms.qaoa(
    graph=graph,
    problem='max_cut',
    p=2,
    backend='pennylane',
    shots=2000,
)

print(result.best_solution)   # '0101' or '1010'
print(result.cut_value)       # 4
print(result.approximation_ratio)  # ~0.96 for p=2

एक ही फ़्लैग से बैकएंड बदलें:

# Run on Qiskit Aer
result_qiskit = hlq.algorithms.qaoa(graph=graph, problem='max_cut', p=2, backend='qiskit')

# Run on real IonQ hardware (if you have credits)
result_ionq = hlq.algorithms.qaoa(graph=graph, problem='max_cut', p=2,
                                   backend='ionq', device='aria-1')

बेहतर परिणामों के लिए p बढ़ाना

QAOA का सन्निकटन अनुपात गहराई p के साथ बेहतर होता है। p→∞ पर, QAOA समस्या को सटीक रूप से हल कर देता है। व्यवहार में:

pविशिष्ट सन्निकटन अनुपात (Max-Cut)आवश्यक गेट्स
1~0.752×edges + 4n
2~0.864×edges + 8n
3~0.916×edges + 12n
5~0.9510×edges + 20n

समझौता: गहरे सर्किट वास्तविक हार्डवेयर पर अधिक शोर (noise) एकत्रित करते हैं। सिम्युलेटर पर, p=3 या उससे अधिक का उपयोग करें। NISQ QPUs पर, p=1 या p=2 आमतौर पर व्यावहारिक सीमा है।

QAOA का उपयोग करना कब सार्थक है?

वर्तमान में उपयोगी:

  • NISQ उपकरणों का बेंचमार्किंग (QAOA एक मानक बेंचमार्क सर्किट है)
  • वैरिएशनल क्वांटम एल्गोरिदम पर शैक्षणिक अनुसंधान
  • सिम्युलेटर पर छोटे ग्राफ़ (20 नोड्स से कम)

अभी तक उपयोगी नहीं:

  • बड़े पैमाने पर वास्तविक हार्डवेयर पर उत्पादन अनुकूलन — क्लासिकल ह्यूरिस्टिक्स (simulated annealing, tabu search) व्यावहारिक समस्याओं पर अब भी QAOA से बेहतर प्रदर्शन करते हैं
  • बड़े ग्राफ़ — सर्किट गहराई ग्राफ़ घनत्व के साथ बढ़ती है

वादा: उच्च-गहराई वाले सर्किट के साथ भविष्य के फ़ॉल्ट-टॉलरेंट हार्डवेयर पर, बड़े p पर QAOA सघन NP-hard अनुकूलन के लिए वास्तविक गति वृद्धि प्रदान कर सकता है। सैद्धांतिक आधार ठोस हैं; हार्डवेयर अभी वहाँ तक नहीं पहुँचा है।

अगले चरण

  • PennyLane SDK guide — अधिक वैरिएशनल एल्गोरिदम के लिए PennyLane सेट अप करें
  • VQE guide — क्वांटम रसायन विज्ञान के लिए सहयोगी एल्गोरिदम
  • HLQuantum — एक ही API के साथ किसी भी बैकएंड पर QAOA चलाएं