2

以下の最適化問題があります。

目的関数は非常に単純です。ベクトル が与えられた場合、最大化するSPREADベクトルを見つけようとします。Wsum(W.SPREAD)

例として、次元 3 では、これは を最大化しようとすることを意味しw1 x spread1 + w2 x spread2 + w3 x spread3ます。

c1, c2 & c3さらに、 ではなくWPOSベクトルに3 つの制約がありPOS = W2POS(W)ます。

例として、次元 3 の制約は次のとおりです。

  1. |pos1 + pos2 + pos3| < 5
  2. |pos1| + |pos2| + |pos3| < 500
  3. Max(pos1, pos2, pos3) < 5

いくつかの最適化を実行する以下のコードを書きましたが、制約 3 は尊重されません。制約を考慮してこの問題を解決するにはどうすればよいですか?

以下のコードを書きました。

from scipy.optimize import fmin_cobyla
import numpy as np
import pandas as pd

def W2POS(W, PRICE, BETA):
    POS = (PRICE * BETA).T.dot(W)
    return POS

def objective(W, SPREAD, sign = 1):
    er = sum((W * SPREAD.T).sum())
    return sign * er

def c1(x, *args):
    """ abs(sum(c)) < 500    """
    POS = W2POS(x,args[0], args[1]) 
    return POS.apply(abs).sum()

def c2(x, *args):
    """ abs(sum()) < 5    """
    POS = W2POS(x,args[0], args[1]) 
    return 5. - abs(POS.sum())

def c3(x, *args):
    """ abs(max(pos)) < 5   """
    POS = W2POS(x,args[0], args[1]) 
    return 5. - POS.apply(abs).max()

# optim
W0 = np.zeros(shape=(len(BETA), 1))
sign = -1
W = fmin_cobyla(objective, W0, cons = [c1, c2, c3], args=(SPREAD,sign), 
                consargs=(PRICE, BETA), maxfun=100, rhobeg = 0.02).T
print 'Solution:', W
args = [PRICE, BETA]
pos = W2POS(W.T,args[0], args[1]) 
print 'c1 < 5:', abs(pos.sum())[0]
print 'c2 < 500:', pos.apply(abs).sum()[0]
print 'c3 < 5:', pos.apply(abs).apply(max)[0]

このコードで c3 が尊重されていないことを示すダミー データで遊ぶことができます: http://pastebin.com/gjbeePgt

4

1 に答える 1

1

元の Fortran 77 ファイルcobyla2.f (このパッケージで入手可能) のドキュメントを読むと、38 行目と 39 行目に次のように記述されています。

C1,C2,...,CM は、少なくとも RHOEND の精度まで、最終的に非負になる制約関数を示します。

fmin_cobylaのscipy API ドキュメントを正しく解釈すると、デフォルトで1.0E-4に設定されます。RHOEND

観察された制約違反が実際にそれよりも小さいが、許容できないほど大きい場合、問題の簡単な解決策は、制約の定式化にRHOENDの値を組み込むことです。つまり、RHOEND

C[i] + RHOEND >= 0

この特定のケースで、制約違反が よりも大きいように見えます。これは、Pauli Virtanen によって作成され、上記の質問に対応するscipyリポジトリの新しいテスト ケースRHOENDによって完全に示されています。

この特定のケースで制約違反を回避するための解決策は、0.01RHOBEGなどの小さい値 on で最適化を開始することです。

于 2013-11-22T21:18:52.537 に答える