Selesaikan model Sherrington-Kirkpatrick dengan ParityQC Parity Twine Optimizer
Anggaran penggunaan: 10 saat pada pemproses Nighthawk r2. (NOTA: Ini hanyalah anggaran. Masa jalan anda mungkin berbeza.)
Hasil pembelajaran
-
Gunakan Parity Twine Optimizer untuk menyelesaikan model Sherrington-Kirkpatrick.
-
Ketahui pilihan yang tersedia untuk Parity Twine Optimizer dan hasil yang dikeluarkan.
Latar belakang
Tutorial ini menunjukkan cara menyelesaikan model Sherrington-Kirkpatrick menggunakan ParityQC Parity Twine Optimizer.
Ia menyediakan kod untuk merumuskan masalah tersebut sepenuhnya secara tempatan dalam bentuk yang boleh berinteraksi dengan Parity Twine Optimizer.
Model Sherrington-Kirkpatrick
Model Sherrington-Kirkpatrick (SK) ialah model asas dalam mekanik statistik, khususnya dalam kajian kaca spin. Berbeza daripada model Ising standard yang interaksinya biasanya terhad kepada jiran terdekat, model SK ialah model julat tak terhingga, bermakna setiap spin berinteraksi dengan setiap spin lain dalam sistem tersebut. Ini membawa kepada landskap tenaga yang sangat kompleks dan "bergerigi" yang dicirikan oleh banyak minimum tempatan, iaitu ciri utama tingkah laku seperti kaca (glassy).
Ciri utama model SK terletak pada frustrasi. Dalam model ini, kekuatan interaksi antara spin diagihkan secara rawak antara nilai positif dan negatif. Ini membawa kepada situasi (contohnya, dalam susunan segi tiga) di mana spin tidak dapat disusun untuk meminimumkan semua interaksi secara serentak. Dalam model SK, kerana setiap spin berinteraksi dengan setiap spin lain, frustrasi ini berganda secara global, membawa kepada jaringan kekangan yang bercanggah.
Rumusan matematik
Keadaan sistem ditakrifkan oleh satu set spin Ising, . Tenaga bagi konfigurasi tertentu diberikan oleh Hamiltonian:
dengan ialah kekuatan gandingan antara spin dan spin .
Dalam model SK, gandingan ialah pemboleh ubah rawak yang tak bersandar dan teragih secara sama. Untuk memastikan tenaga kekal ekstensif (berkadar dengan ) apabila , varians gandingan mesti berskala dengan bilangan zarah:
Keadaan asas bagi yang diberikan ialah konfigurasi spin tertentu (), yang meminimumkan tenaga. Mencari keadaan asas adalah masalah pengoptimuman NP-hard.
Keperluan
Sebelum memulakan tutorial ini, pastikan yang berikut telah dipasang:
-
Qiskit Functions Catalog IBM Client (
pip install qiskit-ibm-catalog) -
Qiskit addon Optimization Mapper (
pip install qiskit_addon_opt_mapper) -
NumPy (
pip install numpy)
Anda juga memerlukan kebenaran untuk mengakses fungsi ParityQC Twine Optimizer. Untuk memohon akses, lengkapkan borang ini.
Persediaan
(Kod ini menganggap anda sudah menyimpan akaun anda ke persekitaran tempatan anda.)
Pertama, import semua pakej yang diperlukan untuk tutorial ini.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "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")
import numpy as np
from qiskit_ibm_catalog import QiskitFunctionsCatalog
Muatkan Parity Twine Optimizer daripada katalog Qiskit Functions:
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
function = catalog.load("parityqc/parity-twine-optimizer")
Langkah 1: Takrifkan masalah sebagai fungsi objektif
Bukannya memperoleh masalah SK daripada pustaka seperti yang kita lakukan untuk masalah Market Split, anda merumuskannya secara terus.
Fungsi generate_sk_problem merumuskan masalah SK secara terus dalam format kamus yang diperlukan. Satu-satunya input yang diperlukan ialah n, iaitu bilangan spin dalam model tersebut.
def generate_sk_problem(
n: int,
coupling_mean: float = 0.0,
coupling_std: float = 1.0,
local_fields_mean: float = 0.0,
local_fields_std: float = 0.0,
edge_density: float = 1.0,
ensure_extensivity: bool = False,
seed: int | None = None,
) -> dict:
"""Generate the Sherrington-Kirkpatrick (SK) model with varying
edge density.
Samples couplings and local fields via ``generate_couplings_sk_model``
and assembles the corresponding Ising Hamiltonian
H = -∑_{i<j} J_ij z_i z_j - ∑_i h_i z_i,
where z_i ∈ {-1, +1}.
Args:
n: Number of spins (>= 2).
coupling_mean: Mean coupling before optional SK scaling.
coupling_std: Coupling std before optional SK scaling.
local_fields_mean: Mean longitudinal field.
local_fields_std: Std of the longitudinal fields.
edge_density: Fraction of non-zero couplings, in ``[2/n, 1]``.
ensure_extensivity: Whether to apply the SK 1/n scaling.
seed: random number generator seed.
Returns:
An encoding the SK Hamiltonian.
Raises:
ValueError: If ``n < 2``, ``coupling_std < 0``, ``local_fields_std < 0``,
or ``edge_density`` is outside ``[2/n, 1]``.
"""
couplings, local_fields = _generate_couplings_sk_model(
n=n,
coupling_mean=coupling_mean,
coupling_std=coupling_std,
local_fields_mean=local_fields_mean,
local_fields_std=local_fields_std,
edge_density=edge_density,
ensure_extensivity=ensure_extensivity,
seed=seed,
)
# Handle quadratic terms: coupling[i, j] * zj[i] * zj[j]
# Only iterate over the upper triangle (i < j)
sk_problem = {
str((i, j)): float(couplings[i, j])
for i in range(n)
for j in range(i + 1, n)
if couplings[i, j] != 0
}
# Handle linear terms: local_fields[i] * zj[i]
sk_problem.update(
{
str((i,)): float(local_fields[i])
for i in range(n)
if local_fields[i] != 0
}
)
return sk_problem
Gunakan fungsi _generate_couplings_sk_model untuk mengira sebutan gandingan rawak dalam model SK. Untuk kawalan lebih terhadap gandingan, anda boleh menggunakan argumen pilihan, yang diterangkan dalam docstring fungsi tersebut.
def _generate_couplings_sk_model(
n: int,
coupling_mean: float = 0.0,
coupling_std: float = 1.0,
local_fields_mean: float = 0.0,
local_fields_std: float = 0.0,
edge_density: float = 1.0,
ensure_extensivity: bool = False,
seed: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""Generate random couplings and local fields for an Ising / SK model.
Couplings are Gaussian. With ``ensure_extensivity=True`` they follow the
Sherrington-Kirkpatrick scaling ``J_ij ~ N(coupling_mean/n, coupling_std^2/n)``
(extensive energy, O(n)); otherwise ``J_ij ~ N(coupling_mean, coupling_std^2)``
(energy O(n^2)). Fields are ``h_i ~ N(local_fields_mean, local_fields_std^2)``.
``edge_density`` sets the fraction of the ``n*(n-1)/2`` possible couplings that
are non-zero (1 = fully dense). The kept edges always include a random spanning
tree, so the interaction graph is guaranteed connected. This requires at least
``n-1`` edges, so ``edge_density`` must be at least ``2/n``.
Args:
n: Number of spins (>= 2).
coupling_mean: Mean coupling before optional SK scaling.
coupling_std: Coupling std before optional SK scaling.
local_fields_mean: Mean longitudinal field.
local_fields_std: Std of the longitudinal fields.
edge_density: Fraction of non-zero couplings, in ``[2/n, 1]``.
ensure_extensivity: Whether to apply the SK 1/n scaling.
seed: random number generator seed.
Returns:
Tuple ``(couplings, fields)``: a symmetric ``(n, n)`` matrix with zero
diagonal, and an ``(n,)`` field vector.
Raises:
ValueError: If ``n < 2``, ``coupling_std < 0``, ``local_fields_std < 0``,
or ``edge_density`` is outside ``[2/n, 1]``.
"""
if n < 2:
raise ValueError(f"n must be >= 2, got {n}")
if coupling_std < 0 or local_fields_std < 0:
raise ValueError(
"coupling_std and local_fields_std must be non-negative"
)
# A connected graph on n nodes needs at least n-1 of the n*(n-1)/2 possible
# edges, so edge_density has a hard lower bound of 2/n.
min_edge_density = 2.0 / n
if not min_edge_density <= edge_density <= 1.0:
raise ValueError(
f"edge_density must be in [{min_edge_density:.4g}, 1] for n={n} "
f"(at least n-1 edges are needed to keep the graph connected), "
f"got {edge_density}"
)
rng = np.random.default_rng(seed)
j_loc, j_scale = (
(coupling_mean / n, coupling_std / np.sqrt(n))
if ensure_extensivity
else (coupling_mean, coupling_std)
)
upper_idx = np.triu_indices(n, k=1)
n_edges = len(upper_idx[0])
# Select which edges are present.
if edge_density < 1.0:
n_keep = int(round(edge_density * n_edges))
# Map each (i, j) node pair to its position in the flat upper-triangle list.
pair_to_flat = {
(int(i), int(j)): idx
for idx, (i, j) in enumerate(
zip(upper_idx[0], upper_idx[1], strict=False)
)
}
# Random spanning tree: node perm[k] links to a random earlier node.
perm = rng.permutation(n)
keep = np.zeros(n_edges, dtype=bool)
for k in range(1, n):
child, parent = perm[k], perm[rng.integers(0, k)]
i, j = min(child, parent), max(child, parent)
keep[pair_to_flat[(int(i), int(j))]] = True
# Fill the remaining budget with random non-tree edges.
remaining = n_keep - (n - 1)
if remaining > 0:
keep[
rng.choice(
np.flatnonzero(~keep), size=remaining, replace=False
)
] = True
else:
keep = np.ones(n_edges, dtype=bool)
n_present = int(keep.sum())
if j_scale == 0.0:
vals = np.full(n_present, j_loc)
else:
vals = rng.normal(loc=j_loc, scale=j_scale, size=n_present)
couplings = np.zeros((n, n))
couplings[upper_idx[0][keep], upper_idx[1][keep]] = vals
couplings += couplings.T # symmetrize; diagonal stays zero
fields = (
np.full(n, local_fields_mean)
if local_fields_std == 0.0
else rng.normal(loc=local_fields_mean, scale=local_fields_std, size=n)
)
return couplings, fields
Langkah 2: Selesaikan masalah menggunakan Parity Twine Optimizer
Dengan fungsi di atas, anda boleh menyediakan masalah SK dan mencari penyelesaian dengan menggunakan Twine Optimizer dan backend IBM Quantum® pilihan.
Untuk menjalankan fungsi, pilih backend yang sesuai; contohnya, ibm_phoenix.
Jika perlu, gunakan options (pilihan) untuk kawalan tambahan terhadap penghantaran:
options = {
"shots": 100000,
"postprocessing_level": 1,
"transpile_only": False,
"job_tags": ["sk"],
}
dengan shots ialah integer yang menentukan bilangan pelaksanaan litar, postprocessing_level menentukan sama ada pasca-pemprosesan digunakan pada hasil,
transpile_only memilih sama ada masalah hanya ditranspilasi kepada litar (dan tidak diselesaikan), dan job_tags ialah label untuk mengenal pasti job pada IBM Quantum Platform.
Saiz model SK ditakrifkan oleh , bilangan spin yang berinteraksi. Setelah anda memilih , kod di atas menjana masalah untuk n_spins.
Jalankan pengoptimum:
n_spins = 50
sk_problem = generate_sk_problem(n_spins)
function_job = function.run(
problem=sk_problem,
variable_type="spin",
backend_name="ibm_phoenix",
options=options,
)
print(f"Job ID: {function_job.job_id}")
Semak status job:
# Monitor the job status
function_job.status()
Dapatkan hasil:
result = function_job.result()
result
Hasilnya berbentuk:
{
'solution': {'0': 1, '1': 1, '10': 1, '11': 1, ... },
'objective_value': -240.5425312543882,
'solution_bitstring': '00001101110100100111001110101001101111111011001110',
'metadata': {
'circuit_metrics': {
'depth': 523,
'gate_count': 10118,
'two_qubit_gate_depth': 196,
'two_qubit_gate_count': 2499,
'num_qubits': 50,
'operations': {'sx': 3353, 'rz': 3320, 'cz': 2499, 'delay': 894, 'measure': 50, 'x': 2},
},
'solver_info': {
'variable_mapping': {'0': 0, '1': 1, '10': 2, '11': 3, ... },
'bitstring_distributions': {
'before_postprocessing': {'011101110010110111001110011000': 1, ... },
'after_postprocessing': {'011011110000110101001111011000': 1, ... }
},
'best_parameters': {
'beta': [-0.4602084830507902],
'gamma': [1.8500357096574955]
}
},
'resource_usage': {
'RUNNING: MAPPING': {'CPU_TIME': 290.272},
'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 0.494},
'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 8.775},
'RUNNING: EXECUTING_QPU': {'QPU_TIME': 31.0},
'RUNNING: POST_PROCESSING': {'CPU_TIME': 162.96},
},
}
}
dengan kamus solution sepadan dengan qubit yang ditakrifkan dalam masalah dan memberikan nilai spin yang dioptimumkan bagi Hamiltonian model SK.
Jujukan spin tertentu ini dalam penyelesaian optimum mewakili konfigurasi yang meminimumkan jumlah tenaga sistem berdasarkan kekuatan interaksi rawak yang diberikan.
Dalam model SK, ini boleh dianggap sebagai keadaan tenaga terendah bagi sistem magnet yang tidak teratur.
metadata memberikan maklumat tentang transpilasi (bilangan/kedalaman gate dua qubit, gate yang digunakan, qubit aktif) dan pelbagai masa jalan.
Langkah seterusnya
- Minta akses kepada fungsi ini dengan melengkapkan borang ini.
- Lawati rujukan API untuk Qiskit Function ini.
- Baca panduan.
- Cuba tutorial untuk menggunakan Parity Twine Optimizer pada masalah Market Split.
- Semak prapencetakan ArXiv Connectivity-aware Synthesis of Quantum Algorithms, Drier et al. (2025).