第1回: アニーリング基礎1. 荷物の分担

- Aさん、Bさんの二人が、それぞれ重さ$w$が異なる$N$個の荷物を出来るだけ均等に分配する。但し、それぞれの荷物には持ちにくさ$D$があり、持ちにくさを考慮した上で、出来るだけ荷物を均等に分配する問題を、Dwaveのアニーリングマシンを用いて解く。<br>

**参考**：[東北大学大関先生講義 第2回](https://altema.is.tohoku.ac.jp/QA4U/) <br>
***Keyword*** ：*Dwave基本設定*、*Pyquboの使い方*、*罰則法*

### 1. 基本準備/設定
#### 1.1 準備1:量子アニーリング用モジュールのインストール
まず、初めに、以下のモジュールをインストールする。
- ***dwave-ocean-sdk***: Dwaveアニーリングマシンのモジュール
- ***openjij***: アニーリングシュミレーター
- ***pyqubo***: Qubo行列作成サポートモジュール

``` Python
pip install dwave-ocean-sdk
pip install openjij
pip install pyqubo
```
#### 1.2 準備2: Dwaveの初期設定
続いて、Dwaveのtoken、enpoint(アクセスURL)、使用するマシンの指定を行う。実際には、関数として数値を指定するだけ。後で、Dwaveにアクセスする際に、上記の関数を指定することになる。

``` Python
token = "DEV-73ac79954ef2135*************************"
endpoint = "https://cloud.dwavesys.com/sapi/"
solver = "Advantage_system4.1"
```
更に、Dwaveマシンを指定するDwaveSamplerと、Qbitへの割り当て行うEmbeddingCompositeをインポートする

``` Python
from dwave.system import DWaveSampler, EmbeddingComposite
```

続いて、インポートしたDWaveSamplerを用いてDwaveマシンを指定する。

``` Python
dw_sampler = DWaveSampler(solver=solver, token=token, endpoint = endpoint)
```

尚、使用するマシンの指定方法を含むDwaveの使用方法は、Qiitaの記事を参考：https://qiita.com/y_daito/items/aad74517927e393564ee

#### 1.3 準備3: 各種モジュールのインポート
openjijから**SQASampler**、pyquboから**Array**、その他として**numpy**、**pandas**、**matplotlib.pyplot**をインポートする。

``` Python
from openjij import SQASampler
from pyqubo import Array
import pandas as pd
```
### 2. 定式化
#### 2.1 エネルギー式の整理

今回の問題は、重さ$w$がそれぞれ異なる$N$個の荷物をAさんとBさんの二人に可能な限り均等に分担する。均等であるとは、AさんとBさんの総重量がイコールになれば良いということ。**アニーリングのエネルギー式は二次関数である必要がある。**<br>
そこで、Aさんの重量を$W_A$、Bさんの重量を$W_B$とすると、エネルギー式$E(x)$を以下のように出来る。
``` math
E(x) =(W_A - W_B)^2
```

続いて、**アニーリング問題は、場合分けが0 or 1のスピンで規定されないといけない。**<br>そこで、$i$番目の荷物をAさんがとる場合、$x_i=1$とし、Aさんがとらない場合、つまりBさんがとる場合を$x_i=0$とする。<br>
続いて、それぞれの荷物の重さを$w_i$とする。<br>
すると、Aさんの荷物の重量は以下となる。<br>
``` math
W_A = \sum_{i=1}^N w_i x_i
```
一方で、全ての荷物の重量$W$は以下となる。
``` math
W = \sum_{i=1}^N w_i
```
ここで、$W_B$を$∑$で表現することも可能だが、$x_i$がAが荷物を持つかどうかの判断となっている為、新たに$x_i$を設定する必要があり面倒。そこで、$W$、$W_A$だけで、$E(x)$を表現してみる。
``` math
E(x) = (W_A - W_B)^2 \\
E(x) = (2W_A - W)^2 \\
``` 
ここで、$W_A$のみ$∑$で表記してみる。尚、$W$は定数なので$∑$を使用せず、$W$のまま記載する。
``` math
E(x) = (2\sum_{i=1}^N w_i x_i - W)^2 \\
``` 
続いて、これを展開する。**$∑$の添え字はべき乗する場合、同じ添え字を使用せず、別の添え字に変更する。**
``` math
E(x) = (2\sum_{i=1}^N w_i x_i - W)(2\sum_{j=1}^N w_j x_j - W) \\
E(x) = 4\sum_{i=1}^N \sum_{j=1}^N w_i w_j x_i x_j - 4 W\sum_{i=1}^N w_i x_i + W^2 
``` 
尚、上記第二項は本来添え字が$i$と$j$で別れるが、いずれも独立している為、$i$でも$j$でも同じ、Aさんの総重量を示す。従い、$i$でまとめている。

#### 2.2 コスト関数の整理

**更に問題を複雑にする為に、夫々の荷物の組み合わせ事に、持ちにくさ$D_{ij}$を定義する。** ここでの添え字$i、j$は、例えば1番目と2番目などと分けることが目的。尚、$i$番目と$i$番目の荷物を同時に持つことは無いので、$D_{ii}$という場合は存在しない。<Br>
ここでコスト関数$C_1(x)$を整理すると以下となる。
``` math
C_1(x) = \sum_{i=1}^N \sum_{j=1, i≠j}^N D_{ij} x_i x_j
``` 
#### 2.3 ハミルトニアンの作成

上記で整理したエネルギー式とコスト関数を足し合わせることでハミルトニアンを作成する。尚、コスト関数は、結果見ながら影響度合いを検討せざるを得ない。影響度を$α_1$と定義した場合、ハミルトニアンは以下となる。
``` math
H(x) = E(x) + α_1 C_1(x) \\
H(x) = 4\sum_{i=1}^N \sum_{j=1}^N w_i w_j x_i x_j - 4 W\sum_{i=1}^N w_i x_i + W^2 + α_1\sum_{i=1}^N \sum_{j=1, i≠j}^N D_{ij} x_i x_j
``` 
数式の整理は以上。<Br>
以降、数式の実装を進める。

### 3. 実装
#### 3.1 問題の設定
今回分担する荷物$N$が10個とした場合。夫々の重さ$w_i$、夫々の持ちにくさ$D_{ij}$、またコスト関数の影響度$α_1$を以下の通り設定する。
``` Python
N = 10
w = [1,2,3,4,5,6,7,8,9,10]
W = sum(w)
D = []
for i in range(1,N+1):
  _a = [i*x for x in w]
  _a[i-1] = 0
  D.append(_a)
a1 = 0
```
#### 3.2 Pyquboを使用せず直接的にQubo行列を表現する場合
まず始めにQubo行列を格納する箱を作成する。$N$行x$N$行の正方行列である。
``` Python
Qubo = np.zeros(N**2).reshape(N,N)
Qubo
```
```
<Output> 
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]
```
Qubo行列の箱に、以下の数式の各項の結果を入力していく。
``` math
H(x) = 4\sum_{i=1}^N \sum_{j=1}^N w_i w_j x_i x_j - 4 W\sum_{i=1}^N w_i x_i + W^2 + α_1\sum_{i=1}^N \sum_{j=1, i≠j}^N D_{ij} x_i x_j
``` 
まず、第1項から、表現する。$x_i$、$x_j$以外をそのまま代入すれば良い。
``` Python
for i in range(N):
  for j in range(N):
    Qubo[i][j] = 4 * w[i] * w[j]
Qubo
```

```
<Output>
array([[  4.,   8.,  12.,  16.,  20.,  24.,  28.,  32.,  36.,  40.],
       [  8.,  16.,  24.,  32.,  40.,  48.,  56.,  64.,  72.,  80.],
       [ 12.,  24.,  36.,  48.,  60.,  72.,  84.,  96., 108., 120.],
       [ 16.,  32.,  48.,  64.,  80.,  96., 112., 128., 144., 160.],
       [ 20.,  40.,  60.,  80., 100., 120., 140., 160., 180., 200.],
       [ 24.,  48.,  72.,  96., 120., 144., 168., 192., 216., 240.],
       [ 28.,  56.,  84., 112., 140., 168., 196., 224., 252., 280.],
       [ 32.,  64.,  96., 128., 160., 192., 224., 256., 288., 320.],
       [ 36.,  72., 108., 144., 180., 216., 252., 288., 324., 360.],
       [ 40.,  80., 120., 160., 200., 240., 280., 320., 360., 400.]])
```
続いて、第2項。
``` Python
for i in range(N):
  Qubo[i][i] = Qubo[i][i] - 4*W*w[i]
Qubo  
```
```
<Output>
array([[ -216.,     8.,    12.,    16.,    20.,    24.,    28.,    32.,
           36.,    40.],
       [    8.,  -424.,    24.,    32.,    40.,    48.,    56.,    64.,
           72.,    80.],
       [   12.,    24.,  -624.,    48.,    60.,    72.,    84.,    96.,
          108.,   120.],
       [   16.,    32.,    48.,  -816.,    80.,    96.,   112.,   128.,
          144.,   160.],
       [   20.,    40.,    60.,    80., -1000.,   120.,   140.,   160.,
          180.,   200.],
       [   24.,    48.,    72.,    96.,   120., -1176.,   168.,   192.,
          216.,   240.],
       [   28.,    56.,    84.,   112.,   140.,   168., -1344.,   224.,
          252.,   280.],
       [   32.,    64.,    96.,   128.,   160.,   192.,   224., -1504.,
          288.,   320.],
       [   36.,    72.,   108.,   144.,   180.,   216.,   252.,   288.,
        -1656.,   360.],
       [   40.,    80.,   120.,   160.,   200.,   240.,   280.,   320.,
          360., -1800.]])
```
次に、第3項であるが、ここには$x_i$も$x_j$も出てこないので、Qubo行列には影響を与えない。従い、作業無。

最後に、第4項のコスト関数。
``` Python for i in range(N):
  for j in range(N):
    if not i == j:
      Qubo[i][j] = Qubo[i][j] + a1*D[i][j]
Qubo
```
``` 
array([[ -216.,     8.,    12.,    16.,    20.,    24.,    28.,    32.,
           36.,    40.],
       [    8.,  -424.,    24.,    32.,    40.,    48.,    56.,    64.,
           72.,    80.],
       [   12.,    24.,  -624.,    48.,    60.,    72.,    84.,    96.,
          108.,   120.],
       [   16.,    32.,    48.,  -816.,    80.,    96.,   112.,   128.,
          144.,   160.],
       [   20.,    40.,    60.,    80., -1000.,   120.,   140.,   160.,
          180.,   200.],
       [   24.,    48.,    72.,    96.,   120., -1176.,   168.,   192.,
          216.,   240.],
       [   28.,    56.,    84.,   112.,   140.,   168., -1344.,   224.,
          252.,   280.],
       [   32.,    64.,    96.,   128.,   160.,   192.,   224., -1504.,
          288.,   320.],
       [   36.,    72.,   108.,   144.,   180.,   216.,   252.,   288.,
        -1656.,   360.],
       [   40.,    80.,   120.,   160.,   200.,   240.,   280.,   320.,
          360., -1800.]])
```
以上でQubo行列の作成は完了。
最後に、DwaveマシンにQubo行列を投げてQubo行列を最小化する$x_i$の組み合わせを抽出する。

``` Python
sampler_dw = EmbeddingComposite(dw_sampler)
solution = sampler_dw.sample_qubo(Qubo, num_reads=10)
print(solution.record)
```
```
<Output>
[([0, 0, 0, 1, 0, 1, 0, 1, 0, 1], -3024., 1, 0.)
 ([1, 0, 1, 1, 0, 0, 0, 0, 1, 1], -3024., 2, 0.)
 ([1, 0, 0, 0, 0, 0, 1, 0, 1, 1], -3024., 1, 0.)
 ([1, 0, 1, 0, 0, 1, 0, 1, 0, 1], -3024., 1, 0.)
 ([1, 0, 0, 1, 0, 1, 1, 0, 0, 1], -3024., 1, 0.)
 ([0, 1, 0, 1, 0, 1, 0, 1, 1, 0], -3016., 1, 0.)
 ([0, 0, 0, 1, 1, 0, 1, 0, 0, 1], -3016., 1, 0.)
 ([0, 1, 0, 0, 1, 0, 0, 1, 1, 0], -2976., 1, 0.)
 ([1, 0, 0, 1, 0, 0, 0, 0, 1, 1], -2976., 1, 0.)]
```
1番目、2番目、3番目の場合でのAさんの重量、Bさんの重量を表現すると以下の通り。
``` Python
for i in range(5):
  wa = np.dot(solution.record[i][0],w)
  wb = W-wa
  print(f"{i+1}番目の結果：Aさんの総重量は{wa}、Bさんの総重量は{wb}")
```
```
1番目の結果：Aさんの総重量は28、Bさんの総重量は27
2番目の結果：Aさんの総重量は27、Bさんの総重量は28
3番目の結果：Aさんの総重量は27、Bさんの総重量は28
4番目の結果：Aさんの総重量は28、Bさんの総重量は27
5番目の結果：Aさんの総重量は28、Bさんの総重量は27
```
#### 3.3 Pyquboを使用してQubo行列を表現する場合
Pyquboを使用する場合、以下の数式の$x_i$の集合であるベクトル$\vec{x}$を定義することから始まる。
``` math
H(x) = (2\sum_{i=1}^N w_i x_i - W)^2 +  α_1\sum_{i=1}^N \sum_{j=1, i≠j}^N D_{ij} x_i x_j \\
H(x) = 4\sum_{i=1}^N \sum_{j=1}^N w_i w_j x_i x_j - 4 W\sum_{i=1}^N w_i x_i + W^2 + α_1\sum_{i=1}^N \sum_{j=1, i≠j}^N D_{ij} x_i x_j
```
``` Python
from pyqubo import Array
x = Array.create(name="x", shape=(N),vartype="BINARY")
```
```
<Output>
Array([Binary('x[0]'), Binary('x[1]'), Binary('x[2]'), Binary('x[3]'), Binary('x[4]'), Binary('x[5]'), Binary('x[6]'), Binary('x[7]'), Binary('x[8]'), Binary('x[9]')])
```
PyquboのArrayでは、0 or 1のバイナリ変数、-1 or +1のイジング変数のいずれかが選択できる。vartypeで"BINARY"or"SPIN"を選択する。

Pyquboを使用する場合、直接Qubo行列を作成するのでなく、上記の$H(x)$を先ほど定義した$\vec{x}$を用いて、数式自体を表現する。出来上がった数式からQubo行列を抜き出すという手順になる。**Pyquboの最大の利点は展開せずとも計算出来る点**であるが、展開しても使用可能。まずは、展開した場合で計算を行う。

以下のように一挙に表現する。
``` Python
### まずハミトルニアンを準備する。
H=0

### 第1項の表現
for i in range(N):
  for j in range(N):
    H = H + 4*w[i]*w[j]*x[i]*x[j]

### 第2項の表現
for i in range(N):
  H = H - 4*W*w[i]*x[i]

### 第3項の表現
H = H + W**2

### 第4項の表現
for i in range(N):
  for j in range(N):
    if not i == j:
      H = H + a1*D[i][j]*x[i]*x[j]
```
$H(x)$の作成が完了すれば、以下の方法でQubo行列のみを抽出する。
``` Python
sampler_dw = EmbeddingComposite(dw_sampler)
solution = sampler_dw.sample_qubo(Qubo, num_reads=10)
print(solution.record)
for i in range(5):
  wa = np.dot(solution.record[i][0],w)
  wb = W-wa
  print(f"{i+1}番目の結果：Aさんの総重量は{wa}、Bさんの総重量は{wb}")
```
```
[([0, 0, 1, 0, 0, 1, 0, 1, 0, 1], -3024., 1, 0. )
 ([1, 0, 1, 1, 1, 1, 0, 0, 0, 1], -3016., 1, 0. )
 ([1, 0, 0, 0, 1, 1, 1, 0, 0, 1], -3016., 1, 0. )
 ([1, 1, 1, 0, 0, 1, 1, 0, 0, 1], -3016., 1, 0. )
 ([1, 0, 0, 0, 0, 0, 1, 1, 1, 0], -3000., 1, 0. )
 ([0, 0, 1, 0, 1, 0, 1, 0, 0, 1], -3000., 1, 0. )
 ([1, 1, 0, 0, 1, 1, 1, 1, 0, 0], -3016., 1, 0.1)
 ([0, 1, 0, 1, 0, 1, 0, 0, 0, 1], -2904., 1, 0. )
 ([1, 1, 0, 0, 0, 1, 1, 0, 1, 1], -2800., 1, 0.1)
 ([0, 1, 1, 1, 0, 0, 0, 0, 0, 1], -2736., 1, 0. )]
1番目の結果：Aさんの総重量は27、Bさんの総重量は28
2番目の結果：Aさんの総重量は29、Bさんの総重量は26
3番目の結果：Aさんの総重量は29、Bさんの総重量は26
4番目の結果：Aさんの総重量は29、Bさんの総重量は26
5番目の結果：Aさんの総重量は25、Bさんの総重量は30
```
続いて、数式を展開しない場合で$H(x)$を表現してみる。
``` Python
### まずハミトルニアンを準備する。
H = 0

### 第1項の表現
H = (2*np.dot(w,x)-W)**2

### 第2項の表現
for i in range(N):
  for j in range(N):
    if not i == j:
      H = H + a1*D[i][j]*x[i]*x[j]
```
続いて、Qubo行列を抽出。
``` Python
model = H.compile()
Qubo, offset = model.to_qubo()
print(Qubo)
```
```
<Output>
{('x[6]', 'x[0]'): 56.0, ('x[6]', 'x[6]'): -1344.0, ('x[7]', 'x[6]'): 448.0, ('x[5]', 'x[0]'): 48.0, ('x[5]', 'x[1]'): 96.0, ('x[8]', 'x[3]'): 288.0, ('x[3]', 'x[3]'): -816.0, ('x[7]', 'x[2]'): 192.0, ('x[9]', 'x[3]'): 320.0, ('x[9]', 'x[1]'): 160.0, ('x[9]', 'x[9]'): -1800.0, ('x[9]', 'x[2]'): 240.0, ('x[5]', 'x[4]'): 240.0, ('x[4]', 'x[1]'): 80.0, ('x[1]', 'x[1]'): -424.0, ('x[2]', 'x[2]'): -624.0, ('x[5]', 'x[3]'): 192.0, ('x[7]', 'x[5]'): 384.0, ('x[4]', 'x[3]'): 160.0, ('x[6]', 'x[1]'): 112.0, ('x[4]', 'x[4]'): -1000.0, ('x[8]', 'x[5]'): 432.0, ('x[1]', 'x[0]'): 16.0, ('x[8]', 'x[2]'): 216.0, ('x[7]', 'x[3]'): 256.0, ('x[8]', 'x[8]'): -1656.0, ('x[2]', 'x[1]'): 48.0, ('x[7]', 'x[0]'): 64.0, ('x[3]', 'x[2]'): 96.0, ('x[6]', 'x[2]'): 168.0, ('x[8]', 'x[7]'): 576.0, ('x[7]', 'x[4]'): 320.0, ('x[6]', 'x[3]'): 224.0, ('x[4]', 'x[2]'): 120.0, ('x[7]', 'x[7]'): -1504.0, ('x[0]', 'x[0]'): -216.0, ('x[9]', 'x[6]'): 560.0, ('x[8]', 'x[6]'): 504.0, ('x[6]', 'x[5]'): 336.0, ('x[2]', 'x[0]'): 24.0, ('x[8]', 'x[1]'): 144.0, ('x[4]', 'x[0]'): 40.0, ('x[9]', 'x[8]'): 720.0, ('x[9]', 'x[0]'): 80.0, ('x[9]', 'x[4]'): 400.0, ('x[5]', 'x[2]'): 144.0, ('x[6]', 'x[4]'): 280.0, ('x[9]', 'x[5]'): 480.0, ('x[8]', 'x[0]'): 72.0, ('x[3]', 'x[0]'): 32.0, ('x[3]', 'x[1]'): 64.0, ('x[7]', 'x[1]'): 128.0, ('x[5]', 'x[5]'): -1176.0, ('x[9]', 'x[7]'): 640.0, ('x[8]', 'x[4]'): 360.0}
```
同じく、Dwaveで解いてみると。
``` Python
sampler_dw = EmbeddingComposite(dw_sampler)
solution = sampler_dw.sample_qubo(Qubo, num_reads=10)
print(solution.record)
for i in range(5):
  wa = np.dot(solution.record[i][0],w)
  wb = W-wa
  print(f"{i+1}番目の結果：Aさんの総重量は{wa}、Bさんの総重量は{wb}")
```
```
[([1, 0, 1, 1, 1, 1, 0, 1, 0, 0], -3024., 1, 0. )
 ([0, 1, 0, 1, 0, 1, 1, 1, 0, 0], -3024., 1, 0. )
 ([0, 1, 0, 1, 1, 0, 0, 1, 1, 0], -3024., 1, 0. )
 ([1, 0, 0, 1, 0, 1, 1, 1, 0, 0], -3016., 1, 0. )
 ([1, 1, 0, 1, 0, 0, 0, 0, 1, 1], -3016., 1, 0. )
 ([1, 0, 0, 1, 1, 0, 1, 1, 0, 0], -3000., 1, 0. )
 ([1, 1, 0, 0, 1, 0, 1, 0, 0, 1], -3000., 1, 0. )
 ([1, 1, 0, 1, 1, 1, 1, 0, 0, 0], -3000., 1, 0. )
 ([0, 0, 0, 0, 0, 0, 0, 1, 1, 0], -2584., 1, 0. )
 ([0, 0, 0, 1, 1, 1, 1, 0, 1, 0], -2976., 1, 0.1)]
1番目の結果：Aさんの総重量は27、Bさんの総重量は28
2番目の結果：Aさんの総重量は27、Bさんの総重量は28
3番目の結果：Aさんの総重量は28、Bさんの総重量は27
4番目の結果：Aさんの総重量は26、Bさんの総重量は29
5番目の結果：Aさんの総重量は26、Bさんの総重量は29
```
これまでと同様の回答が得られた。PyQuboを使用することで、展開せずにハミルトニアンを表現できる為、数学的にプログラミングが容易になる。

#### 3.4 Openjijシュミレーターを使用する場合

参考まで、アニーリングシュミレーターを使用した場合のプログラミング流れを整理する。

``` Python
### シュミレーターの呼び出し
sampler_jij = SQASampler()

### 計算の実施
solution = sampler_jij.sample_qubo(Qubo,num_reads=10)
print(solution.record)

### 結果の表示
for i in range(5):
  wa = np.dot(solution.record[i][0],w)
  wb = W-wa
  print(f"{i+1}番目の結果：Aさんの総重量は{wa}、Bさんの総重量は{wb}")
```
```
[([0, 0, 0, 0, 1, 1, 1, 0, 0, 1], -3024., 1)
 ([1, 0, 1, 0, 0, 1, 0, 1, 1, 0], -3024., 1)
 ([0, 1, 1, 1, 1, 0, 1, 1, 0, 0], -3016., 1)
 ([1, 1, 1, 1, 0, 0, 0, 1, 1, 0], -3024., 1)
 ([0, 0, 1, 0, 0, 0, 1, 1, 1, 0], -3024., 1)
 ([1, 0, 0, 0, 0, 1, 1, 0, 1, 0], -2944., 1)
 ([1, 1, 1, 1, 0, 0, 0, 1, 0, 1], -3024., 1)
 ([0, 0, 1, 0, 1, 0, 0, 0, 1, 1], -3024., 1)
 ([0, 0, 0, 0, 1, 1, 1, 0, 1, 0], -3024., 1)
 ([0, 1, 0, 0, 0, 0, 1, 1, 0, 1], -3024., 1)]
1番目の結果：Aさんの総重量は28、Bさんの総重量は27
2番目の結果：Aさんの総重量は27、Bさんの総重量は28
3番目の結果：Aさんの総重量は29、Bさんの総重量は26
4番目の結果：Aさんの総重量は27、Bさんの総重量は28
5番目の結果：Aさんの総重量は27、Bさんの総重量は28
```
計算精度は、アニーリング実機と比較して低下するが、作成したQubo行列が機能しているか堂かの検証を無償で実施出来る。

### おわりに
今回はアニーリングによる最適化の一番の基礎を整理した。アニーリングは0 or 1しか選択できない為、$x_i$の0はAさんが持たない、1はAさんが持つ、と表現した。しかし、これではAさん、Bさんの二人の場合しか表現できない。それでは、Aさん、Bさん、Cさんと増えてきた場合、つまり**ハミルトニアンが2次式以上になる場合**、どのように$x_i$を設定すべきか、考えないといけない。<br>

**今後の課題**: *ハミルトニアンが2次式以上になる場合の対応*