انتقل إلى المحتوى الرئيسي

محلّل التحسين: دالة Qiskit من Q-CTRL Fire Opal

راجع مرجع API

ملاحظة

دوال Qiskit ميزة تجريبية متاحة فقط لمستخدمي IBM Quantum® Premium Plan وFlex Plan وOn-Prem (عبر IBM Quantum Platform API) Plan. هي في مرحلة إصدار معاينة وقابلة للتغيير.

إصدارات الحزم

تم تطوير الكود في هذه الصفحة باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو أحدث.

qiskit-ibm-runtime~=0.46.1
sympy~=1.14.0

نظرة عامة

مع محلّل التحسين Fire Opal، يمكنك حلّ مسائل التحسين على النطاق الاستخدامي على الأجهزة الكمومية دون الحاجة إلى خبرة كمومية. ما عليك سوى إدخال تعريف المسألة رفيع المستوى، ويتولى المحلّل الباقي. سير العمل بالكامل يدرك الضجيج ويستفيد من إدارة أداء Fire Opal في الخلفية. يقدّم المحلّل باستمرار حلولاً دقيقة للمسائل الصعبة كلاسيكيًا، حتى على نطاق الجهاز الكامل لأكبر أجهزة IBM® QPU.

المحلّل مرن ويمكن استخدامه لحلّ مسائل التحسين التوافقية المعرَّفة كدوال هدف أو رسوم بيانية عشوائية. لا يجب ربط المسائل بطبولوجيا الجهاز. المسائل غير المقيدة والمقيدة قابلة للحلّ، بشرط أن تُصاغ القيود كحدود عقوبة. الأمثلة المضمّنة في هذا الدليل توضّح كيفية حلّ مسألة تحسين غير مقيدة ومسألة مقيدة على النطاق الاستخدامي باستخدام أنواع مدخلات مختلفة للمحلّل. المثال الأول يتضمن مسألة max-cut معرَّفة على رسم بياني منتظم ثلاثي 156 عقدة، بينما يعالج المثال الثاني مسألة Minimum Vertex Cover من 50 عقدة معرَّفة بدالة تكلفة.

للحصول على إمكانية الوصول إلى محلّل التحسين، تواصل مع Q-CTRL.

وصف الدالة

يحسّن المحلّل الخوارزمية بالكامل ويؤتمتها، من قمع الأخطاء على مستوى الأجهزة إلى تعيين المسائل بكفاءة والتحسين الكلاسيكي في حلقة مغلقة. خلف الكواليس، تقلّل خطوط أنابيب المحلّل الأخطاء في كل مرحلة، مما يُمكّن الأداء المحسّن المطلوب للتوسع الفعلي. سير العمل الأساسي مستوحى من خوارزمية التحسين الكمومي التقريبي (QAOA)، وهي خوارزمية هجينة كمومية-كلاسيكية. للاطلاع على ملخص تفصيلي لسير عمل محلّل التحسين الكامل، راجع المخطوطة المنشورة.

تصوّر لسير عمل محلّل التحسين

لحلّ مسألة عامة مع محلّل التحسين:

  1. عرِّف مسألتك كدالة هدف، أو رسم بياني، أو سلسلة دوران SparsePauliOp.
  2. اتصل بالدالة عبر كتالوج دوال Qiskit.
  3. شغّل المسألة مع المحلّل واسترجع النتائج.

صيغ المسائل المقبولة

  • تمثيل التعبير متعدد الحدود لدالة هدف. يُنصح بإنشائه في Python بكائن SymPy Poly موجود وتنسيقه كسلسلة نصية باستخدام sympy.srepr.
  • تمثيل رسم بياني لنوع مسألة محدد. يجب إنشاء الرسم البياني باستخدام مكتبة networkx في Python، ثم تحويله إلى سلسلة نصية باستخدام دالة networkx [nx.readwrite.json_graph.adjacency_data](http://nx.readwrite.json_graph.adjacency_data.).
  • تمثيل سلسلة الدوران لمسألة محددة. يجب تمثيل سلسلة الدوران ككائن SparsePauliOp؛ راجع التوثيق لمزيد من التفاصيل.

الخلفيات المدعومة

شغّل الكود التالي لرؤية قائمة الخلفيات المدعومة حاليًا. إذا لم تكن جهازك مدرجًا، تواصل مع Q-CTRL لإضافة الدعم.

# Added by doQumentation — required packages for this notebook
!pip install -q networkx numpy qiskit-ibm-catalog qiskit-ibm-runtime sympy
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

service.backends()
[<IBMBackend('ibm_boston')>,
<IBMBackend('ibm_pittsburgh')>,
<IBMBackend('ibm_fez')>,
<IBMBackend('ibm_marrakesh')>,
<IBMBackend('ibm_kingston')>,
<IBMBackend('ibm_miami')>]
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# Access Function
solver = catalog.load("q-ctrl/optimization-solver")

المعايير المرجعية

تُظهر نتائج المعايير المرجعية المنشورة أن المحلّل ينجح في حلّ مسائل تتجاوز 120 كيوبت، متفوقًا حتى على النتائج المنشورة سابقًا على أجهزة التليين الكمومي والأيونات المحاصرة. مقاييس المعايير المرجعية التالية تعطي مؤشرًا تقريبيًا على دقة أنواع المسائل وقابليتها للتوسع بناءً على بعض الأمثلة. قد تختلف المقاييس الفعلية بناءً على خصائص المسألة المختلفة، مثل عدد الحدود في دالة الهدف (الكثافة) وموقعها، وعدد المتغيرات، والرتبة متعددة الحدود.

"عدد الكيوبتات" المشار إليه ليس حدًا صارمًا بل يمثّل عتبات تقريبية حيث يمكن توقع دقة حلول عالية الاتساق. مسائل أكبر حجمًا تمّ حلّها بنجاح، ويُشجّع الاختبار خارج هذه الحدود.

الاتصالية العشوائية بين الكيوبتات مدعومة عبر جميع أنواع المسائل.

نوع المسألةعدد الكيوبتاتمثالالدقةالوقت الكلي (ث)استخدام وقت التشغيل (ث)عدد التكرارات
مسائل تربيعية متفرقة الاتصال156max-cut ثلاثي منتظم100%176429316
تحسين ثنائي ذو رتبة عليا156نموذج Ising spin-glass100%146127216
مسائل تربيعية كثيفة الاتصال50max-cut متكامل الاتصال100%175826812
مسألة مقيدة بحدود عقوبة50Minimum Vertex Cover موزون بكثافة حواف 8%100%107421510

البدء

أولًا، سجّل الدخول باستخدام مفتاح IBM Quantum API. ثم اختر دالة Qiskit كما يلي. (هذا المقتطف يفترض أنك حفظت حسابك في بيئتك المحلية مسبقًا.)

# %pip install networkx numpy

مثال: تحسين غير مقيد

شغّل مسألة القطع الأقصى (Max-Cut). يوضّح المثال التالي قدرات المحلّل على مسألة Max-Cut لرسم بياني غير موزون منتظم ثلاثي من 156 عقدة، لكن يمكنك أيضًا حلّ مسائل الرسم البياني الموزون. بالإضافة إلى qiskit-ibm-catalog، ستحتاج أيضًا إلى الحزم التالية لتشغيل هذا المثال: networkx وnumpy. يمكنك تثبيت هذه الحزم بإلغاء تعليق الخلية التالية إذا كنت تشغّل هذا المثال في notebook باستخدام نواة IPython.

import networkx as nx
import numpy as np

# Generate a random graph with 156 nodes
maxcut_graph = nx.random_regular_graph(d=3, n=156, seed=8)

1. تعريف المسألة

يمكنك تشغيل مسألة Max-Cut بتعريف مسألة رسم بياني وتحديد problem_type='maxcut'.

# Optionally, visualize the graph
nx.draw_networkx(
maxcut_graph, nx.kamada_kawai_layout(maxcut_graph), node_size=100
)
# Convert graph to string
problem_as_str = nx.readwrite.json_graph.adjacency_data(maxcut_graph)

Output of the previous code cell

يقبل المحلّل سلسلة نصية كمدخل لتعريف المسألة.

# This cell is hidden from users
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend_name = service.least_busy(n_qubits=156).name

2. تشغيل المسألة

عند استخدام طريقة الإدخال القائمة على الرسم البياني، حدّد نوع المسألة.

# Solve the problem
maxcut_job = solver.run(
problem=problem_as_str,
problem_type="maxcut",
backend_name=backend_name, # E.g. "ibm_fez"
)
# Get job status
print(maxcut_job.status())

تحقق من حالة حمل عمل دالة Qiskit أو استرجع النتائج كما يلي:

QUEUED
# Poll for results
maxcut_result = maxcut_job.result()

# Take the absolute value of the solution since the cost function is minimized
qctrl_maxcut = abs(maxcut_result["solution_bitstring_cost"])

# Print the optimal cut value found by the Optimization Solver
print(f"Optimal cut value: {qctrl_maxcut}")

3. استرجاع النتيجة

استرجع قيمة القطع المثلى من قاموس النتائج.

ملاحظة

ربما تغيّر تعيين المتغيرات إلى السلسلة الثنائية. يحتوي قاموس الإخراج على قاموس فرعي variables_to_bitstring_index_map يساعد في التحقق من الترتيب.

Optimal cut value: 210.0
# %pip install numpy networkx sympy

يمكنك التحقق من دقة النتيجة بحلّ المسألة كلاسيكيًا باستخدام محلّلات مفتوحة المصدر مثل PuLP إذا لم يكن الرسم البياني كثيف الاتصال. قد تتطلب مسائل الكثافة العالية محلّلات كلاسيكية متقدمة للتحقق من صحة الحلّ.

مثال: تحسين مقيد

مثال Max-Cut السابق هو مسألة تحسين ثنائي تربيعي غير مقيد شائعة. يمكن استخدام محلّل التحسين من Q-CTRL لأنواع مسائل متعددة، بما في ذلك التحسين المقيد. يمكنك حلّ أنواع مسائل عشوائية بإدخال تعريف المسألة ممثَّلًا كمتعدد حدود حيث تُنمذَج القيود كحدود عقوبة.

يوضّح المثال التالي كيفية بناء دالة تكلفة لمسألة تحسين مقيدة، الغطاء الأدنى للرؤوس (MVC). بالإضافة إلى حزمتي qiskit-ibm-catalog وqiskit، ستحتاج أيضًا إلى الحزم التالية لتشغيل هذا المثال: numpy وnetworkx وsympy. يمكنك تثبيت هذه الحزم بإلغاء تعليق الخلية التالية إذا كنت تشغّل هذا المثال في notebook باستخدام نواة IPython.

import networkx as nx
from sympy import symbols, Poly, srepr

# To change the weights, change the seed to any integer.
rng_seed = 18
_rng = np.random.default_rng(rng_seed)
node_count = 50
edge_probability = 0.08
mvc_graph = nx.erdos_renyi_graph(
node_count, edge_probability, seed=rng_seed, directed=False
)

# add node weights
for i in mvc_graph.nodes:
mvc_graph.add_node(i, weight=_rng.random())

# Optionally, visualize the graph
nx.draw_networkx(mvc_graph, nx.kamada_kawai_layout(mvc_graph), node_size=200)

1. تعريف المسألة

عرِّف مسألة MVC عشوائية بتوليد رسم بياني بعقد موزونة عشوائيًا.

# Construct the cost function.
variables = symbols([f"n[{i}]" for i in range(node_count)])
cost_function = Poly(0, variables)

for i in mvc_graph.nodes():
weight = mvc_graph.nodes[i].get("weight", 0)
cost_function += variables[i] * weight

Output of the previous code cell

يمكن صياغة نموذج التحسين القياسي للـMVC الموزون كما يلي. أولًا، يجب إضافة عقوبة لأي حالة لا تكون فيها حافة متصلة برأس في المجموعة الفرعية. لذا، ليكن ni=1n_i = 1 إذا كان الرأس ii في الغطاء (أي في المجموعة الفرعية) وni=0n_i = 0 في الحالة المعاكسة. ثانيًا، الهدف هو تقليل العدد الكلي للرؤوس في المجموعة الفرعية، ويمكن تمثيله بالدالة التالية:

Minimizey=iVωini\textbf{Minimize}\qquad y = \sum_{i\in V} \omega_i n_i

# Add penalty term.
penalty_constant = 2
for i, j in mvc_graph.edges():
cost_function += penalty_constant * (
1 - variables[i] - variables[j] + variables[i] * variables[j]
)

الآن يجب أن تشمل كل حافة في الرسم البياني على الأقل نقطة نهاية واحدة من الغطاء، ويمكن التعبير عن ذلك بالمتراجحة:

ni+nj1 for all (i,j)En_i + n_j \ge 1 \texttt{ for all } (i,j)\in E

يجب معاقبة أي حالة لا تكون فيها الحافة متصلة برأس من الغطاء. يمكن تمثيل ذلك في دالة التكلفة بإضافة عقوبة من الشكل P(1ninj+ninj)P(1-n_i-n_j+n_i n_j) حيث PP ثابت عقوبة موجب. وبذلك، البديل غير المقيد للمتراجحة المقيدة للـMVC الموزون هو:

Minimizey=iVωini+P((i,j)E(1ninj+ninj))\textbf{Minimize}\qquad y = \sum_{i\in V}\omega_i n_i + P(\sum_{(i,j)\in E}(1 - n_i - n_j + n_i n_j))

# Solve the problem
mvc_job = solver.run(
problem=srepr(cost_function),
backend_name=backend_name, # E.g. "ibm_fez"
)

2. تشغيل المسألة

print(mvc_job.status())

تحقق من حالة حمل عمل دالة Qiskit أو استرجع النتائج كما يلي:

QUEUED

3. الحصول على النتيجة

استرجع الحلّ وحلّل النتائج. بما أن هذه المسألة تحتوي على عقد موزونة، فالحلّ ليس مجرد الحد الأدنى من عدد العقد المغطاة. بدلًا من ذلك، تمثّل تكلفة الحلّ مجموع أوزان الرؤوس المضمّنة في غطاء الرأس. وهي تمثّل "التكلفة" أو "الوزن" الكلي لتغطية جميع الحواف في الرسم البياني باستخدام الرؤوس المختارة.

mvc_result = mvc_job.result()
qctrl_cost = mvc_result["solution_bitstring_cost"]

# Print results
print(f"Solution cost: {qctrl_cost}")
Solution cost: 10.248198273708624

الدعم

لأي أسئلة أو مشكلات، تواصل مع Q-CTRL.

سجل التغييرات

  • 2026-02-11: أصبح لدينا الآن دعم لـibm_miami

الخطوات التالية