2016-12-23 24 views
0

linprogで単純な線形関数を最小限にしようとしています。係数は、arr2の要素に-1を乗じたものです。 -1 < = x1 < = 1、-2 < = x2 < = 2など、各変数には不等式制約のみがあります。Python SciPy linprogの最適化がステータス3で失敗する

linprogに境界を指定しないことを選択した場合:

は楽しい:-4327476.2887400016 メッセージ:「最適化が失敗した

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

numdim = 28 

arr1 = np.ones(numdim) 
arr1 = - arr1 

arr2 = np.array([ 
19.53, 
128.97, 
3538, 
931.8, 
0.1825, 
150.88, 
10315, 
0.8109, 
3.9475, 
3022, 
31.77, 
10323, 
110.93, 
220, 
2219.5, 
119.2, 
703.6, 
616, 
338, 
84.67, 
151.13, 
111.28, 
29.515, 
29.67, 
158800, 
167.15, 
0.06802, 
1179 
]) 

constr_a = [] 

for i in range(numdim): 

    constr_default = np.zeros(numdim) 
    constr_default[i] = 1 
    constr_a.append(constr_default) 

for i in range(numdim): 

    constr_default = np.zeros(numdim) 
    constr_default[i] = -1 
    constr_a.append(constr_default) 

constr_a = np.asarray(constr_a) 
constr_b = np.arange(1, 2*numdim + 1, 1) 
constr_b[numdim:] = constr_b[:numdim] 

print linprog(np.transpose(arr1 * arr2), constr_a, constr_b, bounds=(None, None)) 

私は、次の結果を得ます。問題は無限にあるようだ。 ステータス:私は最後の行を変更しようとした3

:境界として指定

print linprog(np.transpose(arr1 * arr2), constr_a, constr_b, bounds=(-1000, 1000)) 

番号はランダムです。出力は次のとおりです。

楽しい:-4327476.2887400296 メッセージ: '最適化が正常に終了しました。' ステータス:0

これは、若干異なる結果と希望のステータスを示します。 私の質問は、私は図書館を誤用するのですか?正しい答えはどれですか?このコードは 'bounds'パラメータを指定せずに動作することが期待されていました。これらの単純な制約は各変数で一意であるため、このパラメータを使用することはできません。

私はpython 2.7とscipy 0.17.1を使用します。事前に大きな感謝。 UPD

constr_a

は、ドキュメント(https://docs.scipy.org/doc/scipy/reference/optimize.linprog-simplex.html)に従って行列で、実際のコードであるべきです。構文が正しいことを確認するために、次元数を2に減らすことができます:

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

numdim = 2 

arr1 = np.ones(numdim) 
arr1 = - arr1 

arr2 = np.array([ 
19.53, 
128.97 
]) 

constr_a = [] 

for i in range(numdim): 

    constr_default = np.zeros(numdim) 
    constr_default[i] = 1 
    constr_a.append(constr_default) 

for i in range(numdim): 

    constr_default = np.zeros(numdim) 
    constr_default[i] = -1 
    constr_a.append(constr_default) 

constr_a = np.asarray(constr_a) 
constr_b = np.arange(1, 2*numdim + 1, 1) 
constr_b[numdim:] = constr_b[:numdim] 

print constr_a 
print constr_b 
print linprog(np.transpose(arr1 * arr2), constr_a, constr_b, bounds=(None, None)) 

これは動作します。

答えて

0

constr_aリストが正しく構成されていません。スカラの配列ではなく、配列の配列です。これは不適切な下限につながり、最適化が失敗する可能性があります。

おそらく

constr_a.append(constr_default) 

constr_a.append(constr_default[i]) 

する必要があります彼らは正しい形式と値を持っていることを確認するためにバインドされた配列の両方を検査します。

+0

constr_aは行列(2n、n)であり、未知変数配列は(n、1)であり、行列乗算の結果は(2n、1)である配列constr_bである。私には間違いないと思われます。 – Inna

+0

@Inna 'constr_a'の最初のいくつかの要素を表示して確認してください – tihom

+0

ありがとうございます。投稿に回答しました。 – Inna

関連する問題