0-1 背包问题在量子退火机上的简单实现

本文配置

• Windows 10
• Python==3.8.5
• dwave-ocean-sdk==3.1.1

\$ dwave setup

Optionally install non-open-source packages and configure your environment.

Do you want to select non-open-source packages to install (y/n)? [y]:

D-Wave Drivers
These drivers enable some automated performance-tuning features.
This package is available under the 'D-Wave EULA' license.
The terms of the license are available online: https://docs.ocean.dwavesys.com/eula
Install (y/n)? [y]:
Installing: D-Wave Drivers
Successfully installed D-Wave Drivers.

D-Wave Problem Inspector
This tool visualizes problems submitted to the quantum computer and the results returned.
This package is available under the 'D-Wave EULA' license.
The terms of the license are available online: https://docs.ocean.dwavesys.com/eula
Install (y/n)? [y]:
Installing: D-Wave Problem Inspector
Successfully installed D-Wave Problem Inspector.

Creating the D-Wave configuration file.
Confirm configuration file path [/home/someone/.config/dwave/dwave.conf]:
Profile (create new) [prod]:
API endpoint URL [skip]:
Authentication token [skip]: ABC-1234567890abcdef1234567890abcdef
Default client class (qpu or sw) [qpu]:
Default solver [skip]:
Configuration saved.

基本概念

背包问题

$$Max~~~Cost(X) = \sum^{N}_{i = 1} c_i x_i \\ s.t. ~~~~~ Weight(X) = \sum^{N}_{i=1} w_i x_i \leq W$$

问题模型

• 布尔值变量（或者值域类似于{0, 1}只能取两个值的变量）
• 目标函数是 quadratic 的，也就是支持 $$x^2, x_i x_j, x$$

• 无约束

D-Wave 的库实际上还可以使用 Ising 模型和 QUBO（Quadratic Unconstrained Binary Optimization），都可以转化为 BQM，区别是表达方式。

$$BQM: E(v) = \sum_{i=1}a_iv_i+\sum_{i<j} b_{i,j}v_iv_j+c, \\ where~~~~v_i \in \{−1,+1\}\ or\ \{0,1\} \\ QUBO: E(v) = \sum_{i\leq j} Q_{i,j}x_ix_j,~~~x_i \in \{0,1\} \\ Ising: E(v) = \sum_{i=1}h_is_i+\sum_{i<j}J_{i,j}s_is_j,~~~s_i \in \{−1,+1\}\\$$

转化

$$H = H_A + H_B \\ H_A = A(1 - \sum^{W}_{k=1} y_k)^2 + A(\sum^{W}_{k=1} k y_k - \sum_{i} w_ix_i)^2 \\ H_B = -B\sum_{i} c_ix_i$$

$$k_i = 2^i,~i \in [0, M-1] \\ k_{M} = W - (2^M - 1) \\$$

$$H_A = A(\sum_{i} k_i y_i - \sum_{i} w_ix_i)^2 \\ H_B = -B\sum_{i} c_ix_i$$

$$H = A \ H'\\ H' = \sum_{i=1}^{N} (w_i^2 - c_i) x_i + 2\sum_{i=1}^{N}\sum_{j=i+1}^{N} w_i w_j x_i x_j \\ - 2\sum_{i=1}^{N}\sum_{j=0}^{M}w_i k_j x_i y_j \\ + \sum_{j=0}^{M}k_i^2 y_i + 2 \sum_{i=0}^{M}\sum_{j=i+1}^{M} k_i k_j y_i y_j$$

实现

# passed on 2020.12.11
from dwave.system import LeapHybridSampler
from math import log2, floor
import dimod

# 0-1 背包问题原型
W = 70
N = 7
c = [35, 85, 30, 50, 70, 80, 55]
w = [12, 27, 11, 17, 20, 10, 15]

# 其他变量
A = max(c)
M = floor(log2(W))
k = [2**i for i in range(M)] + [W + 1 - 2**M]

# BQM

# x 项
for i in range(N):
bqm.set_linear('x' + str(i), A * (w[i]**2) - c[i])

# x-x 项
for i in range(N):
for j in range(i + 1, N):
key = ('x' + str(i), 'x' + str(j))
bqm.quadratic[key] = 2 * A * w[i] * w[j]

# x-y 项
for i in range(N):
for j in range(M + 1):
key = ('x' + str(i), 'y' + str(j))
bqm.quadratic[key] = -2 * A * w[i] * k[j]

# y 项
for i in range(M + 1):
bqm.set_linear('y' + str(i), A * (k[i]**2))

# y-y 项
for i in range(M + 1):
for j in range(i + 1, M + 1):
key = ('y' + str(i), 'y' + str(j))
bqm.quadratic[key] = 2 * A * k[i] * k[j]

# 求解
sampler = LeapHybridSampler()
sampleset = sampler.sample(bqm)
sample = sampleset.first.sample
energy = sampleset.first.energy

# 哪些物品被选中了
selected = []
for varname, value in sample.items():
if value and varname.startswith('x'): # x*
selected.append(int(varname[1:]))
selected = sorted(selected)

weight_sum = 0
cost_sum = 0
for i in selected:
weight_sum += w[i]
cost_sum += c[i]

print('能量：', energy)
print('被选中的物品：', selected)
print('总质量：', weight_sum)
print('总价值：', cost_sum)

能量： -270.0

67 声望
5 粉丝
0 条评论