ข้ามไปยังเนื้อหาหลัก
โครงการนี้อยู่ในช่วงเบต้า พบข้อผิดพลาด? สร้าง GitHub Issue มีคำถามหรือไอเดีย? ถามใน Discussions — ยินดีรับฟังความคิดเห็น!
คุณภาพการแปลในหน้านี้เป็นอย่างไร?

Constrained Quantum Optimizer - ฟังก์ชัน Qiskit โดย Aqarios

ดูเอกสารอ้างอิง API

หมายเหตุ

Qiskit Functions เป็นฟีเจอร์ทดลองที่ใช้ได้เฉพาะผู้ใช้แผน IBM Quantum® Premium Plan, Flex Plan และ On-Prem (ผ่าน IBM Quantum Platform API) เท่านั้น ฟีเจอร์นี้อยู่ในสถานะ preview release และอาจมีการเปลี่ยนแปลงได้

ภาพรวม​

ด้วย Constrained Quantum Optimizer โดย Aqarios คุณสามารถแก้ปัญหาการหาค่าเหมาะที่สุดแบบไบนารีที่มีข้อจำกัดบนฮาร์ดแวร์ควอนตัมของ IBM® ได้โดยไม่ต้องปรับสูตรใหม่ด้วยตนเองและไม่ต้องแมปวงจรเอง เพียงแค่ส่งปัญหาในรูปแบบไฟล์ LP, ไฟล์ MPS หรือ Luna Model ฟังก์ชันนี้จะจัดการการปรับสูตรใหม่ การสังเคราะห์วงจร การแปลง (transpilation) และการรันบนฮาร์ดแวร์โดยอัตโนมัติ ตัวแก้ปัญหาใช้ iterative warm-starting [1] ของอัลกอริทึม FlexQAOA ซึ่งเป็นส่วนขยายแบบ constraint-native ของ Quantum Approximate Optimization Algorithm (QAOA)

ตัวแก้ปัญหานี้มุ่งเป้าไปที่ปัญหาแบบไบนารีที่มีข้อจำกัด โดยเฉพาะอย่างยิ่ง one-hot constraints และ set-packing constraints สามารถบังคับได้โดยตรงในตัว (native) ผ่าน XY-mixers ส่วนข้อจำกัดประเภทอื่นจะถูกปรับสูตรใหม่โดยอัตโนมัติให้เป็น penalty terms

ชนิดของตัวแปรที่รองรับ

ฟังก์ชันนี้แก้ได้เฉพาะปัญหาแบบไม่ต่อเนื่อง (discrete) เท่านั้น ตัวแปรตัดสินใจทุกตัวต้องเป็นแบบไบนารี หรือเป็นจำนวนเต็มที่มีขอบเขตล่างและขอบเขตบนที่ระบุชัดเจน เพื่อให้เข้ารหัสลงในคิวบิตได้ ตัวแปรต่อเนื่อง (ค่าจำนวนจริง) ไม่รองรับ โมเดลที่มีตัวแปรเหล่านี้จะถูกปฏิเสธพร้อมรหัสข้อผิดพลาด 4710

คำอธิบาย​

ข้อจำกัดความรับผิดชอบ

ประสิทธิภาพอาจขึ้นอยู่กับทั้งอินสแตนซ์ของปัญหาและขั้นตอนการประมวลผลที่ตามมา ในบางกรณี ตัวอย่างแบบคลาสสิกและตัวอย่างที่สร้างด้วยควอนตัมอาจให้คุณภาพของคำตอบสุดท้ายที่ใกล้เคียงกันหลังจากการประมวลผลภายหลังที่เทียบเท่ากัน ดังนั้นการประเมินควรพิจารณากระบวนการหาค่าเหมาะที่สุดทั้งหมด

Constrained Quantum Optimizer นำ Iterative warm-start XY-mixer QAOA (IWS-QAOA) [1] มาใช้งาน อัลกอริทึมนี้รันวงจร QAOA แบบมุมคงที่บนฮาร์ดแวร์ควอนตัมและอัปเดตความน่าจะเป็นเริ่มต้นแบบ warm-start ของแต่ละวงจรโดยใช้ผลลัพธ์การวัดจากการทำซ้ำครั้งก่อนหน้า ไม่จำเป็นต้องมีการฝึกพารามิเตอร์แบบ variational แต่จะเลือกใช้การกำหนดพารามิเตอร์แบบ linear ramp คงที่แทน

การใช้ XY-mixers เพื่อบังคับใช้ one-hot constraints ช่วยเพิ่มคุณภาพของคำตอบสำหรับปัญหาที่มีข้อจำกัดได้อย่างมาก เนื่องจากพื้นที่การค้นหาถูกลดขนาดลงในทางปฏิบัติให้เหลือเพียง subspace ที่เป็นไปได้ที่เล็กลง — และไม่มีความซับซ้อนเพิ่มเติมจาก penalty terms ที่ถูกนำเข้ามาใน optimization landscape

ขั้นตอนการทำงาน​

ขั้นตอนการทำงานของฟังก์ชันนี้อธิบายไว้ด้านล่าง:

  1. การประมวลผลล่วงหน้า (Preprocessing): ก่อนการสังเคราะห์วงจร ตัวแก้ปัญหาจะวิเคราะห์โครงสร้างข้อจำกัดของปัญหาที่ป้อนเข้ามา:

    • การประมวลผลกราฟล่วงหน้า: เมื่อสามารถนำไปใช้กับปัญหาได้ ปัญหานั้นจะถูกวิเคราะห์ในรูปแบบกราฟ โดยที่ขอบ (edges) จะกำหนดความสัมพันธ์ระหว่างตัวแปร การวิเคราะห์กราฟนี้ช่วยให้เกิดการปรับปรุงปัญหาในขั้นตอนก่อนประมวลผลได้สองอย่าง ประการแรก ข้อจำกัดเดี่ยวหลายข้อสามารถรวมกันเป็นข้อจำกัดขนาดใหญ่ข้อเดียวได้โดยใช้การรวม clique (clique merging) ทำให้สามารถแทนด้วย XY-mixer เพียงตัวเดียว ประการที่สอง ตัวแปรที่มีเพื่อนบ้านเพียงตัวเดียวสามารถกำหนดค่าคงที่ได้อย่างแน่นอน ซึ่งช่วยลดขนาดและความซับซ้อนของปัญหา

    • การแก้ไขข้อจำกัด: ตัวประมวลผลล่วงหน้าจะจัดการกับข้อจำกัดแต่ละข้อแยกกัน หากข้อจำกัดนั้นเป็น one-hot constraint ก็สามารถบังคับใช้ได้ผ่าน XY-mixers หากเป็น set-packing constraint ก็จะถูกแปลงเป็น one-hot constraint ก่อน ข้อจำกัดแบบสมการ (equality constraints) จะถูกจัดการผ่าน quadratic penalties ส่วนข้อจำกัดแบบอสมการ (inequality constraints) จะถูกจัดการผ่าน unbalanced penalization

    • การหาค่า Penalty: ข้อจำกัดที่ไม่สามารถแสดงเป็น one-hot equality constraints ได้จะถูกแปลงเป็น penalty terms ตัวแก้ปัญหาจะคำนวณความแรงของ penalty โดยอัตโนมัติจากโครงสร้างของปัญหา

  2. Iterative warm-starting: ตัวแก้ปัญหาจะรัน parallel warm-start chains หลายชุดพร้อมกัน แต่ละ chain จะเก็บการแจกแจงความน่าจะเป็นเหนือการกำหนดค่าตัวแปร ซึ่งใช้เป็นความน่าจะเป็นเริ่มต้นของวงจร QAOA (warm-start state) ในแต่ละรอบการทำซ้ำ chain จะสุ่มตัวอย่างจากวงจรควอนตัม ทำการประมวลผลภายหลังแบบคลาสสิก และอัปเดตการแจกแจงตามการเกิดขึ้นของตัวอย่าง ตลอดหลายรอบการทำซ้ำ วิธีนี้ช่วยโฟกัสการค้นหาไปที่คำตอบคุณภาพสูงโดยไม่ต้องใช้ variational optimization loop

จำนวน chain (num_parallel) งบประมาณ shot ทั้งหมดต่อ chain (total_shots) และจำนวนการทำซ้ำของ QAOA (reps) เป็นตัวควบคุมหลักสำหรับการแลกเปลี่ยนระหว่างคุณภาพของคำตอบและระยะเวลาในการรัน

Workflow diagram of the Constrained Quantum Optimizer

การเปรียบเทียบประสิทธิภาพ​

เกณฑ์มาตรฐาน (benchmark) ด้านล่างแสดงให้เห็นว่าฟังก์ชัน Qiskit ของ Constrained Quantum Optimizer สามารถหาคำตอบที่มีคุณภาพสูงและเป็นไปได้ (feasible) สำหรับปัญหาการหาค่าเหมาะที่สุดแบบมีข้อจำกัดที่มีตัวแปรไบนารีเกินกว่า 100 ตัวไปมาก ความแม่นยำ (accuracy) คืออัตราส่วนของค่าฟังก์ชันวัตถุประสงค์ที่พบต่อค่าที่เหมาะที่สุดที่ทราบ ระยะเวลาในการรัน (runtime) คือเวลานาฬิกาจริงตั้งแต่การเรียกใช้ฟังก์ชันจนถึงการส่งมอบผลลัพธ์ การใช้งาน QPU คือเวลาในการคำนวณควอนตัมที่คิดค่าใช้จ่าย

มีการทดสอบปัญหาสองประเภท ได้แก่ ปัญหา Maximum Independent Set (MIS) และ Max-kk-Cut ซึ่งเป็นส่วนขยายของปัญหา MaxCut ที่รู้จักกันดีให้รองรับมากกว่าสองหมวดหมู่ Max-kk-Cut ยังเป็นปัญหาการหาค่าเหมาะที่สุดที่สมนัยกับปัญหาการตัดสินใจเรื่องการระบายสีกราฟ (graph coloring decision problem) (เมื่อขอบทั้งหมดถูกตัด กราฟจะสามารถระบายสีได้ด้วย kk สี)

ปัญหาตัวแปรข้อจำกัดคิวบิตความแม่นยำความเป็นไปได้ระยะเวลารวม (s)การใช้ QPU (s)จำนวนช็อตรวม
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

หมายเหตุเกี่ยวกับการเปรียบเทียบประสิทธิภาพ​

  • ผลลัพธ์ข้างต้นได้จากการรันบนโปรเซสเซอร์ ibm_marrakesh Heron r2 โดยใช้ตัวเลือกค่าเริ่มต้นและเปิดใช้ use_session สำหรับอินสแตนซ์ sloane_2dc_128 ได้ใช้ total_shots=12500

  • จำนวนคิวบิตที่ลดลงสำหรับอินสแตนซ์ MIS (74 และ 124 เทียบกับตัวแปร 128 และ 186 ตัว) สะท้อนถึงการกำหนดค่าตัวแปรคงที่ในขั้นตอนการประมวลผลล่วงหน้า

  • อินสแตนซ์ปัญหาสำหรับ MIS นำมาจาก Quantum Optimization Benchmarking Library - อินสแตนซ์สำหรับปัญหา Max-kk-Cut คือ กราฟ Zachary Karate Club ซึ่งมีเลขสี (chromatic number) เท่ากับ 5

เริ่มต้นใช้งาน​

คู่มือนี้สาธิตการใช้งานพื้นฐานของ Constrained Quantum Optimizer โดยแสดงวิธีโหลดฟังก์ชันและรันปัญหาอย่างง่าย สำหรับบทแนะนำที่เจาะลึกมากขึ้น โปรดดู Find the Maximum Independent Set with the Aqarios Constrained Quantum Optimizer

ยืนยันตัวตนด้วย API key ของ IBM Quantum และ instance CRN ของคุณ จากนั้นโหลดฟังก์ชันจากแคตตาล็อก

หมายเหตุ

โค้ดต่อไปนี้สมมติว่าคุณได้บันทึกข้อมูลรับรอง (credentials) ของคุณไว้แล้ว หากต้องการตั้งค่า ให้ทำตามคำแนะนำใน 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")

ตัวอย่างที่ 1: ปัญหาที่มีข้อจำกัดอย่างง่าย​

ตัวอย่างแรกแสดงวิธีใช้ฟังก์ชันกับ LP-files ซึ่งเป็นรูปแบบการระบุปัญหาการหาค่าเหมาะที่สุดที่ใช้กันทั่วไปในการวิจัยดำเนินงาน (operations research) คุณจะกำหนดปัญหาการหาค่าเหมาะที่สุดตามอำเภอใจต่อไปนี้ที่มีตัวแปรไบนารีห้าตัว xi∈{0,1}x_i \in \{0,1\} ภายใต้ข้อจำกัดสองข้อ:

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. กำหนดปัญหา​

ระบุนิพจน์ทางคณิตศาสตร์โดยตรงในรูปแบบ LP-string ดังต่อไปนี้:

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
"""

โปรดทราบว่า [ ... ] / 2 เป็นสัญกรณ์ที่จำเป็นสำหรับฟังก์ชันวัตถุประสงค์แบบกำลังสอง (quadratic objectives) ตามมาตรฐาน LP

2. รันตัวแก้ปัญหา​

แก้ปัญหาด้วยตัวแก้ปัญหา

# 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. ดึงผลลัพธ์​

ผลลัพธ์ให้คำตอบที่แมปชื่อตัวแปรไปยังค่าที่กำหนดที่เกี่ยวข้อง

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}}}}

ฟิลด์ solutions ใน dictionary ที่ส่งกลับมามีคำตอบที่ดีที่สุดแบบเสมอกัน (degenerate) ทั้งหมดที่พบ ในรูปแบบ dictionary ที่แมปชื่อตัวแปรแต่ละตัวไปยังค่าที่กำหนดให้ คำตอบชุดเดียวกันนี้ยังถูกส่งกลับเป็น bitstring ใน solution_bitstrings ด้วย โดย metadata.solver_info.variable_mapping จะบอกว่าตำแหน่งตัวอักษรใดของ bitstring เป็นของตัวแปรใด นอกจากข้อมูลคำตอบแล้ว ยังมี objective_value แฟล็ก feasible และ metadata เพิ่มเติมให้ด้วย

ตัวอย่างที่ 2: Maximum Independent Set​

ปัญหา Maximum Independent Set (MIS) ต้องการหาเซตย่อยที่ใหญ่ที่สุดของจุดยอด (vertices) ในกราฟ โดยที่ไม่มีจุดยอดสองจุดใดในเซตย่อยนั้นมีขอบเชื่อมกัน ตัวอย่างนี้แก้ปัญหา MIS บนกราฟปกติ (regular graph) ที่มี 12 โหนด สำหรับข้อมูลเพิ่มเติมเกี่ยวกับปัญหานี้และตัวอย่างที่ใหญ่กว่า โปรดดูบทแนะนำ

ปัญหานี้สร้างขึ้นด้วย qiskit-addon-opt-mapper ติดตั้งแพ็กเกจที่จำเป็นหากยังไม่ได้ติดตั้ง:

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

ขั้นตอนที่ 1: กำหนดปัญหา​

สร้างกราฟ 3-regular แบบสุ่มและสร้างปัญหาการหาค่าเหมาะที่สุดของ MIS โหนดแต่ละโหนดในกราฟจะกลายเป็นตัวแปรไบนารี และแต่ละขอบจะสร้างข้อจำกัดที่รับประกันว่ามีการเลือกจุดปลายได้อย่างมากที่สุดหนึ่งจุด

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

ขั้นตอนที่ 2: รันตัวแก้ปัญหา​

แก้ปัญหาด้วยตัวแก้ปัญหา

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'

ขั้นตอนที่ 3: ดึงและตีความผลลัพธ์​

สุดท้าย เราจะดึงคำตอบและตรวจสอบความถูกต้อง

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: []

ตัวอย่างที่ 3: การระบายสีกราฟแบบ 3 สี (Max-3-Cut)​

ปัญหา Max-kk-Cut แบ่งจุดยอดของกราฟออกเป็น kk กลุ่ม เพื่อให้จำนวนขอบที่จุดปลายอยู่คนละกลุ่มกันมีค่ามากที่สุด สำหรับ k=3k = 3 นี้จะเทียบเท่ากับการหาการระบายสี 3 สีที่ทำให้ขอบที่ข้ามสีมีจำนวนมากที่สุด

อย่างเป็นทางการ ให้กำหนดแต่ละโหนด i∈Vi \in V ให้กับหนึ่งใน kk กลุ่ม ด้วยตัวแปรไบนารี xi,cx_{i,c} สำหรับสี c∈{1,…,k}c \in \{1, \ldots, k\} ข้อจำกัด one-hot ∑cxi,c=1\sum_c x_{i,c} = 1 สำหรับแต่ละโหนดจะบังคับให้มีการกำหนดค่าที่ไม่ซ้ำกัน ฟังก์ชันวัตถุประสงค์จะทำให้ขอบที่ข้ามกลุ่มมีค่ามากที่สุด:

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

ข้อจำกัดแบบ one-hot เหมาะอย่างยิ่งกับ XY-mixers ซึ่งตัวแก้ปัญหารองรับได้โดยตรงในตัว (native)

ตัวอย่างนี้ใช้กราฟ Zachary Karate Club (34 โหนด, 78 ขอบ) และสร้างโมเดลด้วย Luna Model ติดตั้งแพ็กเกจที่จำเป็นหากยังไม่ได้ติดตั้ง:

# %pip install networkx matplotlib luna-model

ขั้นตอนที่ 1: กำหนดปัญหา​

ก่อนอื่น สร้างตัวแปรไบนารีด้วยแพ็กเกจ luna-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()

ขั้นตอนที่ 2: รันตัวแก้ปัญหา​

แก้ปัญหาด้วยตัวแก้ปัญหา

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'

ขั้นตอนที่ 3: ดึงและแสดงผลลัพธ์​

ดึงและแสดงผลลัพธ์

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

บันทึกการเปลี่ยนแปลง​

[0.4.0] - 2026-09-22​

การเปลี่ยนแปลงที่ทำให้เข้ากันไม่ได้

  • เปลี่ยนชื่อพารามิเตอร์อินพุต model เป็น problem
  • เปลี่ยนชื่อฟิลด์เอาต์พุต obj_value เป็น objective_value
  • แทนที่ตัวเลือก postprocessing ด้วย postprocessing_level ซึ่งรับจำนวนเต็มในช่วง [0, 3] แทนสตริง ค่าเดิมแมปดังนี้ "off" -> 0, "weak" -> 1, "medium" -> 2 และ "strong" -> 3 และค่าเริ่มต้นยังคงเป็น 3
  • ปรับโครงสร้าง metadata.circuit_metrics ใหม่ ตอนนี้จะรายงาน num_qubits, gate_count, depth, two_qubit_gate_count, two_qubit_gate_depth และ operations แยกกันสำหรับ before_transpilation และ after_transpilation แทนที่จะเป็น dictionary แบบแบนชุดเดียวที่เก็บจำนวน Gate เฉลี่ย ฟิลด์นี้จะเป็น None เมื่อแก้ปัญหาได้ตั้งแต่ขั้นตอนการประมวลผลล่วงหน้าและไม่มีการรัน Circuit (รหัสข้อผิดพลาด 4712)

ฟีเจอร์

  • เพิ่มตัวเลือก seed_transpiler เพื่อให้การสังเคราะห์และการ routing ของ Circuit ทำซ้ำได้ในทุกการรัน
  • เพิ่มตัวเลือก job_tags เพื่อแนบแท็กของคุณเองไปกับทุก Qiskit Runtime job ที่ฟังก์ชันส่งขึ้นไป
  • เพิ่มฟิลด์เอาต์พุต solution_bitstrings ซึ่งส่งกลับคำตอบชุดเดียวกับ solutions ในรูปแบบ bitstring
  • เพิ่ม metadata.solver_info.variable_mapping ซึ่งแมปชื่อตัวแปรแต่ละตัวไปยังตำแหน่งตัวอักษรในแต่ละรายการของ solution_bitstrings

เอกสารประกอบ

  • เพิ่มเอกสารว่าไม่รองรับตัวแปรต่อเนื่อง (ค่าจำนวนจริง) และตัวแปรจำนวนเต็มต้องมีขอบเขตที่ระบุชัดเจน โมเดลเหล่านี้จะล้มเหลวพร้อมรหัสข้อผิดพลาด 4710

รับการสนับสนุน​

หากมีคำถามหรือปัญหา โปรดติดต่อ support@aqarios.com พร้อมระบุ job ID ของคุณ

ขั้นตอนถัดไป​

คำแนะนำ

เอกสารอ้างอิง​

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