QUBO モデル + 2023 mathorcup コンテストの質問 A

いくつかの名詞

イジングモデル、イジングモデル

QUBO モデル、二次無制約バイナリ最適化、二次無制約バイナリ最適化モデル

  • スピン変数の定義域空間の値は ですIsing空间。つまり、定義域空間は{ − 1 , 1 } \{-1,1\}です。{ 1 1 }

  • バイナリ変数の場合、そのドメイン空間の値は です布尔空间。つまり、ドメイン空間は{ 0 , 1 } \{0,1\}です。{ 0 ,1 }

HOBO、高次バイナリ最適化、高次バイナリ最適化問題

組み合わせ最適化問題、組み合わせ最適化 (Combinatorial Optimization、CO)

二次無制約バイナリ最適化 (QUBO) モデル

論文参照:量子ブリッジ分析 I: QUBO モデルの定式化と使用に関するチュートリアル | SpringerLink

多くの組み合わせ最適化問題はモデルとして再定式化できQUBOペナルティ関数を使用する非常に自然な方法で、さまざまなタイプの制約関係を「制約なし」定式化で具体化できますQUBOではQUBO、ペナルティ関数を使用すると、より正確なモデル表現を生成できます(この文はよく理解できませんでしたので、翻訳しました)。

QUBO モデルは NP 困難問題を解くために使用されますが、「最適な」解を見つける厳密なソルバーを設計するために使用される方法は、問題の非常に小さなインスタンスを除いて基本的に不可能ですこのモデルは、最新のメタヒューリスティックを使用して、限られた時間内で最適解に近い解を見つけます。

QUBOベーシックモデル

最も単純なQUBOモデルは次のように表現できます。

最小 ⁡ y = xt Q x \min \quad y=\bold{x}^t \bold{Q} \bold{x}y=バツt Qx
ここでx \bold{x}xは二分決定変数のベクトルQ \bold{Q}Qは定数の正方行列です

ここで定数正方行列Q \mathrm{Q}Qは一般的に、対称行列または上/下三角を使用して、一般性を失うことなく最適化問題で使用されます。

上記を展開し、次のようにスカラー形式に書き直します。
min ⁡ ∑ Q ijxixj \min \sum Q_{ij} x_i x_jQイジバツ私はバツj

xi ∈ { 0 , 1 } x_i \in \{0,1\}によるバツ私は{ 0 ,1 } はバイナリ変数に属し、 xi = xi 2 x_i = x_i^2があります。バツ私は=バツ2したがって、より一般的なQUBOモデルでは次のように表現されます。

min ⁡ ∑ ( i , j ) ∈ EQ ijxixj + ∑ i ∈ X cixi \min \sum_{(i, j) \in \mathcal{E}} Q_{ij} x_i x_j+\sum_{i \in \mathcal{ X}} c_i x_i( i , j ) EQイジバツ私はバツj+i Xc私はバツ私は
で、

  • xi ∈ { 0 , 1 } , i ∈ X : = { 1 , … , X } x_i \in\{0,1\}, i \in \mathcal{X}:=\{1, \ldots, X\ }バツ私は{ 0 ,1 } バツ:={ 1 X }は二分決定変数であり、E : = { ( i , j ) ∣ i , j ∈ X , i ≠ j } \mathcal{E}:=\{(i, j) \mid i, j \in \ mathcal{X}, i \neq j\}E:={(j )j× =j }
  • Q ij ∈ R , ( i , j ) ∈ E Q_{ij} \in \mathbb{R},(i, j) \in \mathcal{E}QイジR (j )EQUBOは、目的関数の二次項係数です
  • ci ∈ R , i ∈ X c_i \in \mathbb{R}, i \in \mathcal{X}c私はR XQUBOは、目的関数の一次 (線形) 項の係数です

QUBOIsingこの問題は、変数yi = 1 − 2 xi y_i = 1-2x_iを通じてモデルを使用して等価に表現できます。y私は=12倍_私は変換、元のモデルのQUBO決定変数ドメイン空間{ 0 , 1 } \{ 0,1 \}{ 0 ,1 }Isingはモデル決定変数ドメイン空間{ − 1 , + 1 } \{ -1 , +1 \}にマッピングされます。{ 1 変換後のモデルは次Isingように表されます: min ⁡ ∑ ( i , j ) ∈ EJ ijyiyj + ∑ i ∈ X hiyi , J ij = − 1 4 Q ij , hi = − 1 2 ( ci + ∑ j ∈ XQ
ij ) , \begin{aligned} & \min \sum_{(i, j) \in \mathcal{E}} J_{ij} y_{i} y_{j}+\sum_{i \in \mathcal{X }} h_{i} y_{i}, \\ & J_{ij}=-\frac{1}{4} Q_{ij}\quad, h_{i}=-\frac{1}{2}\ left(c_{i}+\sum_{j \in \mathcal{X}} Q_{ij}\right), \end{aligned}( i , j ) EJイジy私はyj+i Xh私はy私はJイジ=41Qイジh私は=21 c私は+j XQイジ
ただし、yi ∈ { − 1 , 1 } , i ∈ X y_{i} \in\{-1,1\}, i \in \mathcal{X}y私は{ 1 1 } バツ

紙の中の小さな事件

最適化問題: 2 値変数の 2 次目的関数 yy を最小化するy
miny = − 5 x 1 − 3 x 2 − 8 x 3 − 6 x 4 + 4 x 1 x 2 + 8 x 1 x 3 + 2 x 2 x 3 + 10 x 3 x 4 min \quad y=- 5 x_1-3 x_2-8 x_3-6 x_4+4 x_1 x_2+8 x_1 x_3+2 x_2 x_3+10 x_3 x_4y=- 5 ×13x _28 ×36x _4+4x _1バツ2+8 ×1バツ3+2倍_2バツ3+10 ×3バツ4
其中,变量 x i ∈ { 0 , 1 } x_i \in \{ 0 , 1 \} バツ私は{ 0 ,1 } . 線形部分があります(− 5 x 1 − 3 x 2 − 8 x 3 − 6 x 4 -5 x_1-3 x_2-8 x_3-6 x_4- 5 ×13x _28 ×36x _4)和一个二次部分 4 x 1 x 2 + 8 x 1 x 3 + 2 x 2 x 3 + 10 x 3 x 4 4 x_1 x_2+8 x_1 x_3+2 x_2 x_3+10 x_3 x_4 4x _1バツ2+8 ×1バツ3+2倍_2バツ3+10 ×3バツ4)、バイナリ変数xj x_jなのでバツjxj = xj 2 x_j=x_j^2を満たすバツj=バツj2したがって、線形部分は次のように書くことができます。

− 5 × 1 2 − 3 × 2 2 − 8 × 3 2 − 6 × 4 2 -5 x_1^2-3 x_2^2-8 x_3^2-6 x_4^2- 5 ×123x _228 ×326x _42
これに基づいて、最適化モデルの最小化目的関数は行列形式で記述されます。

miny = [ x 1 x 2 x 3 x 4 ] [ − 5 2 4 0 2 − 3 1 0 4 1 − 8 5 0 0 5 − 6 ] [ x 1 x 2 x 3 x 4 ] = xt Q x min \クワッド y=\left[\begin{array}{llll} x_1 & x_2 & x_3 & x_4 \end{array}\right]\left[\begin{array}{cccc} -5 & 2 & 4 & 0 \\ 2 & -3 & 1 & 0 \\ 4 & 1 & -8 & 5 \\ 0 & 0 & 5 & -6 \end{配列}\right]\left[\begin{配列}{l} x_1 \\ x_2 \\ x_3 \\ x_4 \end{array}\right] =\bold{x}^t \bold{Q} \bold{x}y=[バツ1バツ2バツ3バツ4] 524023104185005 6 バツ1バツ2バツ3バツ4 =バツtQx _

問題のサイズが小さいため、枯渇 ( 2 4 = 16 2^4=1624=16通りの可能性) この問題の最適解を見つけます:y = − 11 , x 1 = x 4 = 1 , x 2 = x 3 = 0 ) y=-11,x_1=x_4=1,x_2=x_3= 0)y=11 バツ1=バツ4=1 バツ2=バツ3=0 )

Python でライブラリを使用しますwildqat( pip install wildqat、この方法にはエラーがあります、問題があります、python3.6バージョンに依存するため、Python ライブラリの上位バージョンには互換性がありません、インストールに問題があります)

import wildqat as wq
a = wq.opt()
a.qubo = [[-5,2,4,0],
		  [2,-3,1,0],
    	  [4,1,-8,5],
		  [0,0,5,-6]]
   a.sa()

このライブラリには問題があり、最適解は正しくありませんが、最適解に近いものを見つけることができます。パラメータの設定に問題がある可能性があります。

使用PyQUBO库:[ 2103.01708] PyQUBO: 組み合わせ最適化問題を QUBO フォームにマッピングするための Python ライブラリ (arxiv.org)

関連するコード:

from pyqubo import Binary
import neal

# 定义哈密顿量
   x1, x2, x3, x4 = Binary("x1"), Binary("x2"), Binary("x3"), Binary("x4")
H = -5 * x1 - 3 * x2 - 8 * x3 - 6 * x4 + 4 * x1 * x2 + 8 * x1 * x3 + 2 * x2 * x3 + 10 * x3 * x4

# 编译哈密顿量得到一个模型
model = H.compile()

# 调用'to_qubo()'获取QUBO系数
# 其中,offset表示下面目标函数中的常数值
# qubo是系数,字典dict类型,{('x2', 'x2'): -3.0,...}表示其系数
qubo, offset = model.to_qubo()

print(qubo)
print(offset)

# 求解qubo模型
# 将Qubo模型输出为BinaryQuadraticModel,BQM来求解
bqm = model.to_bqm()

# 定义采样器,这里使用模拟退火采样器
sa = neal.SimulatedAnnealingSampler()

# 进行采样,由于该采样器机制,需要设置高一点的采样个数,这样能够确保能够获得最优值
# 对应的设置越高,时间花费越久。
sampleset = sa.sample(bqm, num_reads=10)
decoded_samples = model.decode_sampleset(sampleset)

# 将采样出来的结果按照目标函数进行排序,求出最佳(小)的采样结果
best_sample = min(decoded_samples, key=lambda x: x.energy)

# 输出采样结果
print(f"采样取值:{
       
       best_sample.sample},对应的结果为:{
       
       best_sample.energy}")

既知のペナルティを備えた QUBO モデルを作成する

一般的な QUBO モデルでは、変数がバイナリであり、制約が含まれていないことが必要です。したがって、実際に制約のある問題を解決したい場合は、二次ペナルティを目的関数に導入する必要があります

古典的な制約 同等のペナルティ
x + y ≤ 1 x+y \leq 1バツ+y1 P ( xy ) P(xy)P ( x y )
x + y ≥ 1 x + y \geq 1バツ+y1 P ( 1 − x − y + xy ) P(1-x-y+xy)P ( 1バツy+)
x + y = 1 x+y=1バツ+y=1 P ( 1 − x − y + 2 xy ) P(1-x-y+2 xy)P ( 1バツy+2 × y
x ≤ yx \leq yバツy P ( x − xy ) P(xx y)P ( ×)
x 1 + x 2 + x 3 ≤ 1 x_1+x_2+x_3 \leq 1バツ1+バツ2+バツ31 P ( x 1 x 2 + x 1 x 3 + x 2 x 3 ) P\left(x_1 x_2+x_1 x_3+x_2 x_3\right)P( ×1バツ2+バツ1バツ3+バツ2バツ3)
x = yx=yバツ=y P ( x + y − 2 xy ) P(x+y-2 xy)P ( ×+y2 × y

ここで、P ( xy ) P(xy)に注意してください。P ( x y )はスカラーPPP( x ∗ y ) (x*y)( ×y )、つまりP ∗ ( x ∗ y ) P*(x*y)P( ×y )、他も同様です。

その中で機能PPPは正のスカラー ペナルティ値として計算され、この値は十分に大きくなるように計算する必要があります。では、QUBOその制約はオプティマイザによって実装されるため、ペナルティ項目によって指定されるルールは次のとおりです。最小化問題、それが実行可能な解である場合、つまり制約条件が満たされている場合、対応するペナルティitem が 0 に等しい; 行の解、つまり制約を満たさない解には、何らかの正のペナルティ量に等しいペナルティ項があります。PPPの値が妥当かどうかは、追加ペナルティ関数を計算するモデルの解を解くことで計算でき、0 であればPPP値効果はOKです。

ペナルティ値が大きすぎると、ペナルティ項が元の目的関数の情報を圧倒し、解の品質を区別することが困難になるため、解のプロセスが妨げられる可能性があります。一方で、ペナルティが小さすぎると、実行可能な解決策の模索が困難になる可能性があります。したがって、ペナルティ値をどのように決定するかを考慮して設計する必要があります。

制約項目の設計に関する関連スキルも掲載されており、情報を確認することができます。

解決する

QUBO多くの組み合わせ最適化問題はモデルとして再定式化でき、シミュレーテッド アニーリング、量子アニーリング、量子近似最適化アルゴリズム ( )QAOAなどの方法を使用して解決できます。どちらも最新のメタヒューリスティック検索手法です。

量子アニーリング

多くの固有名詞と原則の詳細については、D-Wave システムのドキュメントを参照するか、情報を確認してください。たとえば纠缠(entanglement)、、、、、、、、、、耦合器(coupler)_ 本征谱(Eigenspectrum)_ _ _ _ _ _哈密顿量(Hamiltonian)本征态(eigenstates)初始哈密顿量(Initial Hamiltonian)最终哈密顿量(Final Hamiltonian)隧穿哈密顿量 (tunneling Hamiltonian)问题哈密顿量 (problem Hamiltonian)

量子アニーリングは、結合量子ビットの自然な挙動に基づいて基底状態(最低エネルギー状態)を見つけるプロセスです。量子アニーリングのプロセスでは、時間変化するハミルトニアンH ( s ) \mathcal{H}(s)を使用できます。H ( s )来表示:
H ( s ) = A ( s ) HI − B ( s ) HP \mathcal{H}(s)=A(s) H_{I}-B(s) H_{P}H ()=A ( s ) HB ( s ) HP
其中, A ( s ) A(s) A ( s )B ( s ) B(s )B ( s )は、正規化されたアニーリング時間s = t / tas = t / t_{a}s=t / t,其中 t a t_{a} t総アニーリング時間を示します。この設計により、次のことが保証されます。

  • A ( 0 ) = 1 A(0)=1 ( 0 )=1およびB ( 0 ) = 0 B(0)=0B ( 0 )=0H ( s ) \mathcal{H}(s)H ( s )は初期状態HI H_IH、ユーザーによって定義されます。
  • A ( 1 ) = 0 A(1)=0 ( 1 )=0およびB ( 1 ) = 0 B(1)=0B ( 1 )=0H ( s ) \mathcal{H}(s)H ( s )はアニーリング後の状態 HP を表しますH_PHPは、問題ハミルトニアン ( problem Hamiltonian) とも呼ばれ、最小エネルギー状態です。

その後、設計するときに、初期状態の設計を問題に従って簡単に設計できます。たとえば、
HI = ∑ i σ ix H_{I}=\sum_{i} \sigma_{i}^{x}H=p×
其中, σ i x \sigma_{i}^{x} p×iiを示しますPauli − x Pauli-x for i量子ビットポール_ _ _ _x演算子 (パウリ− x -xx演算子)。

そして問題のハミルトニアン、つまりHP H_PHP設計は、最適化された目的関数によって与えられます。
HP = ∑ i , j J ij σ iz ⋅ σ jz + ∑ ihi σ iz H_{P}=\sum_{i, j} J_{ij} \sigma_{i} ^{z} \cdot \sigma_{j}^{z}+\sum_{i} h_{i} \sigma_{i}^{z}HP=jJイジpzpjz+h私はpz
其中, σ i z \sigma_{i}^{z} pziiを示しますP auli − z Pauli-z for i量子ビットポール_ _ _ _z演算子 (パウリ− z -zz演算子)。

量子アニーラーはまず、H ( 0 ) = HI \mathcal{H}(0)=H_{I} となるように量子ビットの重ね合わせ状態を初期化します。H ( 0 )=H、そしてアニーリング時間中に量子ビット結合を操作して、H ( s ) \mathcal{H}(s)H ( s ) HP H_{P}に向かうHP展開後、アニーリング後、問題のハミルトニアンの固有状態 (eigenstate) になります。量子コンピューティングの断熱定理によれば、アニーリング時間が十分に長い場合、時間変化するハミルトニアンH ( s ) \mathcal{H}(s)H ( s )は常に基底状態、つまり最適関数 (H ( s ) \mathcal{H}(s) )をH ( s )の溶液)。

焼き鈍し法

シミュレーテッド アニーリング (SA) は、探索空間で最適なソリューションを見つけるために使用される一般的なグローバル最適化アルゴリズムです。その基本原理は、物理学におけるアニーリング プロセスをシミュレートし、局所的な最適解に陥ることを避けるために、温度パラメーターを通じて探索プロセス中に次善の解を受け入れる確率を制御することです。シミュレーテッド アニーリング アルゴリズムの基本的なフローは次のとおりです。

  1. 解の初期化x 0 x_0バツ0と初期温度T 0 T_0T0

  2. この温度で繰り返し、各繰り返しで次のことを行います。

    a. 現在のソリューションxxからxの近傍でx ' x'バツ

    b. x ' x'を計算します。バツ'目的関数値f ( x ' ) f(x')f ( x' )xxxの目的関数の値f ( x ) f(x)f ( x )

    c. Metropolis 基準に従って、つまりf ( x ' ) < f ( x ) f(x')< f(x) の場合に新しい解を受け入れるかどうかを判断します。f ( x _<f ( x )、確率1 11 はx 'x'を受け入れますバツ'を新しい解として、それ以外の場合は確率e − Δ f / T e^{-\Delta f/T}eΔ f / Tはx ' x'を受け入れますバツ,その中Δ f = f ( x ′ ) − f ( x ) \Delta f=f(x')-f(x)f_ _=f ( x _f ( x )

  3. 温度TTを更新しますT、温度が停止条件を満たすまでステップ 2 を繰り返します。

ここで温度TTTは時間の経過とともに減少するパラメータで、アルゴリズムが次善の解決策を受け入れる確率を制御します。

上記のアルゴリズムから、反復効果は、初期温度、冷却速度、終了温度の 3 つのパラメーターによって影響を受けることがわかります。

  • 通常、初期温度はより高い値に設定され、探索の初期段階で一部の不適切な解が確実に受け入れられるようにするため、局所的な最適解から外れる可能性が高くなります。

  • 通常、終了温度は低い値に設定されており、温度が終了温度まで低下すると探索が終了し、このとき得られる解がアルゴリズムによって得られる最適解となります。

  • 冷却速度は、通常、1 未満の定数に設定されます。冷却速度が遅いほど、探索時間は長くなりますが、探索範囲が広くなり、全体的な最適解を見つける確率が高くなります。

したがって、最適解に迅速に到達するには、初期温度、冷却速度、終了温度の 3 つのパラメーターを合理的に設定する必要があります。

ここでは、 dwave-samplersライブラリのサンプラーSimulatedAnnealingSamplerと対応するパラメーターを紹介します。

このライブラリでは、初期温度と最終温度は1 TK \frac{1}{TK}で計算されます。TK _1β 1 \beta_1に変換b1β 0 \beta_0b0(ここでKKKはボルツ定数です)、パラメーターbeta_range = [ β 0 , β 1 ] \text{beta\_range} =[\beta_0,\beta_1] をベータ範囲=[ b0b1が入ってきます。冷却速度は通常beta_schedule_type、 とパラメータnum_sweepsについてはbeta_schedule_type

  • "linear": 線形、[β 0 , β 1 ] [\beta_0,\beta_1][ b0b1]num_sweepsサンプリングポイントを各更新温度の値として線形に取得します
  • "幾何学"、幾何学、[β 0 , β 1 ] [\beta_0,\beta_1][ b0b1]各更新温度の値としてサンプリング ポイントnp.geomspace(*beta_range, num=num_betas)を取得しますnum_sweeps
  • 「カスタム」: ユーザー定義

量子近似最適化アルゴリズム (QAOA)

量子近似最適化アルゴリズムはQPandaライブラリを利用することができますが、この部分はよく理解できていないので、後で時間があるときに追加します。

高次問題 (HOBO)

解決すべき主な問題は、QUBOモデル内の二次項よりも高次の目的関数の問題をどのように解決するかです。

参考论文:[2001.00658] Compressed Quadratization of Higher Order Binary Optimization Problems (arxiv.org)

論文ごとに異なる名前が記載されています。

  • 高次バイナリ最適化 ( HOBO): 高次バイナリ最適化
  • 項二次化 二次化: 項の二乗に従って、単項式を二次式に変換します。つまり、xi = xi 2 、ただしxi ∈ 0 , 1 x_i = x_i^2, \quad where \quad x_i \in{0,1}バツ私は=バツ2ここ_バツ私は0 1

高次のバイナリ最適化問題の圧縮二次化: 現時点では、ローゼンバーグ多項式を使用して高次の最適化問題の次数を減らす方法があり、追加の変数を導入することでブール空間内の項の数を 1 倍に減らします。この方法は、最終的には最終的なブール空間行列が非常にまばらになり、問題のサイズが大きくなります。次に論文では、変数を追加せずに元のブール空間で直接動作するリダクション手法が提案されています。

論文の中に私が理解できなかったものが 1 つあります。

ここに画像の説明を挿入

ここにxxを感じてくださいX は間違っています、 zzであるべきですzの場合、表現したい意味は次のようになります。zzz はブール空間の値に属し、変数yyy、つまりyyy が特定の値をとるときh ( z , y は特定の値をとる) h(z,y_{特定の値をとる})h ( z ,y特定の)はf ( z ) f(z)と同等ですf ( z ) 、 hhによるh関数は確かではありません。関数が等価条件を満たすことがわかり、別の制限を加える、つまりyyy がこの特定の値は h ( z , y は特定の値を取る) h(z,y_{特定の値を取る}) になります。h ( z ,y特定の)を最小値に、

次に、貪欲なアイデアに従って、 f ( z ) f(z)を最小化するときが来ると、理解するのは簡単です。f ( z )は、 h ( z , y ) h(z,y) を最小化することと同じです。h ( z ,y

これに基づいて、同等のものがあります。

ここに画像の説明を挿入

これは理解するのがさらに難しいですが、xi ∈ { 0 , 1 } x_i \in \{ 0 , 1 \}を考えてください。バツ私は{ 0 ,1 }、ここで y は多くの組み合わせであり、yi ∈ { 0 , 1 } y_i \in \{ 0, 1\}y私は{ 0 ,1 } を網羅的にリストするのが簡単で、ddLinear and quadratic reformulations of nonlinear optimization problems in binary variablesであることが論文で証明されています。d、目的の変数yyyの数は ⌈log ⁡ d ⌉ − 1 \lceil\log d\rceil-1ログ_d⌉ _1 . (式の表現に問題があるような気がします)

この置換方法には 2 つの問題があります。詳しくは論文を参照してください。降順の置換に変数を使用しなかったため、慎重に検討HOBOしませんでした。

2023 年の mathorcup の質問 A

数学的定義

名詞 数式
融資額 LLL (固定値) は 1000000
金利収入率 I (固定値) は 8%
合格率マトリックス、TTT 其中, T i , j T_{i,j} T jiiを示しますiクレジット スコア カード番目j個のしきい値
不良債権比率マトリックス、HHH 其中, H i , j H_{i,j} H jiiを示しますiクレジット スコア カード番目jしきい値
合計合格率 PPP
総不良債権率 QQQ
コレクションスペース(記事内で具体的に説明) X \数学{X}バツ
制約 λ \ラムダ
最終収入 HHH

質問 1

問題 1 では、決定変数xi 、 j x_{i,j}を定義します。バツ jこれは以下を表すために使用されます:
xi , j = { 0 、i 番目のクレジット スコアカードの j 番目のしきい値は選択しません 1 、i 番目のクレジット スコアカードの j 番目のしきい値を選択します x_{i,j}= \left\{ \ begin{array}{c} 0 \quad 、 \i\ 番目のクレジット スコアカードの \j\ 番目のしきい値は選択しません \\ 1 \quad 、 \i の \j\ 番目のしきい値を選択します\ 番目のクレジット スコアカード \\ \end{array} \right。バツ j={ 0i 番目のクレジット スコアカードのj番目のしきい値の選択を解除します    1i番目のクレジット スコアカードのj番目の    しきい値を選択します
次に、決定変数xi 、 j x_{i,j}についてバツ j対応する合格率Pi , j P_{i,j}P jおよびダメージ率Q i , j Q_{i,j}Q j有:
P i , j = xi , j ∗ T i , j Q i , j = xi , j ∗ Hi , j P_{i,j} = x_{i,j} \ * \ T_{i,j} \\ Q_{i,j} = x_{i,j} \ * \ H_{i,j}P j=バツ j  T jQ j=バツ j  H j
次に、決定変数xi , j x_{i,j}バツ j対応する最終所得H i , j H_{i,j}H j
H i , j = L ∗ I ∗ P i , j ∗ ( 1 − Q i , j ) − L ∗ Pi , j ∗ Q i , j H_{i,j} = L \ * \ I \ * \ P_{i,j} \ * \ (1-Q_{i,j}) \ - \ L \ * \ P_{i,j} \ * \ Q_{i,j}H j=L    P j  ( 1Q j)  L  P j  Q j
全体、つまり最終収入を考えてみましょうHHH
H = ∑ ( i , j ) ∈ XH i , j = ∑ i = 1 100 ∑ j = 1 10 [ L ∗ I ∗ P i , j ∗ ( 1 − Q i , j ) − L ∗ P i , j ∗ Q i , j ] = L ∗ I ∗ ∑ i = 1 100 ∑ j = 1 10 P i , j − L ∗ ( I + 1 ) ∗ ∑ i = 1 100 ∑ j = 1 10 ( P i , j ∗ Q i , j ) = L ∗ I ∗ ∑ i = 1 100 ∑ j = 1 10 ( Ti , j ∗ xi , j ) − L ∗ ( I + 1 ) ∗ ∑ i = 1 100 ∑ j = 1 10 ( Ti , j ∗ H i , j ∗ xi , j 2 ) H = \sum_{ {(i, j) \in \mathcal{X}}} H_{i,j} \\ = \sum_{i=1}^{100} \sum_{j=1}^{10} [{L \ * \ I \ * \ P_{i,j} \ * \ (1-Q_{i,j}) \ - \ L \ * \ P_{i,j} \ * \ Q_{i,j}}] \ \ = L \ * \ I \ * \sum_{i=1}^{100} \sum_{j=1}^{10}P_{i,j} - L*(I+1)*\sum_{i =1}^{100} \sum_{j=1}^{10}(P_{i,j} \ * \ Q_{i,j}) \\ = L \ * \ I \ * \sum_{i= 1}^{100} \sum_{j=1}^{10}(T_{i,j} \ * \ x_{i,j}) - L*(I+1)*\sum_{i=1} ^{100} \sum_{j=1}^{10}(T_{i,j} \ * \ H_{i,j} \ * \ x_{i,j}^2)H=( i , j ) XH j=i = 1100j = 110[ L    P j  ( 1Q j)  L  P j  Q j]=L   i = 1100j = 110P jL(+1 )i = 1100j = 110( P j  Q j)=L   i = 1100j = 110( T j  バツ j)L(+1 )i = 1100j = 110( T j  H j  バツj2)
最終収入については、目的関数− H -HH ,即
min − H = L ∗ ( I + 1 ) ∗ ∑ i = 1 100 ∑ j = 1 10 ( Ti , j ∗ H i , j ∗ xi , j 2 ) − L ∗ I ∗ ∑ i = 1 100 ∑ j = 1 10 ( Ti , j ∗ xi , j ) min \ -H = L*(I+1)*\sum_{i=1}^{100} \sum_{j=1}^{ 10}(T_{i,j} \ * \ H_{i,j} \ * \ x_{i,j}^2) - L \ * \ I \ * \sum_{i=1}^{100} \ sum_{j=1}^{10}(T_{i,j} \ * \ x_{i,j}) H=L(+1 )i = 1100j = 110( T j  H j  バツj2)L   i = 1100j = 110( T j  バツ j)
制約を考慮します。全体で選択できるスコアカードのしきい値は 1 つだけなので、決定変数xi 、 j x_{i,j}バツ jそのうちの 1 つだけが 1、つまり
∑ ( i , j ) ∈ X xi , j = ∑ i = 1 100 ∑ j = 1 10 xi , j = 1 \sum_{ {( i, j) \in \mathcal { X }}} x_{i,j}= \sum_{i=1}^{100} \sum_{j=1}^{10} x_{i,j} = 1( i , j ) Xバツ j=i = 1100j = 110バツ j=1

ここでX \mathcal{X}X空間は次のように定義されます:X : = { ( i , j ) ∣ i ∈ { 1 , 2 , . . . , 100 } , j ∈ { 1 , 2 , . . . , 10 } } \mathcal{X} := \{(i, j) \mid i \in \{1,2,...,100\}, j \in \{1,2,...,10 \} \}バツ:={(j ){ 1 2 ... 100 } j{ 1 2 ... 10 }}

以上の説明:
min − H = L ∗ ( I + 1 ) ∗ ∑ i = 1 100 ∑ j = 1 10 ( Ti , j ∗ Hi , j ∗ xi , j 2 ) − L ∗ I ∗ ∑ i = 1 100 ∑ j = 1 10 (Ti , j ∗ xi , j ) s 。と。∑ i = 1 100 ∑ j = 1 10 xi , j = 1 分 \ -H = L*(I+1)*\sum_{i=1}^{100} \sum_{j=1}^{10} (T_{i,j} \ * \ H_{i,j} \ * \ x_{i,j}^2) - L \ * \ I \ * \sum_{i=1}^{100} \sum_{ j=1}^{10}(T_{i,j} \ * \ x_{i,j}) \\ st \quad \sum_{i=1}^{100} \sum_{j=1}^{ 10} x_{i,j} = 1 H=L(+1 )i = 1100j = 110( T j  H j  バツj2)L   i = 1100j = 110( T j  バツ j)s i = 1100j = 110バツ j=1
制約項λ \lambdaλ上記の 2 次制約付き 2 値最適化モデルを 2 次制約なし 2 値最適化モデルに書き換えます (QUBO):
min y = L ∗ ( I + 1 ) ∗ ∑ i = 1 100 ∑ j = 1 10 ( Ti , j ∗ H i , j ∗ xi , j 2 ) − L ∗ I ∗ ∑ i = 1 100 ∑ j = 1 10 ( Ti , j ∗ xi , j ) + λ ∗ ( ∑ i = 1 100 ∑ j = 1 10 xi , j − 1 ) 2 分 \ \ y = L*(I+1)*\sum_{i=1}^{100} \sum_{j=1}^{10}(T_{i,j} \ * \ H_{i ,j} \ * \ x_{i,j}^2) - L \ * \ I \ * \sum_{i=1}^{100} \sum_{j=1}^{10}(T_ {i, j} \ * \ x_{i,j}) + \lambda * (\sum_{i=1}^{100} \sum_{j=1}^{10} x_{i,j} - 1 )^2分かっ  =L(+1 )i = 1100j = 110( T j  H j  バツj2)L   i = 1100j = 110( T j  バツ j)+(i = 1100j = 110バツ j1 )2

質問 1 の列挙暴力コード実装の場合:

import time
import pandas as pd

if __name__ == '__main__':
    # 定义一些变量
    L = 1000000  # 贷款资金
    I = 0.08  # 利息收入率

    df = pd.read_csv('./data/附件1:data_100.csv', header=0)

    # 定义最大的数
    max_value = -1

    # 定义最大数字的索引下标
    max_i = max_j = -1

    start = time.time()

    for i in range(1, 101):
        for j in range(0, 10):

            # 总通过率
            P = df[f"t_{
      
      i}"].iloc[j]

            # 总坏账率
            Q = df[f"h_{
      
      i}"].iloc[j]

            # 此时的最终收入
            temp_value = L * I * P * (1 - Q) - L * P * Q

            # print(f"选卡[{i},{j + 1}],对应最终收入{temp_value},最大收入:{max_value}")

            if temp_value > max_value:
                max_value = temp_value
                max_i = i
                max_j = j

    end = time.time()
    print(f"暴力时间:{
      
      end - start} s")

    print(f"最大值:{
      
      max_value}")
    print(f"对应的选取卡1:第{
      
      max_i}{
      
      max_j + 1}个阈值")

QUBOモデル + シミュレーテッド アニーリング アルゴリズムを使用して、次のことを実現します。

import time
from pyqubo import Array, Constraint
from dwave.samplers import SimulatedAnnealingSampler

import numpy as np
from pyqubo import Placeholder


# 在字典中找到value的key
def get_key(dict, value):
    return [k for k, v in dict.items() if v == value]


# 主函数,问题一的主要求解函数
def main():
    # 定义一些变量
    L = 1000000  # 贷款资金
    I = 0.08  # 利息收入率

    # 读取数据
    data = np.genfromtxt('./data/附件1:data_100.csv', delimiter=',', skip_header=1)

    # 获取T矩阵和H矩阵
    T = data[:, ::2]
    H = data[:, 1::2]

    # 定义二进制决策变量,10 * 100
    x = Array.create('x', shape=(10, 100), vartype='BINARY')

    # 定义惩罚项M
    M = Placeholder('M')
    M = 100000

    # 定义哈密顿量,也就是对应的目标函数
    # 注意这里不是总通过率和总坏账率,是中间变量,将最终决策目标的连加符号放到里面整出来的
    P = np.sum(np.multiply(x, T))
    Q = np.sum(np.multiply(x, H))
    H = - (L * I * P * (1 - Q) - L * P * Q) + M * Constraint((np.sum(x) - 1) ** 2, label='sum(x_i_j) = 1')

    # 编译哈密顿量得到一个模型
    model = H.compile()

    # 将Qubo模型输出为BinaryQuadraticModel,BQM来求解
    bqm = model.to_bqm()

    # 记录开始退火时间
    start = time.time()

    # 模拟退火
    sa = SimulatedAnnealingSampler()
    sampleset = sa.sample(bqm, seed=666, beta_range=[10e-10, 50], num_sweeps=10000, beta_schedule_type='geometric',num_reads=10)


    # 对数据进行筛选,对选取的数据进行选取最优的
    decoded_samples = model.decode_sampleset(sampleset)  # 将上述采样最好的num_reads组数据变为模型可读的样本数据
    best_sample = min(decoded_samples, key=lambda x: x.energy)  # 将能量值最低的样本统计出来,表示BQM的最优解

    end = time.time()
    print(f"退火时间花费:{
      
      end - start} s")

    # 统计决策变量为1的所有数据
    data_1_list = get_key(best_sample.sample, 1)

    print(f"对应的取1的决策变量有:{
      
      data_1_list}(注意是索引,从0开始),对应的能量为(最大最终收入):{
      
      - best_sample.energy}")
    
    
if __name__ == '__main__':
    main()

問題 1 については、総当たりの枯渇はQUBOモデル + シミュレーテッド アニーリング アルゴリズムの実行時間よりも高速ですが、アルゴリズムの時間計算量を考慮すると、カードにはmmがあります。mシート、しきい値選択にはnnn _

  • ループによる総当たりアルゴリズムはO ( mn ) O(mn)O ()
  • QUBOモデル+シミュレーテッドアニーリングアルゴリズムは現代のメタヒューリスティック最適化アルゴリズムであり、特にNP問題などデータ量が多い場合、規模が大きくなるほど演算速度が速くなります。

質問2

問題 2 については、QUBO モデルの 2 つの理解を考慮します。

  • 決定変数xi 、 j 、 k x_{i,j,k}を定義するバツi j k選択するかどうかを示します:最初のクレジット スコア カードにはiiを選択しますiしきい値、2 番目のクレジット スコア カードはjjj 個のしきい値があり、3 番目のクレジット スコア カードはkk 番目k 個のしきい値。
  • 主に暴力的な疲労のプロセスから得られた発見であり、最初の 2 枚のクレジット スコア カードの閾値選択は固定されており、3 番目のクレジット スコア カードは定義されていますi 個のしきい値が決定変数xi x_iバツ私は、3 枚目のクレジット スコア カードの最適なしきい値を決定した後、他の 2 枚のクレジット カードの最適なしきい値を同様に決定します。数回の反復の後、この方法によって決定されたしきい値が、この問題におけるしきい値の最適な組み合わせになります。

詳細については、以下を参照してください。

シャワー

決定変数xi 、 j 、 k x_{i,j,k}を定義するバツi j k表すために使用されます:
xi , j , k = { 0 、未選択: 最初のクレジット スコア カードに i しきい値を選択し、2 番目のクレジット スコア カードに j しきい値を選択し、3 番目のクレジット スコア カードに k しきい値を選択します。 1、選択: 最初のクレジット スコア カードは i 番目のしきい値を選択し、2 番目のクレジット スコア カードは j 番目のしきい値を選択し、3 番目のクレジット スコア カードは k 番目のしきい値を選択します x_{i,j,k}=\ left\{ \begin{array}{c} 0 \quad 、選択しないでください: \ 最初のクレジット スコア カードは \i \ 番目のしきい値を選択し、2 番目のクレジット スコア カードは \j 番目のしきい値を選択し、3 番目のクレジット スコア カードは \ を選択しますクレジット スコア カードの k\ 番目のしきい値 \\ 1 \quad を選択します: \最初のクレジット スコア カードは \i\ 番目のしきい値を選択し、2 番目のクレジット スコア カードは \j\ 番目のしきい値を選択し、3 番目のクレジット スコア カードは \j\ 番目のしきい値を選択します\k\番目のしきい値\\ \end{array} \right を選択します。バツi j k={ 0選ばないでください: 最初のクレジットスコア カードのi番目のしきい値、 2 番目のクレジット スコア カードのj番目のしきい値、 3番目のクレジット スコア カードのk番目のしきい値を選択します。      1選択する: 最初のクレジットスコア カードのi番目のしきい値、 2 番目のクレジット スコア カードのj番目のしきい値、 3番目のクレジット スコア カードのk番目の      しきい値を選択します。
次に、決定変数xi 、 j 、 k x_{i,j,k}についてバツi j k対応する合格率Pi , j , k P_{i,j,k}Pi j kおよびダメージ率Q i , j , k Q_{i,j,k}Qi j k有:
P i , j , k = xi , j , k ∗ T 1 , i ∗ T 2 , j ∗ T 3 , k Q i , j , k = xi , j , k ∗ 1 3 ∗ ( H 1 , i + H 2 , j + H 3 , k ) P_{i,j,k} = x_{i,j,k} \ * \ T_{1,i} \ * \ T_{2,j} \ * \ T_ {3,k} \\ Q_{i,j,k} = x_{i,j,k} \ * \ \frac{1}{3} \ * \ (H_{1,i} \ + \ H_{ 2,j} \ + \ H_{3,k})Pi j k=バツi j k  T1   T2 j  T3 kQi j k=バツi j k  31  ( H1  + H2 j + H3 k)
次に、決定変数xi , j , k x_{i,j,k}バツi j k対応する最終所得H i , j , k H_{i,j,k}Hi j k
Hi , j , k = L ∗ I ∗ Pi , j , k ∗ ( 1 − Q i , j , k ) − L ∗ Pi , j , k ∗ Q i , j , k H_{i,j ,k} = L \ * \ I \ * \ P_{i,j,k} \ * \ (1-Q_{i,j,k}) \ - \ L \ * \ P_{i,j,k} \ * \ Q_{i,j,k}Hi j k=L    Pi j k  ( 1Qi j k)  L  Pi j k  Qi j k
全体、つまり最終収入を考えてみましょうHHH
H = ∑ ( i , j , k ) ∈ XH i , j , k = ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 [ L ∗ I ∗ P i , j , k ∗ ( 1 − Q i , j , k ) − L ∗ P i , j , k ∗ Q i , j , k ] = L ∗ I ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 Pi , j , k − L ∗ ( I + 1 ) ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 ( Pi , j , k ∗ Q i , j , k ) = L ∗ I ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 [( T 1 , i ∗ T 2 , j ∗ T 3 , k ) ∗ xi , j , k ] − L ∗ ( I + 1 ) 3 ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 [( H 1 , i + H 2 , j + H 3 , k ) ∗ T 1 , i ∗ T 2 , j ∗ T 3 , k ∗ xi , j , k 2 ] H = \和_{ {(i, j, k) \in \mathcal{X}}} H_{i,j,k} \\ = \sum_{i=1}^{10} \sum_{j=1}^{10} \sum_{k=1}^{10} \ [ {L \ * \ I \ * \ P_{i,j,k} \ * \ (1-Q_{i,j,k}) \ - \ L \ * \ P_{i,j,k} \ * \ Q_{i,j,k}} ]\\ = L \ * \ I \ * \sum_{i=1}^{10} \sum_{j=1 }^{10} \sum_{k=1}^{10}P_{i,j,k} - L*(I+1)*\sum_{i=1}^{10} \sum_{j=1 }^{10} \sum_{k=1}^{10}(P_{i,j,k} \ * \ Q_{i,j,k}) \\ = L \ * \ I \ * \sum_{ i=1}^{10} \sum_{j=1}^{10} \sum_{k=1}^{10} [( T_{1,i} * T_{2,j} * T_{3, k} ) \ * \ x_{i,j,k}] \\ -\frac {L*(I+1)}{3} * \sum_{i=1}^{10} \sum_{j=1 }^{10} \sum_{k=1}^{10} [(H_{1,i} + H_{2,j} + H_{3,k}) * T_{1,i} * T_{2 ,j} * T_{3,k} * x_{i,j,k}^2]H=( i , j , k ) XHi j k=i = 110j = 110k = 110 [ L    Pi j k  ( 1Qi j k)  L  Pi j k  Qi j k]=L   i = 110j = 110k = 110Pi j kL(+1 )i = 110j = 110k = 110( Pi j k  Qi j k)=L   i = 110j = 110k = 110[( T1 T2 jT3 k)  バツi j k]3L(+1 )i = 110j = 110k = 110[( H1 +H2 j+H3 k)T1 T2 jT3 kバツi j k2]
目的関数− H -HH、このときの決定変数の制約条件は次のとおりです。 (選択肢が 1 つだけ選択されている)
∑ ( i , j , k ) ∈ X xi , j , k = ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 xi , j , k = 1 \sum_{ { (i, j, k) \in \mathcal{X}}} x_{i,j,k}= \sum_{i=1}^{10} \sum_{ j=1}^{10} \sum_{k=1}^{10} x_{i,j,k} = 1( i , j , k ) Xバツi j k=i = 110j = 110k = 110バツi j k=1

ここでX \mathcal{X}X空間は次のように定義されます:X : = { ( i , j , k ) ∣ i , j , k ∈ { 1 , 2 , . . . , 10 } } \mathcal{X}:=\{(i, j ,k ) \mid i,j,k \in \{1,2,...,10\} \}バツ:={(j k )j k{ 1 2 ... 10 }}

上記:
min − H = L ∗ I ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 [ ( T 1 , i ∗ T 2 , j ∗ T 3 , k ) ∗ xi , j , k ] − L ∗ ( I + 1 ) 3 ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 [ ( H 1 , i + H 2 , j + H 3 , k ) ∗ T 1 , i ∗ T 2 , j ∗ T 3 , k ∗ xi , j , k 2 ] s 。と。∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 xi , j , k = 1 分 \ -H = L \ * \ I \ * \sum_{i=1}^{10} \sum_{j= 1}^{10} \sum_{k=1}^{10} [( T_{1,i} * T_{2,j} * T_{3,k} ) \ * \ x_{i,j,k }] \\ -\frac {L*(I+1)}{3} * \sum_{i=1}^{10} \sum_{j=1}^{10} \sum_{k=1}^ {10} [(H_{1,i} + H_{2,j} + H_{3,k}) * T_{1,i} * T_{2,j} * T_{3,k} * x_{ i,j,k}^2] \\ st \quad \sum_{i=1}^{10} \sum_{j=1}^{10} \sum_{k=1}^{10} x_{i ,j,k} = 1 H=L   i = 110j = 110k = 110[( T1,iT2,jT3,k)  xi,j,k]3L(I+1)i=110j=110k=110[(H1,i+H2,j+H3,k)T1,iT2,jT3,kxi,j,k2]s.t.i=110j=110k=110xi,j,k=1
通过添加约束项 λ \lambda λ上記の 2 次制約付き 2 値最適化モデルを 2 次制約なし 2 値最適化モデルに書き換えます (QUBO):
min y = L ∗ I ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 [( T 1 , i ∗ T 2 , j ∗ T 3 , k ) ∗ xi , j , k ] − L ∗ ( I + 1 ) 3 ∗ ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 [( H 1 , i + H 2 , j + H 3 , k ) ∗ T 1 , i ∗ T 2 , j ∗ T 3 , k ∗ xi , j , k 2 ] + λ ∗ ( ∑ i = 1 10 ∑ j = 1 10 ∑ k = 1 10 xi , j , k − 1 ) 2 分 \ \ y = L \ * \ I \ * \sum_{i=1}^{10} \sum_{j=1}^{10} \sum_{k= 1}^ {10} [( T_{1,i} * T_{2,j} * T_{3,k} ) \ * \ x_{i,j,k}] \\ -\frac {L*( I+1 )}{3} * \sum_{i=1}^{10} \sum_{j=1}^{10} \sum_{k=1}^{10} [(H_{1,i} + H_{ 2,j} + H_{3,k}) * T_{1,i} * T_{2,j} * T_{3,k} * x_{i,j,k}^2] \\ + \lambda * (\sum_{i=1}^{10} \sum_{j=1}^{10} \sum_{k=1}^{10} x_{i,j,k} - 1)^ 2分かっ  =L   i = 110j = 110k = 110[( T1 T2 jT3 k)  バツi j k]3L(+1 )i = 110j = 110k = 110[( H1 +H2 j+H3 k)T1 T2 jT3 kバツi j k2]+ l(i = 110j = 110k = 110バツi j k1 )2

コード実装のプロセスでは、合計合格率 T 1 、 i ∗ T 2 、 j ∗ T 3 、 k T_{1,i} \ * \ T_{2,j} \ * \ T_ を計算する必要があるため{3,k}T1   T2 j  T3 kそして、合計不良債権率1 3 ∗ ( H 1 , i + H 2 , j + H 3 , k ) \frac{1}{3} * (H_{1,i} + H_{2,j} + H_ {3,k})31( H1 +H2 j+H3 knumpyfor ループの使用効率が比較的遅い場合は、ライブラリ内のブロードキャスト メカニズムを使用して

コードは次のように実装されます。

import time
from pyqubo import Array, Constraint
from dwave.samplers import SimulatedAnnealingSampler
import numpy as np
from pyqubo import Placeholder


# 在字典中找到value的key
def get_key(dict, value):
    return [k for k, v in dict.items() if v == value]


def main():
    # 定义一些变量
    L = 1000000  # 贷款资金
    I = 0.08  # 利息收入率

    # 表示选取的卡号
    card1, card2, card3 = 1, 2, 3

    # 读取数据
    data = np.genfromtxt('../data/附件1:data_100.csv', delimiter=',', skip_header=1)

    # 获取T矩阵和H矩阵
    T = data[:, ::2]
    H = data[:, 1::2]

    # 定义二进制决策变量,10 * 100
    x = Array.create('x', shape=(10, 10, 10), vartype='BINARY')

    # 定义惩罚项M
    M = Placeholder('M')
    M = 30000

    # 定义哈密顿量,也就是对应的目标函数
    # 注意这里不是总通过率和总坏账率,是中间变量,将最终决策目标的连加符号放到里面整出来的
    T1 = T[:, card1 - 1]
    T2 = T[:, card2 - 1]
    T3 = T[:, card3 - 1]

    H1 = H[:, card1 - 1]
    H2 = H[:, card2 - 1]
    H3 = H[:, card3 - 1]

    # 计算三种组合后的总通过率和总坏账率,通过广播机制来实现
    T = T1[:, None, None] * T2[None, :, None] * T3[None, None, :]
    H = (H1[:, None, None] + H2[None, :, None] + H3[None, None, :]) / 3

    P = np.sum(np.multiply(x, T))
    Q = np.sum(np.multiply(x, H))
    H = - (L * I * P * (1 - Q) - L * P * Q) + M * Constraint((np.sum(x) - 1) ** 2, label='sum(x_i_j) = 1')

    # 编译哈密顿量得到一个模型
    model = H.compile()

    # 将Qubo模型输出为BinaryQuadraticModel,BQM来求解
    bqm = model.to_bqm()

    print("开始模拟退火")

    start = time.time()
    sa = SimulatedAnnealingSampler()
    sampleset = sa.sample(bqm, seed=888, beta_range=[10e-12, 60], beta_schedule_type='geometric', num_reads=50)

    # 对数据进行筛选
    decoded_samples = model.decode_sampleset(sampleset)  # 将上述采样最好的num_reads组数据变为模型可读的样本数据
    best_sample = min(decoded_samples, key=lambda x: x.energy)  # 将能量值最低的样本统计出来,表示BQM的最优解

    # print(f"验证约束条件M:{best_sample.constraints()}")
    end = time.time()
    print(f"退火时间:{
      
      end - start} s")

    # print(best_sample.sample)

    # 统计决策变量为1的所有数据
    data_1_list = get_key(best_sample.sample, 1)

    print(f"对应的取1的决策变量有:{
      
      data_1_list}(表示[第一张卡的阈值][第二张卡的阈值][第三张卡的阈值],注意是索引,从0开始),对应的能量为{
      
      -best_sample.energy}")


if __name__ == '__main__':
    main()

列挙暴力

対応する列挙暴力コードは次のとおりです。

import pandas as pd

if __name__ == '__main__':
    # 定义一些变量
    L = 1000000  # 贷款资金
    I = 0.08  # 利息收入率

    # 选取第几列的信用卡
    card1 = 1
    card2 = 2
    card3 = 3

    df = pd.read_csv('../data/附件1:data_100.csv', header=0)
    # 定义最大的数
    max_value = -1

    # 定义最大数字的索引下标
    max_i = max_j = max_k = -1

    for i in range(0, 10):
        for j in range(0, 10):
            for k in range(0, 10):
                # 总通过率
                P = df[f"t_{
      
      card1}"].iloc[i] * df[f"t_{
      
      card2}"].iloc[j] * df[f"t_{
      
      card3}"].iloc[k]

                # 总坏账率
                Q = (df[f"h_{
      
      card1}"].iloc[i] + df[f"h_{
      
      card2}"].iloc[j] + df[f"h_{
      
      card3}"].iloc[k]) / 3

                # 此时的最终收入
                temp_value = L * I * P * (1 - Q) - L * P * Q

                # print(f"选卡1阈值:[{i + 1}],选卡1阈值:[{j + 1}],选卡1阈值:[{k + 1}],对应最终收入{temp_value},之前的最大收入:{max_value}")

                if temp_value > max_value:
                    max_value = temp_value
                    max_i = i
                    max_j = j
                    max_k = k

        print(f"第{
      
      i + 1}个对应的最大值:{
      
      max_value},三个阈值选取为:{
      
      max_i + 1},{
      
      max_j + 1},{
      
      max_k + 1},其中,阈值编号[1-10]")

    print(f"最大值:{
      
      max_value},三个阈值选取为:{
      
      max_i + 1},{
      
      max_j + 1},{
      
      max_k + 1},其中,阈值编号[1-10]")

貪欲+QUBO

実行プロセス中に、3 番目の質問に非常に役立つルールを見つけました。上記の意思決定プロセス (for ループ) を印刷して確認できます。

最初のサイクルの決定プロセスは次のとおりです[1,1,2]-->[2,1,2]-->[3,1,2]-->[3,1,2]-->[3,1,2]-->[6,1,2]-->[7,1,2]-->[8,1,2]-->[8,1,2]-->[8,1,2]ここに出力される結果は比較的小さいため、ルールが明らかではない可能性があります。しかし、見分けるのは簡単です:

3 つのスコアリング クレジット カードの意思決定プロセスでは、1 番目と 2 番目のスコアリング クレジット カードのしきい値の選択が固定され、3 番目のスコアリング クレジット カードのしきい値の選択が考慮される場合、この時点で最適なクレジット スコアリング カードのしきい値が選択されます。時間。次に、1 番目と 3 番目のスコアリング クレジット カードのしきい値の選択を固定し、2 番目のスコアリング クレジット カードのしきい値の選択を考慮して、この時点で最適なクレジット スコアリング カードのしきい値を選択します。次に、2 番目と 3 番目のスコアリング クレジット カードのしきい値の選択を固定し、最初のスコアリング クレジット カードのしきい値の選択を考慮して、この時点で最適なクレジット スコアリング カードのしきい値を選択します。このノンストップの反復に基づいて、最終的なしきい値の選択は、最適なしきい値の組み合わせになります。(それを証明することを検討してください)。

ここに画像の説明を挿入

このプロセスに基づいて、元の10 × 10 × 10 10 \times 10 \times 10を変換できます。10×10×10 個の決定変数の解は、反復回数 × 10 反復回数\× 10反復×10 個の決定変数に関する質問。これは質問 3 にとって非常に重要な発見です。質問 3 では、元々は1000 × 990 × 980 1000 \times 990 \times 980でした。1000×990×980 の決定変数問題は、反復回数× 980 反復\× 980に変換されます。反復×980 の決定変数スケールの質問。

質問3

最初に次のことを検討しました: 設計決定変数xi 、 j x_{i,j}バツ jこれは以下を表すために使用されます:
xi , j = { 0 、i 番目のクレジット スコアカードの j 番目のしきい値は選択しません 1 、i 番目のクレジット スコアカードの j 番目のしきい値を選択します x_{i,j}= \left\{ \ begin{array}{c} 0 \quad 、 \i\ 番目のクレジット スコアカードの \j\ 番目のしきい値は選択しません \\ 1 \quad 、 \i の \j\ 番目のしきい値を選択します\ 番目のクレジット スコアカード \\ \end{array} \right。バツ j={ 0i 番目のクレジット スコアカードのj番目のしきい値の選択を解除します    1i番目のクレジット スコアカードのj番目の    しきい値を選択します
制約を考慮しない場合の全体の合格率PPPとダメージ率QQQ满足:
P = ∏ ( i , j ) ∈ X ( xi , j ∗ Ti i , j + 1 − xi , j ) = ∏ ( i , j ) ∈ X ( Ti , jxi , j ) Q = 1 3 ∗ ∑ ( i , j ) ∈ X ( H i , j ∗ xi , j ) P =\prod_{(i,j) \in \mathcal{X}}(x_{i,j}*T_{i,j } +1-x_{i,j}) = \prod_{(i,j) \in \mathcal{X}}(T_{i,j}^{x_{i,j}}) \\ Q = \ frac{1}{3} * \sum_{(i,j) \in \mathcal{X} }( H_{i,j} * x_{i,j})P=( i , j ) X( × jT j+1バツ j)=( i , j ) X( Tjバツ j)Q=31( i , j ) X( H jバツ j)
最終所得HHH有:
H = L ∗ I ∗ P ∗ ( 1 − Q ) − L ∗ P ∗ QH = L \ * \ I \ * \ P \ * \ (1-Q) \ - \ L \ * \ P \ * \QH=L    P  ( 1  L  P  P = ∏ ( i , j ) ∈ X ( xi , j ∗ Ti , j + 1 − xi , j ) P =\prod_{(i,j) \in \mathcal{X} を使用すると、Q が次のようになります
} (x_{i,j}*T_{i,j} +1-x_{i,j})P=( i , j ) X( × jT j+1バツ j)この式の目的関数において、決定変数の最も高いサブ項の係数は1001 10011001回。ホーボーホーボーに変換H OBOモデルをダウングレードする必要がありますが、これは非常に複雑に感じられます。考慮しない。

結果として、P = ∏ ( i , j ) ∈ X ( Ti , jxi , j ) P = \prod_{(i,j) \in \mathcal{X}}(T_{i,j}^{x_{i) を使用します、j}})P=( i , j ) X( Tjバツ j)式を使用してから、多項式近似 (多項式近似) を使用するアイデアを検討し、テイラー級数展開などの多項式を使用して指数項を展開します:eax = ∑ n = 0 ∞ ( ax ) nn ! e^{ax} = \sum_ {n=0}^{\infty} \frac{(ax)^n}{n!}e× _=n = 0( × ) _、一次項を維持します。つまり、eax ≈ 1 + axe^{ax} \about 1+axe× _1+。_ _ つまり、指数項は多項式関数の線形項に変換できます。
P = ∏ ( i , j ) ∈ X ( Ti , jxi , j ) = exp { ∑ ( i , j ) ∈ X [ xi , j ∗ ln ( Ti , j ) ] } ≈ 1 + ∑ ( i , j ) ∈ X [ xi , j ∗ ln ( Ti , j ) ] P = \prod_{(i,j) \in \mathcal {X}} (T_{i,j}^{x_{i,j}}) = exp \{ \sum_{(i,j) \in \mathcal{X}} [x_{i,j}* ln (T_{i,j})] \} \about 1 + \sum_{(i,j) \in \mathcal{X}} [x_{i,j}* ln(T_{i,j})]P=( i , j ) X( Tjバツ j)=エクスペ{ _ _ ( i , j ) X[ × jl n ( T j)]}1+( i , j ) X[ × jl n ( T j)]
次に、この理論に基づいて、元の目的関数を最高二次項の目的関数に変換できます。しかし、これも問題です。なぜなら、決定変数xi , j ∈ { 0 , 1 } x_{i,j} \in \{ 0,1 \} であるからです。バツ j{ 0 ,1 }が離散変数である場合、テイラーレベル展開の使用は等価ではない可能性があり、考慮されません。

上記のすべての考慮事項、つまり全体の合格率PPをどのように解決するかという問題があります。P式。PPができれPを主項目の式に変換すると、問題全体を解くのは非常に簡単になります。次に、決定変数xi 、 j 、 k 、 l 、 m 、 n x_{i,j,k,l,m,n} をバツi j k l m n選択するかどうかを決定するために使用されます: セクションiiiクレジットスコアカードセレクションlllしきい値、jj 番目jクレジット スコア カードの月目を選択してくださいm番目のしきい値、kk 番目kクレジット スコア カードの選択nnn 個のしきい値。つまり:
xi , j , k , l , m , n = { 0 、 1 は​​選択しないでください、 x_{i,j,k,l,m,n}=\left\{ \begin{array}{c を選択してください} 0 \quad、\\ 1 \quad は選択しないでください、\end{array} \right を選択してください。バツi j k l m n={ 0選ばないでください1選ぶ
次に、決定変数xi 、 j 、 k 、 l 、 m 、 n について x_{i,j,k,l,m,n}バツi j k l m n対応する合格率Pi , j , k , l , m , n P_{i,j,k,l,m,n}Pi j k l m nおよびダメージ率Q i , j , k , l , m , n Q_{i,j,k,l,m,n}Qi j k l m n有:
P i , j , k , l , m , n = xi , j , k , l , m , n ∗ Ti , l ∗ T j , m ∗ T k , n Q i , j , k , l , m , n = 1 3 ∗ xi , j , k , l , m , n ∗ ( H i , l + H j , m + H k , n ) P_{i,j,k,l,m,n} = x_{i,j,k,l,m,n} \* \ T_{i,l} \ * \ T_{j,m} \ * \ T_{k,n} \\ Q_{i,j,k ,l,m,n} = \frac{1}{3} * x_{i,j,k,l,m,n} \ * \ (H_{i,l} + H_{j,m}+H_ {k,n})Pi j k l m n=バツi j k l m n  T  Tj m  Tk nQi j k l m n=31バツi j k l m n  ( H+Hj m+Hk n)
を最終所得の式に代入します:
H = ∑ ( i , j , k , l , m , n ) ∈ XH i , j , k , l , m , n = ∑ i = 1 100 ∑ j = 1 100 ∑ k = 1 100 ∑ l = 1 10 ∑ m = 1 10 ∑ n = 1 10 [ L ∗ I ∗ Pi , j , k , l , m , n ∗ ( 1 − Q i , j , k , l , m , n ) − L ∗ P i , j , k , l , m , n ∗ Q i , j , k , l , m , n ] H = \sum_{ {(i, j,k,l, m , n) \ \mathcal{X}}} H_{i,j,k,l,m,n} \\ = \sum_{i=1}^{100} \sum_{j=1}^{100} \sum_{ k=1}^{100} \sum_{l=1}^{10} \sum_{m=1}^{10} \sum_{n=1}^{10} [{L \ * \ I \ * \ P_{i,j,k,l,m,n} \ * \ (1-Q_{i,j,k,l,m,n}) \ - \ L \ * \ P_{i, j,k ,l,m,n} \ * \ Q_{i,j,k,l,m,n} }] \\H=( i , j , k , l , m , n ) XHi j k l m n=i = 1100j = 1100k = 1100l = 110m = 110n = 110[ L    Pi j k l m n  ( 1Qi j k l m n)  L  Pi j k l m n  Qi j k l m n]
この方法で制約が考慮されない場合、量子数は100 × 100 × 100 × 10 × 10 × 10 100 \times 100 \times 100 \times 10 \times 10 \times 10 となります。100×100×100×10×10×10、メモリが十分ではないため、これを実行できません。

暴力を考慮する

ループを使用してブルート フォースを実行して、最適な組み合わせを見つけることを検討してください。これを実行するには時間がかかるので、マルチスレッド + 分割統治の考え方を検討してください。コードは次のとおりです。

import time
import pandas as pd
from threading import Thread

# 定义一些变量
L = 1000000  # 贷款资金
I = 0.08  # 利息收入率

df = pd.read_csv('../data/附件1:data_100.csv', header=0)

# 全局变量,用于存储所有线程中的最大值
max_value = -1
# 定义最大数字的索引下标
max_i = max_j = max_k = max_m = max_n = max_l = -1


def computer_result(begin, end):
    # 使用全局变量
    global max_value, max_i, max_j, max_k, max_m, max_n, max_l

    for i in range(begin, end):
        for j in range(i + 1, 101):
            for k in range(j + 1, 101):
                for m in range(0, 10):
                    for n in range(0, 10):
                        for l in range(0, 10):
                            # 总通过率
                            P = df[f"t_{
      
      i}"].iloc[m] * df[f"t_{
      
      j}"].iloc[n] * df[f"t_{
      
      k}"].iloc[l]

                            # 总坏账率
                            Q = (df[f"h_{
      
      i}"].iloc[m] + df[f"h_{
      
      j}"].iloc[n] + df[f"h_{
      
      k}"].iloc[l]) / 3

                            # 此时的最终收入
                            temp_value = L * I * P * (1 - Q) - L * P * Q

                            if temp_value > max_value:
                                max_value, max_i, max_j, max_k, max_m, max_n, max_l = temp_value, i, j, k, m, n, l


if __name__ == '__main__':

    start = time.time()
    print(start)

    # 创建线程并启动它们
    threads = [Thread(target=computer_result, args=(i, i + 1)) for i in range(1, 101)]
    for thread in threads:
        thread.start()

    # 等待所有线程执行完毕
    for thread in threads:
        thread.join()

    end = time.time()
    print(f"时间花费:{
      
      end - start} s")
    print(f"最大值:{
      
      max_value},对应的选取卡1:第{
      
      max_i}{
      
      max_m + 1}个阈值,"
          f"对应的选取卡2:第{
      
      max_j}{
      
      max_n + 1}个阈值,"
          f"对应的选取卡3:第{
      
      max_k}{
      
      max_l + 1}个阈值,其中,卡取值[1-100],阈值取值[1-10]")

コードはまだ最適化できると思いますが、それに時間をかけたくありません。

暴力と貪欲について考える

これは主に質問 2 にある貪欲法則であるため、この効率は比較的高いです。次に、同様に次の反復アルゴリズムを使用します。

ここに画像の説明を挿入

それでは、主な問題は、2 つのスコアリング クレジット カードのしきい値を固定した後、最適なクレジット スコア カードのしきい値をどのように見つけるかということです。強引に行うか、QUBO問題 1 のモデルを使用します。

暴力的な解決策は次のとおりです。

import pandas as pd

if __name__ == '__main__':
    # 定义一些变量
    L = 1000000  # 贷款资金
    I = 0.08  # 利息收入率

    # 迭代次数
    Iter = 10

    # 选取第几列的信用卡,初始化最开始选择的数据
    card1, threshold1, card2, threshold2, card3, threshold3 = 1, 0, 2, 0, 3, 0

    # 定义最大的数
    max_value = -1
    # 读取数据
    df = pd.read_csv('../data/附件1:data_100.csv', header=0)

    for iter in range(Iter):  # 迭代次数,其实这里还可以根据几次迭代算出的总值来提前结束迭代
        # 设置更新迭代,不使用临时变量
        card1, threshold1, card2, threshold2, card3, threshold3 = card2, threshold2, card3, threshold3, card1, threshold1

        # 从固定的信用卡1和信用卡2外数据中选一个,构建可以选择的卡的集合
        choose_list = {
    
    i for i in range(1, 101) if i not in (card1, card2)}

        # 获取第一张卡和第二张卡的通过率和坏账率,否则在循环里重复获取了
        t1 = df[f"t_{
      
      card1}"].iloc[threshold1]
        t2 = df[f"t_{
      
      card2}"].iloc[threshold2]
        h1 = df[f"h_{
      
      card1}"].iloc[threshold1]
        h2 = df[f"h_{
      
      card2}"].iloc[threshold2]

        # 固定第一张卡,和第二张卡,然后找到最佳的第三张卡
        for c3 in choose_list:
            for th3 in range(0, 10):
                # 总通过率
                P = t1 * t2 * df[f"t_{
      
      c3}"].iloc[th3]

                # 总坏账率
                Q = (h1 + h2 + df[f"h_{
      
      c3}"].iloc[th3]) / 3

                # 此时的最终收入
                temp_value = L * I * P * (1 - Q) - L * P * Q

                if temp_value > max_value:
                    max_value = temp_value
                    card3 = c3
                    threshold3 = th3

    print(f"最大值:{
      
      max_value},卡选择:{
      
      card1}_{
      
      threshold1 + 1},{
      
      card2}_{
      
      threshold2 + 1},{
      
      card3}_{
      
      threshold3 + 1}")

貪欲+QUBO

コード:

import pandas as pd
import time
import re
from pyqubo import Array, Constraint
from dwave.samplers import SimulatedAnnealingSampler
import numpy as np
from pyqubo import Placeholder

# 在字典中找到value的key
def get_key(dict, value):
    return [k for k, v in dict.items() if v == value]


def main():
    # 定义一些变量
    L = 1000000  # 贷款资金
    I = 0.08  # 利息收入率

    # 迭代次数
    Iter = 10

    # 选取第几列的信用卡,初始化最开始选择的数据
    card1, threshold1, card2, threshold2, card3, threshold3 = 1, 0, 2, 0, 3, 0

    # 定义最大的数
    max_value = -1
    # 读取数据
    df = pd.read_csv('../data/附件1:data_100.csv', header=0)

    for iter in range(Iter):  # 迭代次数,其实这里还可以根据几次迭代算出的总值来提前结束迭代
        # 设置更新迭代,不使用临时变量
        card1, threshold1, card2, threshold2, card3, threshold3 = card2, threshold2, card3, threshold3, card1, threshold1

        # 获取第一张卡和第二张卡的通过率和坏账率
        t1 = df[f"t_{
      
      card1}"].iloc[threshold1]
        t2 = df[f"t_{
      
      card2}"].iloc[threshold2]
        h1 = df[f"h_{
      
      card1}"].iloc[threshold1]
        h2 = df[f"h_{
      
      card2}"].iloc[threshold2]

        # 获取第三张卡能够选取的通过率与坏账率的矩阵

        choose_index = [i for i in range(1, 101) if i not in (card1, card2)]
        card3_data = df.drop([f"t_{
      
      card1}", f"h_{
      
      card1}", f"t_{
      
      card2}", f"h_{
      
      card2}"], axis=1).values

        # 获取T矩阵和H矩阵
        T = card3_data[:, ::2]
        H = card3_data[:, 1::2]

        # 定义二进制决策变量,10 * 98
        x = Array.create('x', shape=(10, 98), vartype='BINARY')
        # 定义惩罚项M
        M = Placeholder('M')
        M = 50000

        # 定义哈密顿量,也就是对应的目标函数
        P = t1 * t2 * np.sum(np.multiply(x, T))
        Q = (h1 + h2 + np.sum(np.multiply(x, H))) / 3
        H = - (L * I * P * (1 - Q) - L * P * Q) + M * Constraint((np.sum(x) - 1) ** 2, label='sum(x_i_j) = 1')

        # 编译哈密顿量得到一个模型
        model = H.compile()
        bqm = model.to_bqm()
        # 记录开始退火时间
        start = time.time()

        #
        sa = SimulatedAnnealingSampler()

        sampleset = sa.sample(bqm, seed=666, beta_range=[10e-10, 50], num_sweeps=999, beta_schedule_type='geometric',
                              num_reads=50)

        # 对数据进行筛选,对选取的数据进行选取最优的
        decoded_samples = model.decode_sampleset(sampleset)  # 将上述采样最好的num_reads组数据变为模型可读的样本数据
        best_sample = min(decoded_samples, key=lambda x: x.energy)  # 将能量值最低的样本统计出来,表示BQM的最优解

        end = time.time()
        # print(f"退火时间花费:{end - start} s")

        # 统计决策变量为1的所有数据,并对第一个数据进行拆解,获得对应的下标
        data_1_list = get_key(best_sample.sample, 1)
        index_i_j = re.findall(r'\d+', data_1_list[0])
        index_i = int(index_i_j[0])

        if max_value < - best_sample.energy:
            card3 = choose_index[int(index_i_j[1])]
            threshold3 = index_i
            max_value = - best_sample.energy

        print(
            f"第{
      
      iter + 1}次迭代,最大值:{
      
      max_value},卡选择:{
      
      card1}_{
      
      threshold1 + 1},{
      
      card2}_{
      
      threshold2 + 1},{
      
      card3}_{
      
      threshold3 + 1}")

    print(f"最大值:{
      
      max_value},卡选择:{
      
      card1}_{
      
      threshold1 + 1},{
      
      card2}_{
      
      threshold2 + 1},{
      
      card3}_{
      
      threshold3 + 1}")


if __name__ == '__main__':
    start = time.time()
    main()
    end = time.time()
    print(f"时间花费: {
      
      end - start}s")

おすすめ

転載: blog.csdn.net/weixin_41012765/article/details/130249552