私は2つのポリゴンBP
とGP
を黒のポリゴンの不等式制約_-x+y<=1 and x+y<= 5 and x-y<=3 and -y <= 0
_と緑のポリゴンの_-1<=x<=4 and 0 <= y <= 3
_のセットで記述しています。
ここでの私の目標は、LPを使用して分数問題の最適な解を見つけることです。B
がGPにある場合、最大値lambda
は
B =ラムダ* B_BP +(1-ラムダ)* B_GP
言い換えれば、上記の意味で多角形の内側にあるB
の最大の部分を見つけたいのです。そのため、LPプログラムを作成するのに苦労しています。BPを行列の不等式条件として作成すると、すべての_B_BP
_が_M_BP*B_BP <= C
_であるC
がベクトル_(1,5,3,0)
_および_M_BP
_は、行列_((-1,1),(1,1),(1,-1),(0,-1))
_です。だから私はそれがB = x_1 + x_2を与えられたようなもので行くべきだと思います
ラムダを最大化
m_BP * L_BP <= C_Bの対象
およびB_BP> = 0
私が思うところ(これはすべて私の試みであり、すべて非常に間違っている可能性があります)L_BP = (x,y)
ベクトルとlambda = (x+y)/normalization
、および_C_B
_は、ベクトルB
。
最初の質問が複雑すぎる場合は、申し訳ありませんが、ここから始めます。
私があなたの問題を正しく理解していれば、これを数学的な意味で正確に解決することは可能だと思います。説明させてください。 (Superkogitoが指摘するように)目的関数はラムダで線形であるため、最大値(または最小値)は常にいずれかのコーナーポイントで達成されます。これを使うとラムダを計算できます。
簡単な例から始めましょう。黒いポリゴン内のどのポイントでも、ラムダが1であることは明らかです。B= B_BPと置くだけです。ここで、B =(-1、3)としましょう。 B_BP =(-1、0)以外の黒い点を取り、ラムダ> 0の場合、正方形内の緑の点では、x座標は-1より高くなります。だからあなたができる最善はB_BP =(-1、0)を置くことです。次に、緑の点はB_GP =(-1、3)である必要があるため、ラムダ= 0になります。
同じロジックに従って、エンドポイント(-1、0)および(-1、3)によって定義されたエッジでは、常にB_BP =(-1、0)およびB_GP =(-1、3)を使用することがわかります。 。このエッジを上ると、ラムダは1から0に減少します。(-1、1)ラムダ= 2/3では、(-1、2)ラムダ= 1/3で。 (-1、3)と(2、3)の間の上部エッジについても同じことが言えます:(0、3)でラムダ= 1/3など。コーナー(4、3)のある緑の三角形の場合、(4、3)を端点として使用する必要があります。次に(3、3)で、たとえばラムダ= 1/2。
興味深い問題は、明らかに三角形の内部にあります。ここでもB_GPはコーナーの1つであり、B_BPは三角形の辺である黒い線上にあります。これが当てはまらない別の解決策があると想定し、B_GPまたはB_BPを少し左または右にシフトすることでラムダを増やすことができることを証明することで、これを示すことができます。完全な数学的証明はここでは長すぎると思います。左側の三角形を見てみましょう。緑のコーナーが(-1、3)、黒い側が(-1、0)と(2、3)の間です。次に、最大ラムダの場合、B_GP =(-1、3)で、B_BPが黒側になります。 B =ラムダ* B_BP +(1-ラムダ)* B_GPなので、2つの方程式が得られます。また、B_BPはy = x + 1の行にあるため、3番目の方程式が得られます。これらから、B_BPとラムダ(点Bが与えられます)のx座標とy座標を解くことができます。
私はこれを行い、ラムダ=(Bx-By + 4)/ 3.に到達します。B_BPの座標は、B_BPx =(Bx + 1 +ラムダ)/ラムダおよびB_BPy =(By-3 + 3 *ラムダ)/ラムダです。 (ラムダを入力するだけです)。たとえば、ポイント(0、2)の場合、ラムダは2/3になります。他の2つの三角形でもまったく同じことができます。私も同じように行いました。
要約します:
左の三角形の場合:ラムダ=(Bx-By + 4)/ 3
右上の三角形の場合:ラムダ=(-By-Bx + 7)/ 2
右下の三角形の場合:ラムダ= By-Bx + 4
これをプログラミングするのは簡単です。必要に応じて、他の2つの三角形に対応するB_BPの座標を提供できます。お知らせください。ちなみに、三角とBの角を直線で結ぶと到着します。
もちろん、これは目的関数が線形の場合にのみ機能します。他の場合では、Superkogitoによって提案されたアプローチを使用する必要があります。あなたの質問を正しく理解できたといいのですが、理解できない場合はご容赦ください。少なくとも私はそれが素晴らしい数学的挑戦であるとわかりました。
私の意見では、問題はより良い定式化を必要としています。これで問題が解決するかどうかはわかりませんが、うまくいけば役に立ちます。したがって、この最適化問題を解決するには scipy.optimize.minimize を使用することをお勧めします。符号を反転するか逆を使用するだけで、最大化を最小化に変換できます。
また、コードはBP、GP、およびランダムポイントBのランダムポイントに基づいているため、これらも入力ベクトルにフィードする必要があります。入力ベクトルから、ラムダ係数を計算できます(このコードでは、この変数をkと名付けました)。このアプローチは、目的関数fun
、つまり最大kx
および最大ky
の最小出力で制約を満たす入力ベクトルの値を返します。
前述のアプローチは、次のように実装できます。
import numpy as np
import scipy.optimize
# compute k
def k(x):
x_bp, y_bp = x[0], x[1]
x_gp, y_gp = x[2], x[3]
bx , by = x[4], x[5]
# compute k
kx = (bx - x_gp) / (x_bp - x_gp)
ky = (by - y_gp) / (y_bp - y_gp)
return kx, ky
# define objctive/cost function
def fun(x):
kx, ky = k(x)
return 1 / kx + 1 / ky
# define constraints (bp raandom point constraints)
cons = ({'type': 'ineq', 'fun': lambda x: x[0] + x[1] - 5},
{'type': 'ineq', 'fun': lambda x: -x[0] - x[1] - 3})
# init bounds
bnds = ((None, None), (0, None),
(-1., 4.), (0., 3.),
(-1., 4.), (0., 3.))
# init vars vec
#x = [x_bp, y_bp, x_gp, y_gp, bx, by]
x0 = [ 0.1, 0.2, 0.3, 0.5, 0.6, 0.5]
# optimize
res = scipy.optimize.minimize(fun,
x0,
bounds=bnds,
constraints=cons)
# print result
print("optimal x: ", np.round(res.x, 3))
# print optimal k
print("optimal k: ", np.round(k(res.x), 3))
コードを少し調整して、初期値x0
と境界ですが、これでうまくいくはずです。投稿されたスニペットの結果は次のようになります。
optimal x: [0.1 0.2 0.3 0.5 0.6 0.5]
optimal k: [-1.5 -0. ]