Lewati ke konten utama
Proyek ini masih dalam tahap beta. Menemukan bug? Buat isu GitHub. Punya pertanyaan atau ide? Tanya di Discussions — kami sangat menghargai masukan kamu!
Bagaimana kualitas terjemahan di halaman ini?

Constrained Quantum Optimizer - Sebuah Fungsi Qiskit oleh Aqarios

Lihat referensi API

catatan

Qiskit Functions adalah fitur eksperimental yang hanya tersedia untuk pengguna IBM Quantum® Premium Plan, Flex Plan, dan On-Prem (melalui IBM Quantum Platform API) Plan. Fitur ini berstatus rilis pratinjau dan dapat berubah sewaktu-waktu.

Ikhtisar​

Dengan Constrained Quantum Optimizer oleh Aqarios, Anda dapat menyelesaikan masalah optimasi biner dengan batasan pada perangkat keras kuantum IBM® tanpa reformulasi manual dan pemetaan sirkuit. Cukup berikan masalah sebagai file LP, file MPS, atau Luna Model. Fungsi ini menangani reformulasi, sintesis sirkuit, transpilasi, dan eksekusi perangkat keras secara otomatis. Solver ini memanfaatkan warm-starting iteratif [1] dari algoritma FlexQAOA, sebuah ekstensi constraint-native dari Quantum Approximate Optimization Algorithm (QAOA).

Optimizer ini menargetkan masalah biner dengan batasan (constraints). Secara khusus, batasan one-hot dan batasan set-packing dapat diterapkan secara native dengan menggunakan XY-mixer. Jenis batasan lainnya secara otomatis direformulasikan sebagai suku penalti.

Tipe variabel yang didukung

Fungsi ini hanya menyelesaikan masalah diskrit. Setiap variabel keputusan harus biner, atau integer dengan batas bawah dan batas atas yang eksplisit, supaya bisa di-encode ke dalam qubit. Variabel kontinu (bernilai real) tidak didukung: model yang berisi variabel tersebut ditolak dengan kode error 4710.

Deskripsi​

Penyangkalan

Kinerja dapat bergantung pada instance masalah maupun langkah-langkah pemrosesan selanjutnya. Dalam beberapa kasus, sampel klasik dan sampel yang dihasilkan kuantum mungkin mencapai kualitas solusi akhir yang serupa setelah pascapemrosesan yang setara. Oleh karena itu, evaluasi harus mempertimbangkan keseluruhan alur kerja optimasi.

Constrained Quantum Optimizer mengimplementasikan Iterative warm-start XY-mixer QAOA (IWS-QAOA) [1]. Algoritma ini menjalankan sirkuit QAOA sudut tetap (fixed-angle) pada perangkat keras kuantum dan memperbarui probabilitas warm-start awal setiap sirkuit menggunakan hasil pengukuran dari iterasi sebelumnya. Tidak diperlukan pelatihan parameter variasional; sebagai gantinya, dipilih parametrisasi ramp linear tetap.

Dengan menggunakan XY-mixer untuk menerapkan batasan one-hot, Anda dapat meningkatkan kualitas solusi secara drastis untuk masalah dengan batasan, karena ruang pencarian secara praktis direduksi menjadi subruang yang layak (feasible) yang lebih kecil — dan tidak ada kompleksitas tambahan, akibat suku penalti, yang diperkenalkan ke dalam lanskap optimasi.

Alur Kerja​

Alur kerja fungsi ini dijelaskan di bawah ini:

  1. Preprocessing: Sebelum sintesis sirkuit, optimizer menganalisis struktur batasan dari masalah input:

    • Preprocessing graf: Jika berlaku untuk masalah tersebut, masalah dianalisis sebagai graf, di mana edge menentukan hubungan antar variabel. Analisis graf ini memungkinkan dua peningkatan preprocessing masalah. Pertama, batasan tunggal dapat digabungkan menjadi satu batasan besar dengan menggunakan penggabungan clique, sehingga direpresentasikan oleh satu XY-mixer. Kedua, variabel yang hanya memiliki satu tetangga dapat difiksasi secara deterministik, sehingga mengurangi ukuran dan kompleksitas masalah.

    • Penyelesaian batasan: Preprocessor menangani setiap batasan secara terpisah: Jika batasan tersebut adalah batasan one-hot, batasan itu dapat diterapkan melalui XY-mixer. Jika batasan tersebut adalah batasan set-packing, batasan itu akan terlebih dahulu diubah menjadi batasan one-hot. Batasan persamaan ditangani melalui penalti kuadratik, dan batasan pertidaksamaan melalui penalisasi tidak seimbang.

    • Penurunan penalti: Batasan yang tidak dapat dinyatakan sebagai batasan persamaan one-hot diubah menjadi suku penalti. Optimizer menentukan kekuatan penalti secara otomatis dari struktur masalah.

  2. Warm-starting iteratif: Optimizer menjalankan beberapa rantai warm-start paralel. Setiap rantai menyimpan distribusi probabilitas atas penugasan variabel, yang digunakan sebagai probabilitas awal sirkuit QAOA (keadaan warm-start). Pada setiap iterasi, sebuah rantai mengambil sampel dari sirkuit kuantum, menerapkan pascapemrosesan klasik, dan memperbarui distribusinya berdasarkan kemunculan sampel. Di seluruh iterasi, ini memfokuskan pencarian pada solusi berkualitas tinggi tanpa loop optimasi variasional.

Jumlah rantai (num_parallel), total anggaran shot per rantai (total_shots), dan jumlah pengulangan QAOA (reps) adalah kontrol utama untuk menyeimbangkan kualitas solusi dengan waktu eksekusi.

Workflow diagram of the Constrained Quantum Optimizer

Benchmark​

Benchmark di bawah ini menunjukkan bahwa Fungsi Qiskit Constrained Quantum Optimizer mampu menemukan solusi yang layak (feasible) dan berkualitas tinggi untuk masalah optimasi dengan batasan yang memiliki jauh lebih dari 100 variabel biner. Akurasi adalah rasio nilai objektif yang ditemukan terhadap optimum yang diketahui. Runtime adalah waktu wall-clock dari pemanggilan fungsi hingga pengiriman hasil. Penggunaan QPU adalah waktu Quantum Compute yang dapat ditagih.

Ada dua masalah yang diuji: masalah Maximum Independent Set (MIS) dan Max-kk-Cut, yang merupakan perluasan dari masalah MaxCut yang terkenal ke lebih dari dua kategori. Max-kk-Cut juga merupakan padanan masalah optimasi dari masalah keputusan pewarnaan graf (graph coloring) (ketika semua edge terpotong, graf tersebut dapat diwarnai dengan kk warna).

MasalahVariabelBatasanQubitAkurasiKelayakanTotal runtime (s)Penggunaan QPU (s)Total shot
MIS es60fst02186280124100.0%True940.2147.025.0k
MIS sloane_2dc_128128517374100.0%True347.6106.012.5k
Max-3-Cut Karate Club99339998.7%True279.5166.025.0k
Max-4-Cut Karate Club13233132100.0%True258.3200.025.0k

Catatan Benchmark​

  • Hasil di atas diperoleh pada prosesor Heron r2 ibm_marrakesh dengan opsi default dan use_session diaktifkan. Untuk instance sloane_2dc_128, digunakan total_shots=12500.

  • Jumlah qubit yang berkurang untuk instance MIS (74 dan 124 dibandingkan dengan 128 dan 186 variabel) mencerminkan penetapan nilai variabel pada tahap preprocessing.

  • Instance masalah untuk MIS diambil dari Quantum Optimization Benchmarking Library. - Instance untuk masalah Max-kk-Cut adalah graf Zachary Karate Club, yang memiliki bilangan kromatik 5.

Mulai​

Panduan ini menunjukkan penggunaan dasar Constrained Quantum Optimizer dengan memperlihatkan cara memuat fungsi dan menjalankan masalah sederhana. Untuk tutorial yang lebih mendalam, lihat Find the Maximum Independent Set with the Aqarios Constrained Quantum Optimizer.

Autentikasi dengan kunci API IBM Quantum dan CRN instance Anda, lalu muat fungsi dari katalog.

catatan

Kode berikut mengasumsikan Anda telah menyimpan kredensial Anda. Untuk menyiapkannya, ikuti petunjuk dalam Save your IBM Cloud account credentials.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"luna_model": "luna-model", "networkx": "networkx", "qiskit_addon_opt_mapper": "qiskit-addon-opt-mapper", "qiskit_ibm_catalog": "qiskit-ibm-catalog"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# Verify that you have access to the function
catalog.list()
[QiskitFunction(aqarios/constrained-quantum-optimizer)]
# Load the function
optimizer = catalog.load("aqarios/constrained-quantum-optimizer")
# Check the list of backends you have access to
catalog.backends()
[<IBMBackend('ibm_pittsburgh')>,
<IBMBackend('ibm_boston')>,
<IBMBackend('ibm_phoenix')>,
<IBMBackend('ibm_fez')>,
<IBMBackend('ibm_miami')>,
<IBMBackend('ibm_marrakesh')>,
<IBMBackend('ibm_kingston')>]
# Select the backend you want to use
backend = catalog.backend("ibm_phoenix")

Contoh 1: Masalah sederhana dengan batasan​

Contoh pertama menunjukkan cara menggunakan fungsi dengan file LP, spesifikasi masalah optimasi umum yang digunakan dalam riset operasi. Anda akan merumuskan masalah optimasi arbitrer berikut dengan lima variabel biner xi∈{0,1}x_i \in \{0,1\} yang tunduk pada dua batasan:

min⁡x1x2+2x2x3−x3x4−2x4x5−2x1x3−4x2x5s.t.x1+x2+x3≤1x3−x4+x5=0 \min x_1 x_2 + 2 x_2 x_3 - x_3 x_4 - 2 x_4 x_5 - 2 x_1 x_3 - 4 x_2 x_5 \\ \text{s.t.}\quad x_1 + x_2 + x_3 \leq 1 \\ \quad x_3 - x_4 + x_5 = 0

1. Rumuskan masalah​

Nyatakan langsung ekspresi matematis sebagai format string LP berikut:

lp_str = """\\Problem name: Example
Minimize
obj: [ 2 x_1 x_2 + 4 x_2 x_3 - 2 x_3 x_4 - 4 x_4 x_5 - 4 x_1 x_3 - 8 x_2 x_5 ] / 2
Subject To
c1: x_1 + x_2 + x_3 <= 1
c2: x_3 - x_4 + x_5 = 0
Binaries
x_1 x_2 x_3 x_4 x_5
End
"""

Perhatikan bahwa [ ... ] / 2 adalah notasi yang diperlukan untuk fungsi objektif kuadratik dari standar LP.

2. Jalankan optimizer​

Selesaikan masalah dengan optimizer.

# Set up low-resource options for the simple problem
options = {"total_shots": 2000, "num_parallel": 5, "use_session": True}

# Dispatch the job
job_1 = optimizer.run(
problem=lp_str, backend_name=backend.name, options=options
)

print(f"Job ID: {job_1.job_id}")
Job ID: 2e06a3a8-7c29-4c76-94d7-194293363f4a
# Monitor the job status
job_1.status()
'RUNNING: WAITING_FOR_QPU'

3. Ambil hasil​

Hasil ini memuat solusi, yaitu pemetaan nama variabel ke nilai yang ditetapkan.

result = job_1.result()

result
{'solutions': [{'x_1': 0, 'x_2': 1, 'x_3': 0, 'x_4': 1, 'x_5': 1}],
'solution_bitstrings': ['01011'],
'raw_energy': -6.0,
'objective_value': -6.0,
'feasible': True,
'metadata': {'resource_usage': {'RUNNING: MAPPING': {'CPU': 5.405},
'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU': 9.902},
'RUNNING: WAITING_FOR_QPU': {'CPU': 25.456},
'RUNNING: EXECUTING_QPU': {'CPU': 25.202},
'RUNNING: POST_PROCESSING': {'CPU': 6.481}},
'circuit_metrics': {'before_transpilation': {'num_qubits': 6,
'gate_count': 42,
'depth': 15,
'two_qubit_gate_count': 12,
'two_qubit_gate_depth': 7,
'operations': {'rz': 12,
'p': 8,
'ry': 7,
'rzz': 4,
'cx': 3,
'xx_plus_yy': 3,
'global_phase': 2,
'cry': 2,
'x': 1}},
'after_transpilation': {'num_qubits': 6,
'gate_count': 254,
'depth': 100,
'two_qubit_gate_count': 48,
'two_qubit_gate_depth': 33,
'operations': {'rz': 78, 'sx': 122, 'cz': 48, 'measure': 6, 'x': 0}}},
'solver_info': {'variable_mapping': {'x_1': 0,
'x_2': 1,
'x_3': 2,
'x_4': 3,
'x_5': 4}}}}

Field solutions dalam dictionary hasil berisi semua solusi terbaik yang degenerate yang ditemukan, berupa dictionary yang memetakan setiap nama variabel ke nilainya. Solusi yang sama juga dikembalikan sebagai bitstring di solution_bitstrings; metadata.solver_info.variable_mapping menunjukkan posisi karakter mana dalam bitstring yang merupakan milik variabel mana. Selain data solusi, tersedia juga objective_value, flag feasible, dan metadata tambahan.

Contoh 2: Maximum Independent Set​

Masalah Maximum Independent Set (MIS) mencari subset vertex terbesar dalam sebuah graf sedemikian rupa sehingga tidak ada dua vertex dalam subset tersebut yang berbagi edge. Contoh ini menyelesaikan MIS pada graf reguler dengan 12 node. Untuk informasi lebih lanjut tentang masalah ini dan contoh yang lebih besar, lihat tutorial.

Masalah ini dibangun dengan qiskit-addon-opt-mapper. Instal paket yang diperlukan jika perlu:

# %pip install networkx qiskit-addon-opt-mapper

Langkah 1: Definisikan masalah​

Buat graf 3-reguler acak dan buat masalah optimasi MIS. Setiap node graf menjadi variabel biner, dan setiap edge memperkenalkan batasan yang memastikan bahwa paling banyak satu endpoint yang dipilih.

import networkx as nx
from qiskit_addon_opt_mapper.applications import IndependentSet
from qiskit_addon_opt_mapper.translators import to_docplex_mp

# 12-node random 3-regular graph
G = nx.random_regular_graph(3, 12, seed=7)

# Build MIS problem and export as LP string
mis = IndependentSet(G)
mis_problem = mis.to_optimization_problem()
lp_str = to_docplex_mp(mis_problem).export_as_lp_string()

print(lp_str)
\ This file has been generated by DOcplex
\ ENCODING=ISO-8859-1
\Problem name: Independent set

Maximize
obj: x_0 + x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 + x_8 + x_9 + x_10 + x_11
Subject To
c0: x_0 + x_4 <= 1
c1: x_0 + x_9 <= 1
c2: x_0 + x_8 <= 1
c3: x_1 + x_2 <= 1
c4: x_1 + x_7 <= 1
c5: x_1 + x_3 <= 1
c6: x_2 + x_4 <= 1
c7: x_2 + x_11 <= 1
c8: x_3 + x_10 <= 1
c9: x_3 + x_11 <= 1
c10: x_4 + x_5 <= 1
c11: x_5 + x_10 <= 1
c12: x_5 + x_6 <= 1
c13: x_6 + x_8 <= 1
c14: x_6 + x_7 <= 1
c15: x_7 + x_9 <= 1
c16: x_8 + x_11 <= 1
c17: x_9 + x_10 <= 1

Bounds
0 <= x_0 <= 1
0 <= x_1 <= 1
0 <= x_2 <= 1
0 <= x_3 <= 1
0 <= x_4 <= 1
0 <= x_5 <= 1
0 <= x_6 <= 1
0 <= x_7 <= 1
0 <= x_8 <= 1
0 <= x_9 <= 1
0 <= x_10 <= 1
0 <= x_11 <= 1

Binaries
x_0 x_1 x_2 x_3 x_4 x_5 x_6 x_7 x_8 x_9 x_10 x_11
End

Langkah 2: Jalankan optimizer​

Selesaikan masalah dengan optimizer.

options = {"total_shots": 2000, "use_session": True}

# Dispatch the job
job_2 = optimizer.run(
problem=lp_str, backend_name=backend.name, options=options
)

print(f"Job ID: {job_2.job_id}")
Job ID: f041431c-b42e-4627-afe5-522fea61faf6
# Monitor the job status
job_2.status()
'QUEUED'

Langkah 3: Ambil dan interpretasikan hasil​

Terakhir, kita mengambil solusi dan memverifikasi kebenarannya.

result = job_2.result()

print(f"Feasible: {result['feasible']}")
print(f"Independent set size: {int(result['objective_value'])}")

# Extract the selected nodes
solution = result["solutions"][0]
independent_set = [
int(k.split("_")[1]) for k, v in solution.items() if v == 1
]
print(f"Selected nodes: {sorted(independent_set)}")

# Verify no two selected nodes share an edge
conflicts = [
(u, v)
for u, v in G.edges()
if u in independent_set and v in independent_set
]
print(f"Edge conflicts: {conflicts}")
Feasible: True
Independent set size: 5
Selected nodes: [1, 4, 6, 9, 11]
Edge conflicts: []

Contoh 3: Pewarnaan-3 graf (Max-3-Cut)​

Masalah Max-kk-Cut mempartisi vertex dari sebuah graf menjadi kk kelompok untuk memaksimalkan jumlah edge yang endpoint-nya berada pada kelompok yang berbeda. Untuk k=3k = 3 ini setara dengan menemukan pewarnaan 3 yang memaksimalkan edge lintas warna.

Secara formal, tetapkan setiap node i∈Vi \in V ke salah satu dari kk kelompok dengan variabel biner xi,cx_{i,c} untuk warna c∈{1,…,k}c \in \{1, \ldots, k\}. Batasan one-hot ∑cxi,c=1\sum_c x_{i,c} = 1 untuk setiap node memastikan penugasan yang unik. Fungsi objektif memaksimalkan edge lintas kelompok:

min⁡∑(u,v)∈E∑cxu,c xv,cs.t.∑cxi,c=1∀i∈V\min \sum_{(u,v) \in E} \sum_c x_{u,c} \, x_{v,c}\\ \text{s.t.} \sum_{c} x_{i,c} = 1 \quad \forall i \in V

Batasan one-hot ideal untuk XY-mixer, yang ditangani secara native oleh optimizer.

Contoh ini menggunakan graf Zachary Karate Club (34 node, 78 edge) dan membangun model dengan Luna Model. Instal paket yang diperlukan jika perlu:

# %pip install networkx matplotlib luna-model

Langkah 1: Definisikan masalah​

Pertama, hasilkan variabel biner dengan paket luna-model. Kemudian, definisikan fungsi objektif dan tambahkan batasan ke model.

import networkx as nx
from luna_model import Model, quicksum

k = 3
G = nx.karate_club_graph()

# Instantiate the Model object
model = Model(name="Max-3-Cut")

# Add binary variables
x = model.add_variables("x", shape=(G.number_of_nodes(), k))

# Add the objective by using the numpy dot abstraction
model.objective = quicksum(x[i].dot(x[j]) for i, j in G.edges)

# Bulk-add the one-hot constraints
model.add_constraints(x.sum(axis=1) == 1)

# Encode the model to send via API
model_enc = model.encode_b64()

Langkah 2: Jalankan optimizer​

Selesaikan masalah dengan optimizer.

options = {"use_session": True}

# Dispatch the job
job_3 = optimizer.run(
problem=model_enc, backend_name=backend.name, options=options
)

print(f"Job ID: {job_3.job_id}")
Job ID: df911d83-9df7-44a1-bfad-5d66e08676c3
# Monitor the job status
job_3.status()
'RUNNING: WAITING_FOR_QPU'

Langkah 3: Ambil dan visualisasikan hasil​

Ambil dan visualisasikan hasilnya.

result = job_3.result()
solution = result["solutions"][0]

# Map each node to its assigned color group
node_group = {}
for i in G.nodes:
for c in range(k):
if solution[f"x{i},{c}"] == 1:
node_group[i] = c

print(f"Feasible: {result['feasible']}")
print(f"Violations: {int(result['objective_value'])}")

# Visualize the partition
colors = ["tab:blue", "tab:orange", "tab:green"]
node_colors = [colors[node_group[i]] for i in G.nodes()]
nx.draw(G, nx.kamada_kawai_layout(G), node_color=node_colors, node_size=200)
Feasible: True
Violations: 4

Output of the previous code cell

Log Perubahan​

[0.4.0] - 2026-09-22​

Perubahan yang tidak kompatibel (breaking changes)

  • Mengganti nama parameter input model menjadi problem.
  • Mengganti nama field output obj_value menjadi objective_value.
  • Mengganti opsi postprocessing dengan postprocessing_level, yang menerima integer dalam rentang [0, 3] alih-alih string. Nilai sebelumnya dipetakan sebagai "off" -> 0, "weak" -> 1, "medium" -> 2, dan "strong" -> 3, dan defaultnya tetap 3.
  • Menyusun ulang metadata.circuit_metrics. Sekarang field ini melaporkan num_qubits, gate_count, depth, two_qubit_gate_count, two_qubit_gate_depth, dan operations secara terpisah untuk before_transpilation dan after_transpilation, bukan satu dictionary datar berisi rata-rata jumlah gate. Field ini bernilai None ketika masalah diselesaikan saat preprocessing dan tidak ada sirkuit yang dijalankan (kode error 4712).

Fitur

  • Menambahkan opsi seed_transpiler supaya sintesis dan routing sirkuit bisa direproduksi antar-run.
  • Menambahkan opsi job_tags untuk melampirkan tag Anda sendiri ke setiap job Qiskit Runtime yang dikirim oleh fungsi.
  • Menambahkan field output solution_bitstrings, yang mengembalikan solusi yang sama seperti solutions dalam bentuk bitstring.
  • Menambahkan metadata.solver_info.variable_mapping, yang memetakan setiap nama variabel ke posisi karakternya dalam entri solution_bitstrings.

Dokumentasi

  • Mendokumentasikan bahwa variabel kontinu (bernilai real) tidak didukung dan bahwa variabel integer memerlukan batas yang eksplisit. Model seperti itu gagal dengan kode error 4710.

Dapatkan dukungan​

Untuk pertanyaan atau masalah, hubungi support@aqarios.com dengan menyertakan ID job Anda.

Langkah selanjutnya​

Rekomendasi

Referensi​

  1. Bucher et al. (2026), Constrained Quantum Optimization via Iterative Warm-Start XY-Mixers 10.1088/1367-2630/ae8ea2