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

SQOA Solver - Qiskit Function โดย JIJ

ดู API reference

หมายเหตุ

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

ภาพรวม​

ด้วย SQOA Solver โดย JIJ คุณสามารถแก้ปัญหา combinatorial optimization ขนาดใหญ่บนคอมพิวเตอร์ควอนตัม IBM® ได้ ตัวแก้นี้อิงตาม Sampling-based Quantum Optimization Algorithm with Quantum Relaxation (SQOA-QR) [1] ต่างจากอัลกอริทึมควอนตัมที่ใช้การจับคู่แบบหนึ่งต่อหนึ่งระหว่างตัวแปรตัดสินใจแบบคลาสสิกกับ qubit SQOA Solver สามารถจัดการปัญหา optimization ที่มีตัวแปรมากกว่าจำนวน qubit ที่มีอยู่บนอุปกรณ์ควอนตัมปัจจุบันได้ การออกแบบที่อิงการสุ่มตัวอย่างยังทำให้ไวต่อสัญญาณรบกวนทางกายภาพบนฮาร์ดแวร์ควอนตัมปัจจุบันน้อยลงด้วย คุณสมบัติเหล่านี้ทำให้ SQOA Solver เหมาะกับปัญหา optimization ในช่วงนี้ของการประมวลผลควอนตัม

ตัวแก้นี้จัดการปัญหา Quadratic Unconstrained Binary Optimization (QUBO) ที่ให้มาในรูปสูตรทางคณิตศาสตร์แบบคลาสสิก และแมปสูตรแบบคลาสสิกไปยังบริบทควอนตัมให้อัตโนมัติ คุณยังแปลงปัญหาที่มีข้อจำกัดให้เป็นปัญหาที่ไม่มีข้อจำกัดได้โดยใช้ penalty method

ส่วนต่อไปนี้อธิบาย workflow ของตัวแก้ ผลการ benchmark และตัวอย่างแบบ end-to-end ที่สร้างแบบจำลองปัญหาด้วย qiskit-addon-opt-mapper และอาจใช้ Open Mathematical prograMming eXchange (OMMX) ด้วย OMMX เป็นรูปแบบข้อมูลเปิดและ SDK ที่ช่วยให้แลกเปลี่ยนปัญหา optimization ระหว่างเครื่องมือซอฟต์แวร์ได้ง่ายขึ้น

คำอธิบาย​

SQOA Solver ใช้งาน Sampling-based Quantum Optimization Algorithm with Quantum Relaxation (SQOA-QR) และล้อมด้วยการประมวลผลก่อนและหลังแบบคลาสสิก ส่วนนี้อธิบายเฟรมเวิร์ก SQOA และความแตกต่างจาก Quantum Approximate Optimization Algorithm (QAOA)

ภาพต่อไปนี้แสดงแผนภาพของ workflow ของ SQOA Solver แผนภาพ workflow ของ SQOA Solver ตั้งแต่การประมวลผลก่อนแบบคลาสสิก ผ่านการสุ่มตัวอย่าง SQOA ไปจนถึงการประมวลผลหลังและ local search

เฟรมเวิร์ก SQOA​

SQOA เป็นเฟรมเวิร์กที่อิงการสุ่มตัวอย่างสำหรับ combinatorial optimization [1] โดยรวมสองเทคนิคเข้าด้วยกัน คือ Quantum Random Access Optimization (QRAO) [2] ซึ่งเข้ารหัสปัญหาใน quantum relaxation และ sample-based quantum diagonalization (SQD) [3] หรือที่เรียกว่า quantum-selected configuration interaction (QSCI) [4] ซึ่งใช้คอมพิวเตอร์ควอนตัมเพียงเพื่อสุ่มตัวอย่าง bitstring และหา state พลังงานต่ำบนคอมพิวเตอร์คลาสสิก SQOA เป็นเฟรมเวิร์กในความหมายที่ว่ากำหนดการรวมนี้ไว้ แต่ปล่อยรายละเอียดให้แต่ละการใช้งานเลือกเอง เช่น วิธีกำหนดตัวแปรให้กับ qubit และ circuit ใดที่สร้างตัวอย่าง

  • Quantum relaxation ด้วย QRAO QAOA และแนวทางอิง Ising อื่น ๆ แทนตัวแปรไบนารีแต่ละตัวด้วยตัวดำเนินการ ZZ ของ qubit ของมัน ส่วน QRAO ใช้ตัวดำเนินการ XX และ YY ด้วย เมื่อใช้ (3,1) quantum random access code (QRAC) ตัวแปรไบนารีได้สูงสุดสามตัวใช้ qubit เดียวร่วมกัน และแต่ละตัวแปรแทนด้วยตัวดำเนินการ Pauli ที่ต่างกัน

    QUBO จะกลายเป็น relaxed Hamiltonian ที่ต้องการ qubit น้อยกว่า Ising Hamiltonian ตัวแปรที่มีปฏิสัมพันธ์กันใน QUBO ต้องวางไว้บน qubit คนละตัว หากใช้ qubit ร่วมกัน ผลคูณของตัวดำเนินการ Pauli ของพวกมันจะลดรูปเหลือตัวดำเนินการเดียวบน qubit นั้น (เช่น XY=iZXY = iZ) และ relaxed Hamiltonian จะไม่แสดงปฏิสัมพันธ์ของพวกมันอีกต่อไป

    ดังนั้นการกำหนดตัวแปรให้กับ qubit จึงเป็นตัวกำหนดทั้งจำนวน qubit และคุณภาพของ relaxation และ SQOA Solver ออกแบบการกำหนดนี้ในขั้นตอนประมวลผลก่อน

  • Sample-based quantum diagonalization (SQD) ขั้นแรกคอมพิวเตอร์ควอนตัมเตรียม quantum state ที่ซ้อนทับกับ state พลังงานต่ำของ relaxed Hamiltonian แล้วสุ่มตัวอย่าง bitstring จากมัน จากนั้นคอมพิวเตอร์คลาสสิกฉาย relaxed Hamiltonian ลงบน subspace ที่ขึงด้วย bitstring ที่สุ่มได้ และทำ diagonalization เพื่อประมาณ ground state

    เนื่องจาก relaxed Hamiltonian ไม่เป็นแนวทแยง การทำ diagonalization จึงรวม bitstring ที่สุ่มได้เป็น superposition ส่วนกับ Ising Hamiltonian แบบทแยง ทุก bitstring เป็น eigenstate อยู่แล้ว และ diagonalization จะเลือกได้เพียงตัวอย่างที่ดีที่สุดเท่านั้น แนวทางเดียวกันนี้เคยถูกใช้กับปัญหาขนาดใหญ่ในเคมีควอนตัม

ground state โดยประมาณที่ได้จาก SQD ไม่สอดคล้องกับคำตอบแบบคลาสสิกของปัญหาเดิมโดยตรง จึงต้องถอดรหัสคำตอบแบบคลาสสิกจากมัน เนื่องจาก state นี้คำนวณบนคอมพิวเตอร์คลาสสิก การถอดรหัสที่เรียกว่า rounding จึงเป็นการประมวลผลหลังแบบคลาสสิก SQOA Solver ใช้เทคนิคถอดรหัสที่ออกแบบมาเพื่อให้ได้คำตอบแบบคลาสสิกที่ดีขึ้นด้วยวิธี heuristic

ตารางต่อไปนี้เปรียบเทียบ SQOA กับ QAOA ซึ่งเป็นแนวทาง variational ทั่วไปสำหรับปัญหาประเภทเดียวกัน

 QAOASQOA
qubit สำหรับตัวแปรไบนารี nn ตัวnnqubit หนึ่งตัวเก็บตัวแปรได้สูงสุดสามตัว จำนวนที่แน่นอนขึ้นอยู่กับโครงสร้างของปัญหา
การใช้ QPUประมาณค่าพลังงานของ circuit ที่มีพารามิเตอร์ซ้ำ ๆ ภายในลูป optimization แบบคลาสสิกสุ่มตัวอย่าง bitstring เท่านั้น ไม่มีการฝึกพารามิเตอร์ของ circuit บน QPU
จากตัวอย่างสู่คำตอบเลือก bitstring ที่วัดได้ดีที่สุดทำ diagonalization ของ relaxed Hamiltonian ใน subspace ที่สุ่มได้บนคอมพิวเตอร์คลาสสิก แล้ว round state ที่ได้

รอบ ๆ SQOA-QR นั้น SQOA Solver เพิ่มการประมวลผลแบบคลาสสิก ขั้นประมวลผลก่อนจะตรึงตัวแปรที่หาค่าเหมาะสมที่สุดได้ล่วงหน้า และออกแบบการกำหนดตัวแปรให้กับ qubit ส่วนขั้นประมวลผลหลังจะปรับปรุงคำตอบที่ round แล้วด้วย local search ซึ่งคุณปิดได้ด้วย postprocessing_level=0

Benchmarks​

ข้อสงวนสิทธิ์

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

ตัวชี้วัด benchmark ต่อไปนี้ให้ภาพรวมของคุณภาพคำตอบ การบีบอัด qubit และเวลาในการรันของปัญหาขนาดและโครงสร้างที่เลือกมา ตารางแสดง Maximum Independent Set instances บางส่วนจาก Quantum Optimization Benchmarking Library (QOBLIB) และ instance MaxCut แบบ 3-regular สองรายการ คุณสามารถโหลด instance ของ QOBLIB เป็นออบเจกต์ ommx.v1.Instance พร้อมคำตอบที่เหมาะสมที่สุดได้โดยใช้แพ็กเกจ ommx-quantum-benchmarks

แต่ละ instance รัน 10 ครั้งบนโปรเซสเซอร์ IBM Heron r2 Number of qubits นับ qubit ที่ใช้จริงบนฮาร์ดแวร์หลังการประมวลผลก่อนและการเข้ารหัส QRAC อัตราการบีบอัดขึ้นอยู่กับแต่ละ instance Approximation ratio (AR) รายงานคุณภาพของคำตอบที่ดีที่สุดที่พบจากการรัน 10 ครั้ง:

AR=CbestCopt,\mathrm{AR} = \frac{C_{\textrm{best}}}{C_{\textrm{opt}}},

โดยที่ CbestC_{\textrm{best}} คือค่า objective ที่ดีที่สุดที่พบ และ CoptC_{\textrm{opt}} คือค่า objective ที่เหมาะสมที่สุดที่ทราบ ทุก instance เป็นปัญหา maximization ที่มีค่าเหมาะสมที่สุดเป็นบวก ดังนั้น AR จึงไม่เกิน 100% และ 100% ในคอลัมน์ Approximation ratio หมายความว่าตัวแก้พบคำตอบที่เหมาะสมที่สุด Total time คือเวลา QPU และ CPU รวมเฉลี่ยต่อการรัน QPU time คือการใช้งาน IBM Quantum Compute เฉลี่ยต่อการรัน

Instanceจำนวนตัวแปรจำนวน qubitApproximation ratioเวลารวม (วินาที)เวลา QPU (วินาที)
maxcut_384_nodes38412998.5%62.112.0
gen200_p0-9_4420067100%38.012.0
es60fst0218642100%24.712.0
es60fst0416229100%17.912.0
maxcut_150_nodes15051100%23.112.0
sloane_1dc_1281283793.8%19.112.0
sloane_2dc_1281288100%12.311.5
C125-912543100%22.312.0
es60fst0112312100%13.612.0
es60fst0311326100%14.912.0
sloane_1dc_646416100%13.411.9
chesapeake3913100%13.112.0
football356100%12.512.0
karate342100%6.26.0
ibm323211100%12.912.0
farm174100%8.58.0

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

ดูข้อมูลการเข้าถึง Qiskit Function นี้ได้ใน Qiskit Functions Catalog

ส่วนนี้แสดงวิธียืนยันตัวตนและโหลด function รวมถึงวิธีเตรียมปัญหาในรูปแบบ dictionary ที่ SQOA Solver รับ โดยใช้ OptimizationProblem จาก qiskit-addon-opt-mapper ตัวอย่างที่ตามมาจะรัน function และอ่านผลลัพธ์

ยืนยันตัวตนและโหลด function​

ก่อนอื่น ให้ยืนยันตัวตนด้วย IBM Quantum API key ของคุณ (โค้ดต่อไปนี้สมมติว่าคุณบันทึกบัญชีของคุณไว้ในสภาพแวดล้อมในเครื่องแล้ว) จากนั้นสร้าง catalog client ดังนี้

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

_needed = {"jijmodeling": "jijmodeling", "networkx": "networkx", "ommx": "ommx", "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(jij/sqoa-solver)]
solver = catalog.load("jij/sqoa-solver")

เตรียม input ด้วย qiskit-addon-opt-mapper​

คู่มือนี้สร้างแบบจำลองปัญหาด้วยคลาส OptimizationProblem ของ qiskit-addon-opt-mapper SQOA Solver รับปัญหา QUBO เป็น coefficient dictionary ในรูปแบบ tuple-string ที่ฟังก์ชัน optimization ของ IBM ใช้ ดังนั้นทุกตัวอย่างในคู่มือนี้จึงทำตามรูปแบบการเตรียมฝั่ง client เดียวกัน:

  1. เขียนแบบจำลอง สร้าง OptimizationProblem เพิ่มตัวแปรตัดสินใจแบบไบนารี และกำหนด objective และข้อจำกัดใด ๆ

  2. แปลงเป็น QUBO แปลงปัญหาด้วย OptimizationProblemToQubo ซึ่งเพิ่มข้อจำกัดใด ๆ เข้าไปใน objective เป็นเทอม penalty และคืนปัญหา minimization ที่ไม่มีข้อจำกัดซึ่งเทียบเท่ากัน

  3. แปลงเป็น dictionary ส่ง QUBO ให้ฟังก์ชันช่วย to_problem_dict() ที่นิยามไว้ในส่วนถัดไป แล้วส่งผลลัพธ์ให้ solver.run() เป็น problem พร้อมกับ variable_type="binary"

SQOA Solver ทำ minimization กับปัญหาแบบ dictionary เสมอ ซึ่งตรงกับปัญหา minimization ที่ OptimizationProblemToQubo คืนมา ดังนั้นสำหรับปัญหา maximization ค่า objective_value ที่คืนมาจึงเป็นค่าลบของ objective เดิม หากต้องการอ่านผลลัพธ์ในรูปของปัญหาเดิม ให้ประเมินการกำหนดค่าที่คืนมาด้วย OptimizationProblem ตามที่ตัวอย่างแสดง สำหรับรายละเอียดของรูปแบบ dictionary ดู Accepted problem formats ใน API reference

# %pip install qiskit-addon-opt-mapper

ให้นิยามฟังก์ชันช่วยต่อไปนี้ครั้งเดียวแล้วนำกลับมาใช้ในทุกตัวอย่าง ฟังก์ชันนี้แปลง QUBO ที่ OptimizationProblemToQubo คืนมาเป็นรูปแบบ dictionary key ใช้ดัชนีตัวแปรของ QUBO ดังนั้น key ของคำตอบ x_0, x_1 และต่อ ๆ ไปในผลลัพธ์จึงสอดคล้องกับดัชนีเหล่านั้น ทุกตัวแปรจะได้รายการเชิงเส้น แม้สัมประสิทธิ์เป็นศูนย์ เพื่อให้คำตอบที่คืนมาครอบคลุมทุกตัวแปร

from qiskit_addon_opt_mapper import OptimizationProblem
from qiskit_addon_opt_mapper.converters import OptimizationProblemToQubo

def to_problem_dict(qubo: OptimizationProblem) -> dict[str, float]:
"""Convert a QUBO from OptimizationProblemToQubo to the SQOA Solver dictionary format."""
objective = qubo.objective
payload = {"()": objective.constant}
# Keep every variable in the problem, even with a zero linear coefficient.
payload.update({f"({i},)": 0.0 for i in range(qubo.get_num_vars())})
for i, coefficient in objective.linear.to_dict().items():
payload[f"({i},)"] += coefficient
for (i, j), coefficient in objective.quadratic.to_dict().items():
# Fold a binary diagonal term x_i * x_i = x_i into the linear term.
key = f"({i},)" if i == j else f"({i}, {j})"
payload[key] = payload.get(key, 0.0) + coefficient
return {key: float(value) for key, value in payload.items()}

ตัวอย่างที่ 1: MaxCut บนกราฟ 3-regular​

ปัญหากราฟจำนวนมาก เช่น MaxCut เป็น NP-hard และเป็นตัวเลือกที่เหมาะสมสำหรับ quantum optimization ติดตั้ง networkx เป็น dependency เพิ่มเติมเพื่อรันตัวอย่างนี้:

# %pip install networkx

1. เขียนแบบจำลอง​

กำหนดตัวแปรไบนารี xv∈{0,1}x_v \in \{0, 1\} ให้แต่ละจุดยอดของกราฟ G=(V,E)G = (V, E) เพื่อบอกว่าอยู่ฝั่งใดของการตัด เส้นเชื่อมถูกตัดเมื่อจุดปลายทั้งสองอยู่คนละฝั่ง ดังนั้นขนาดของการตัดคือ:

Cut(x)=∑(u,v)∈E(xu+xv−2xuxv).\mathrm{Cut}(x) = \sum_{(u,v) \in E} \left(x_u + x_v - 2 x_u x_v\right).

objective นี้เป็น QUBO ที่ไม่มีข้อจำกัดอยู่แล้ว ดังนั้น OptimizationProblemToQubo จึงเพียงเปลี่ยน maximization เป็น minimization ที่เทียบเท่า และคงตัวแปรไว้เหมือนเดิม คลาสแอปพลิเคชัน Maxcut ใน qiskit_addon_opt_mapper.applications สร้างแบบจำลองเดียวกันได้ด้วย Maxcut(G).to_optimization_problem()

import networkx as nx

G = nx.random_regular_graph(3, 40, seed=42)

linear = {v: 0 for v in G.nodes}
quadratic = {}
for u, v in G.edges:
linear[u] += 1
linear[v] += 1
quadratic[(u, v)] = -2

maxcut = OptimizationProblem("MaxCut")
maxcut.binary_var_list(G.number_of_nodes(), name="x")
maxcut.maximize(linear=linear, quadratic=quadratic)

2. รันตัวแก้​

แปลงแบบจำลองเป็น QUBO แล้วเป็น dictionary จากนั้นส่งเข้าไป problem และ variable_type จำเป็นต้องระบุ ส่วน backend_name ไม่บังคับ เมื่อไม่ระบุหรือเป็น None function จะเลือก QPU ที่พร้อมใช้งานและคิวว่างที่สุดซึ่งมีให้ instance ของคุณ

dictionary options รับ shots, seed, session, postprocessing_level และ job_tags สำหรับคำอธิบายและค่าเริ่มต้น ดู API reference

qubo = OptimizationProblemToQubo().convert(maxcut)

job = solver.run(
problem=to_problem_dict(qubo),
variable_type="binary",
backend_name="ibm_fez",
options={
"shots": 4096,
"seed": 42,
},
)

3. ดึงผลลัพธ์​

job.result() คืน dictionary ที่มีสี่ key:

  • solution คือการกำหนดค่าตัวแปรทั้งหมด โดยใช้ key เป็น x_i ซึ่ง i คือดัชนีตัวแปร (เช่น x_3)

  • objective_value และ feasible คือ objective และความเป็นไปได้ของการกำหนดค่านั้น โดยประเมินบน dictionary ที่ส่งเข้าไป

  • metadata เก็บ solver_info และ resource_usage

เนื่องจาก QUBO เป็นรูปแบบ minimization ของ MaxCut ค่า objective_value จึงเป็นค่าลบของขนาดการตัด ให้ประเมินการกำหนดค่าบน OptimizationProblem ดั้งเดิมเพื่ออ่านขนาดการตัดโดยตรง

result = job.result()

x = [result["solution"][f"x_{i}"] for i in range(maxcut.get_num_vars())]
print(f"Cut value: {maxcut.objective.evaluate(x)}")
print(f"Nodes on side 1: {[v for v, value in enumerate(x) if value > 0.5]}")
Cut value: 55.0
Nodes on side 1: [5, 7, 9, 11, 14, 16, 17, 19, 21, 23, 24, 26, 30, 31, 33, 34, 36, 37, 38]

4. ตรวจสอบการใช้ทรัพยากร​

result["metadata"]["resource_usage"] รายงานเวลาที่ใช้ในแต่ละเฟสของการทำงาน เฟสอื่นนอกจาก RUNNING: EXECUTING_QPU รายงาน CPU_TIME ซึ่งเป็นเวลาจริงของเฟสเป็นวินาที เมื่อมีข้อมูล

เฟส RUNNING: EXECUTING_QPU รายงาน QPU_TIME ซึ่งเป็นการใช้ QPU ของ Quantum Compute job ทั้งหมดในการรัน หากมีข้อมูลการใช้งานสุดท้ายของทุก job สำหรับรายละเอียด ดู API reference

for phase, metrics in result["metadata"]["resource_usage"].items():
line = f"{phase:36s}"
if "CPU_TIME" in metrics:
line += f" CPU {metrics['CPU_TIME']:8.1f} s"
if "QPU_TIME" in metrics:
line += f" QPU {metrics['QPU_TIME']:8.1f} s"
print(line)
RUNNING: MAPPING CPU 3.2 s
RUNNING: OPTIMIZING_FOR_HARDWARE CPU 5.0 s
RUNNING: WAITING_FOR_QPU CPU 1.1 s
RUNNING: EXECUTING_QPU QPU 3.0 s
RUNNING: POST_PROCESSING CPU 0.9 s

ตัวอย่างที่ 2: แปลงปัญหาที่มีข้อจำกัดเป็น QUBO​

SQOA Solver รับปัญหาที่ไม่มีข้อจำกัด ตัวอย่างนี้แสดงวิธีแปลงปัญหาที่มีข้อจำกัดเป็น QUBO ด้วย OptimizationProblemToQubo และแมปผลลัพธ์กลับไปยังตัวแปรของปัญหาเดิม

selection = OptimizationProblem("ConstrainedExample")
selection.binary_var_list(2, name="x")
selection.maximize(linear={"x0": 1, "x1": 1})
selection.linear_constraint({"x0": 1, "x1": 1}, "<=", 1, name="at_most_one")

print(selection.prettyprint())
Problem name: ConstrainedExample

Maximize
x0 + x1

Subject to
Linear constraints (1)
x0 + x1 <= 1 'at_most_one'

Binary variables (2)
x0 x1

OptimizationProblemToQubo เพิ่มข้อจำกัดเข้าไปใน objective เป็นเทอม penalty และแปลงปัญหาเป็น minimization น้ำหนัก penalty ที่เหมาะสมขึ้นอยู่กับปัญหา

หลังการรัน interpret() จะแมปการกำหนดค่า QUBO กลับไปยังตัวแปรของปัญหาเดิม

ประเมิน objective และความเป็นไปได้บนปัญหาเดิม สำหรับปัญหาแบบ dictionary ฟิลด์ feasible ของผลลัพธ์อ้างถึงเฉพาะโดเมนของตัวแปรเท่านั้น เพราะ dictionary ไม่มีข้อจำกัด

converter = OptimizationProblemToQubo(penalty=4.0)
qubo = converter.convert(selection)

job = solver.run(
problem=to_problem_dict(qubo),
variable_type="binary",
backend_name="ibm_fez",
)
result = job.result()

x_qubo = [result["solution"][f"x_{i}"] for i in range(qubo.get_num_vars())]
x = converter.interpret(x_qubo)
print("Objective:", selection.objective.evaluate(x))
print("Feasible:", selection.is_feasible(x))
print("x values:", x)
Objective: 1.0
Feasible: True
x values: [1. 0.]

ตัวอย่างที่ 3: ส่ง OMMX instance​

SQOA Solver ยังรับ ommx.v1.Instance จาก SDK OMMX ซึ่งเก็บชื่อตัวแปร subscript และ metadata การแปลงไว้ด้วยกันกับปัญหา เมื่อเทียบกับ dictionary แล้ว input แบบ OMMX มีข้อดีดังนี้:

  • ผลลัพธ์ยังมี ommx.v1.Solution มาตรฐานอยู่ใน solver_info["ommx_solution"] ด้วย

  • objective_value ถูกประเมินตามความหมายของ instance ดังนั้น objective ของปัญหา maximization จึงไม่ถูกเปลี่ยนเป็นค่าลบ

  • สำหรับ instance ที่แปลงในที่เดิมด้วย Instance.to_qubo() ค่า feasible จะถูกประเมินเทียบกับข้อจำกัดเดิม

ตัวอย่างนี้สร้างแบบจำลอง MaxCut จากตัวอย่างที่ 1 ด้วย JijModeling ซึ่งเป็นเครื่องมือสร้างแบบจำลอง mathematical optimization ที่คอมไพล์แบบจำลองเป็น OMMX instance ติดตั้ง JijModeling ซึ่งจะติดตั้งแพ็กเกจ ommx ด้วย:

# %pip install "jijmodeling~=2.8.0"

SQOA Solver แลกเปลี่ยนข้อมูล OMMX เป็นสตริง Base64 แบบมาตรฐานที่มี padding นิยามฟังก์ชันช่วยต่อไปนี้สำหรับการแปลงนี้:

  • to_problem_payload() แปลง ommx.v1.Instance เป็นสตริงที่คุณส่งเป็น problem

  • to_ommx_solution() ถอดรหัส ommx.v1.Solution มาตรฐานจากผลลัพธ์

import base64

from ommx.v1 import Instance, Solution

def to_problem_payload(instance: Instance) -> str:
"""Serialize an OMMX instance into the `problem` string for SQOA Solver."""
return base64.b64encode(instance.to_bytes()).decode()

def to_ommx_solution(result: dict) -> Solution:
"""Decode the canonical OMMX solution from a SQOA Solver result."""
payload = result["metadata"]["solver_info"]["ommx_solution"]
return Solution.from_bytes(base64.b64decode(payload, validate=True))

1. เขียนแบบจำลองด้วย JijModeling​

สูตรปกติแบบ spin ของ MaxCut บนกราฟ G=(V,E)G = (V, E) กำหนด sv∈{−1,+1}s_v \in \{-1, +1\} ให้แต่ละจุดยอด เส้นเชื่อมถูกตัดเมื่อ susv=−1s_u s_v = -1 ดังนั้นขนาดของการตัดคือ:

Cut⁡(s)=∑(u,v)∈E1−susv2.\operatorname{Cut}(s) = \sum_{(u,v) \in E} \frac{1 - s_u s_v}{2}.

JijModeling ไม่มีตัวแปรตัดสินใจแบบ spin โดยตรง และ SQOA Solver รับตัวแปร QUBO แบบไบนารี ดังนั้นให้ประกาศ bv∈{0,1}b_v \in \{0, 1\} และนิยามนิพจน์ค่า spin sv=1−2bvs_v = 1 - 2b_v ภายในแบบจำลอง ด้วยนิพจน์นี้ objective จะคงอยู่ในรูป spin มาตรฐาน และ instance ที่คอมไพล์แล้วยังคงเป็น QUBO แบบไบนารี

import jijmodeling as jm

@jm.Problem.define("MaxCut", sense=jm.ProblemSense.MAXIMIZE)
def maxcut_model(problem: jm.DecoratedProblem):
V = problem.Natural() # number of nodes
E = problem.Graph(dtype=V) # edge list
b = problem.BinaryVar(shape=(V,))
s = 1 - 2 * b # spin-valued expression

problem += jm.sum((1 - s[u] * s[v]) / 2 for u, v in E)

หากคุณแสดง maxcut_model ใน notebook จะเห็นสูตรดังนี้:

Problem ⁣:MaxCutmax⁡∑⟨u,v⟩∈E1−(1−2⋅b)u⋅(1−2⋅b)v2whereDecision Variables:bi∈{0,1}a 1-dim array of binary decision variables∀i∈{0,…,V−1}Placeholders:Ei∈V×Va 1-dim array of placeholders with elements in V×V∀i∈{0,…,len_at(E,0)−1}V∈Na scalar placeholder in N\begin{array}{rl} \text{Problem}\colon &\text{MaxCut}\\ \displaystyle \max &\displaystyle \sum _{\left\langle u,v\right\rangle \in E}{\frac{1-{\left(1-2\cdot b\right)}_{u}\cdot {\left(1-2\cdot b\right)}_{v}}{2}}\\ &\\ \text{where}&\\ &\text{Decision Variables:}\\ &\qquad \begin{alignedat}{2}{b}_{i}&\in \left\{0,1\right\}&\qquad &\text{a }1\text{-dim array of }\text{binary}\text{ decision variables}\\ &\forall i\in \left\{0,\ldots ,V-1\right\}&&\\ \end{alignedat}\\ &\\ &\text{Placeholders:}\\ &\qquad \begin{alignedat}{2}{E}_{i}&\in V\times V&\qquad &\text{a }1\text{-dim array of placeholders with elements in }V\times V\\ &\forall i\in \left\{0,\ldots ,\mathop{\mathtt{len\_{}at}}\left(E,0\right)-1\right\}&&\\ &&&\\ V&\in \mathbb{N}&\qquad &\text{a scalar placeholder in }\mathbb{N}\\ \end{alignedat}\end{array}

2. คอมไพล์ instance และรันตัวแก้​

ผูกกราฟจากตัวอย่างที่ 1 เพื่อคอมไพล์เป็น ommx.v1.Instance แล้วส่งด้วย variable_type="binary" OMMX instance จะถูกส่งเป็นปัญหาแบบไบนารีเสมอ

instance = maxcut_model.eval(
{"V": G.number_of_nodes(), "E": [list(edge) for edge in G.edges]}
)

job = solver.run(
problem=to_problem_payload(instance),
variable_type="binary",
backend_name="ibm_fez",
)

3. ดึงผลลัพธ์​

สำหรับ input แบบ OMMX ค่า objective_value คือขนาดการตัด และ to_ommx_solution() ถอดรหัสคำตอบมาตรฐานเพื่อให้คุณอ่านการกำหนดค่าตามชื่อตัวแปรได้

result = job.result()
print(f"Cut value: {result['objective_value']}")

solution = to_ommx_solution(result)
b_values = solution.extract_decision_variables("b")
print(
f"Nodes on side 1: {sorted(v for (v,), value in b_values.items() if value > 0.5)}"
)
Cut value: 55.0
Nodes on side 1: [5, 7, 9, 11, 14, 16, 17, 19, 21, 23, 24, 26, 30, 31, 33, 34, 36, 37, 38]

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

หากต้องการการสนับสนุน ส่งอีเมลไปที่ info@j-ij.com

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

คำแนะนำ
  • ขอทดลองใช้ SQOA Solver ฟรีโดยกรอกแบบฟอร์มนี้
  • ดู API reference ของ Qiskit Function นี้
  • ลองตัวอย่างแบบ end-to-end ใน tutorial maximum independent set problem
  • เรียนรู้วิธีสร้างแบบจำลองปัญหา optimization ด้วย qiskit-addon-opt-mapper
  • เรียนรู้วิธีสร้างแบบจำลองและแลกเปลี่ยนปัญหา optimization ด้วย JijModeling และ OMMX
  • อ่านบทความ SQOA-QR [1] เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับเฟรมเวิร์ก SQOA

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

[1] Matsuyama, H., & Yamashiro, Y. (2025). Sampling-based quantum optimization algorithm with quantum relaxation. 2025 IEEE International Conference on Quantum Computing and Engineering (QCE), 1, 2323–2333. DOI, arXiv:2504.12629

[2] Fuller, B., Hadfield, C., Glick, J. R., Imamichi, T., Itoko, T., Thompson, R. J., Jiao, Y., Kagele, M. M., Blom-Schieber, A. W., Raymond, R., et al. (2024). Approximate solutions of combinatorial problems via quantum relaxations. IEEE Transactions on Quantum Engineering, 5, 1–15. DOI, arXiv:2111.03167

[3] Robledo-Moreno, J., Motta, M., Haas, H., Javadi-Abhari, A., Jurcevic, P., Kirby, W., et al. (2025). Chemistry beyond the scale of exact diagonalization on a quantum-centric supercomputer. Science Advances, 11(25), eadu9991. DOI, arXiv:2405.05068

[4] Kanno, K., Kohda, M., Imai, R., Koh, S., Mitarai, K., Mizukami, W., & Nakagawa, Y. O. (2026). Quantum-selected configuration interaction: Classical diagonalization of Hamiltonians in subspaces selected by quantum computers. Physical Review Research, 8(2), 023268. DOI, arXiv:2302.11320