2016-06-12 11 views
0
私はscipy.optimize.minimizeに

scipyのダウンロードoptimize.minimize機能

max r 
x1**2 + y1**2 <= (1-r)**2 
(x1-x2)**2 + (y1-y2)**2 >= 4*r**2 
0 <= r <= 1 

だから私が書いてきた次のコードを使用非線形計画タスクを解決しようと

r = np.linspace(0, 1, 100) 
x1 = np.linspace(0, 1, 100) 
y1 = np.linspace(0, 1, 100) 
x2 = np.linspace(0, 1, 100) 
y2 = np.linspace(0, 1, 100) 


fun = lambda r: -r 
cons = ({'type': 'ineq', 
    'fun': lambda x1, r: [x1[0] ** 2 + x1[1] ** 2 - (1 - r) ** 2], 
    'args': (r,)}, 
    {'type': 'ineq', 
    'fun': lambda x2, r: [x2[0] ** 2 + x2[1] ** 2 - (1 - r) ** 2], 
    'args': (r,)}, 
    {'type': 'ineq', 
    'fun': lambda x1, x2, r: [(x1[0] - x2[0]) ** 2 + (x1[1] - x2[1]) ** 2 - 4 * r ** 2], 
    'args': (x2, r,)}) 
bnds = ((0, 1), (-1, 1), (-1, 1), (-1, 1), (-1, 1)) 
x0 = [0, 0, 0, 0, 0] 
minimize(fun, x0, bounds=bnds, constraints=cons) 

をしかし、私は次のエラーを持っています

File "C:\Anaconda2\lib\site-packages\scipy\optimize\slsqp.py", line 377, in _minimize_slsqp 
c = concatenate((c_eq, c_ieq)) 
ValueError: all the input arrays must have same number of dimensions 

、私は私のミスを見つけるためのお手伝いをし、正しいコードを入力してください

UPD: Thxを私はそれを正しく構築する方法を理解しました@unutbuします。

g(x) >= 0 

制約がそのようにあるように見える理由です:私たちは、このような形式に制約をリードしなければならない最小化のタスクで

fun = lambda x: -x[0] 
cons = ({'type': 'ineq', 
    'fun': lambda x: -x[1] ** 2 - x[2] ** 2 + (1 - x[0]) ** 2}, 
    {'type': 'ineq', 
    'fun': lambda x: -x[3] ** 2 - x[4] ** 2 + (1 - x[0]) ** 2}, 
    {'type': 'ineq', 
    'fun': lambda x: (x[1] - x[3]) ** 2 + (x[1] - x[4]) ** 2 - 4 * x[0] ** 2}) 
bnds = ((0, 1), (-1, 1), (-1, 1), (-1, 1), (-1, 1)) 
x0 = [0.5, 0.3, 0.5, 0.3, 0.5] 
answer = minimize(fun, x0, bounds=bnds, constraints=cons) 

+0

が得られます。他のすべては1を使用しています。これは 'x0'によると5要素の配列です。 – hpaulj

答えて

2

あなたのパラメータ空間は5次元であるようです。パラメータ のポイントはz = (r, x1, y1, x2, y2)となります。従って を最小化すべき関数 - とも制約関数は、 - ポイントzを受け入れ、 スカラー値を返すべきです。

したがって代わりに

fun = lambda r: -r 

使用

def func(z): 
    r, x1, y1, x2, y2 = z 
    return -r 

、代わりの

lambda x1, r: [x1[0] ** 2 + x1[1] ** 2 - (1 - r) ** 2] 

使用

def con1(z): 
    r, x1, y1, x2, y2 = z 
    return x1**2 + y1**2 - (1-r)**2 

など。例えば0 <= r <= 1ような単純な制約がboundsパラメータを設定する代わりに、制約を定義することによって扱うことができること


注。そしてx2y1x1の境界場合、y2は、-1から1まで、あなたはまた、

x1 = np.linspace(-1, 1, 100) 
... 

しかし、配列rx1y1

x1 = np.linspace(0, 1, 100) 
... 

を変更する場合がありますされていますx2,y2は、funcを最小化するために必要ではないので、スクリプトから完全に除外することもできます。


import numpy as np 
import scipy.optimize as optimize 

""" 
max r 
x1**2 + y1**2 <= (1-r)**2 
(x1-x2)**2 + (y1-y2)**2 >= 4*r**2 
0 <= r <= 1 
""" 

def func(z): 
    r, x1, y1, x2, y2 = z 
    return -r 

def con1(z): 
    r, x1, y1, x2, y2 = z 
    return x1**2 + y1**2 - (1-r)**2 

def con2(z): 
    r, x1, y1, x2, y2 = z 
    return 4*r**2 - (x1-x2)**2 - (y1-y2)**2 

cons = ({'type': 'ineq', 'fun': con1}, {'type': 'ineq', 'fun': con2},) 
bnds = ((0, 1), (-1, 1), (-1, 1), (-1, 1), (-1, 1)) 
guess = [0, 0, 0, 0, 0] 
result = optimize.minimize(func, guess, bounds=bnds, constraints=cons) 
print(result) 

それは第三 `cons`関数は2つの引数を取ることだろ

 fun: -1.0 
    jac: array([-1., 0., 0., 0., 0., 0.]) 
message: 'Optimization terminated successfully.' 
    nfev: 14 
    nit: 2 
    njev: 2 
    status: 0 
success: True 
     x: array([ 1., 0., 0., 0., 0.]) 
関連する問題