やりたいこと
wildqat(http://mdrft.com/wildqat/ )を使って高校数学を解きたかったけど、無理だったので中学数学にします。
問
f(x) = x^2 - 3x
の最小値とその時のxの値を求めよ。
中学数学的な解
\begin{align}
f(x) &= x^2 - 3x\\
&= \left(x-\frac{3}{2}\right)^2-\frac{9}{4}
\end{align}
となるので、(グラフを書いて)$x=\frac{3}{2}$のとき、最小値$-\frac{9}{4}$
wildqatで求めた解(コード)
import wildqat as wq
import numpy as np
a = wq.opt()
a.qubo = np.zeros((4,4))
A = [2,1,1/2,1/4]
B = -3 * np.diag(A)
A_sqr = wq.sqr(A)
a.qubo += A_sqr + B
a.sa()
> [0,1,1,0]
a.E[-1]
> -2.25
解説
解説するまでもないかもしれませんが…
まずかなり恣意的ですが、
x = 2x_1 + x_2 + \frac{1}{2}x_3 + \frac{1}{4}x_4
と置きます。このように置くことで、 $ 0 < x \leqq 3.75$だと言えます。
これを $ 0 \leqq x \leqq 4 $に近づけたいときは
x = 2x_1 + x_2 + \frac{1}{2^1}x_3 + \frac{1}{2^2}x_4 + \frac{1}{2^3}x_5+\cdots
と$\frac{1}{2^n}$の項をどんどん増やして行けば良いですね。
$x$の最大値を増やしたいときは、逆に$x$を$4x_1$からはじめたり、$8x_1$からはじめたりしたら良いですね。
脱線しましたがもとに戻りまして、上のようにおいた$x$を$f(x)$に代入すればQUBO行列が求まりますね。
$x^2$の計算が面倒ですが、これはwildqat.sqr()を使えば楽に計算できます。
これがA_sqr = wq.sqr(A)に該当します。
$-3x$の部分はQUBO行列の対角成分のみに関与するもので、B = -3 * np.diag(A)に該当します。
以上を使って解いてみると(a.sa())、
x = \frac{1}{2}+\frac{1}{4} = \frac{3}{4}
であることがわかりました。このときに取る最小値はa.E[-1]を使えばわかります(a.E[-1]はコスト関数が最終的に収束した値)。
これが-2.25でしたので、以上より
$x=\frac{3}{4}$のとき、最小値$-\frac{9}{4}$をとることがわかりました。
流石にもうちょっと文量増やしたい
ので追記します。