最適化方法を使用する必要がある場合は、scipy.minimize、具体的には'SLSQP'メソッドを使用できます。これは、拘束された勾配に基づく最小化アルゴリズムです。
scipy.minimise
は、scipy.fmin_slsqpメソッドの単なるラッパーです。
問題定義
最適化の最初のステップは、あなたの設計変数、目的関数と制約を識別することです。制約は明確ですが、他の2つはあまり明確ではありません。
目的関数の方向を指定していません。私はすべての従業員に配分されたボーナスの割合を最大にすることを前提としています。
デザイン変数には、8人の従業員がおり、それぞれにxボーナスを割り当てることができます。したがって、8つの設計変数を使用することができますが、これらはそれぞれの従業員が達成した売上数に関連する必要があると述べています。したがって、売上数に対する乗数として使用する単一の設計変数を使用すると、
# Design variable
x = 1
# Sales info
sales_list = [10, 2, 4, 15, 8, 7, 12, 1]
# Calculate x1 - x8
for index, entry in enumerate(sales_list):
print 'x' + str(index) + ': ' + str(entry * x)
目的関数
Scipy.minimize
は最小化されようとしている機能を必要とします。あなたのケースでは、1つの設計変数だけを使用して、全体の目的関数は、あなたの制約を満足させながらx0を最大にすることになります。最小化問題に最大限切り替えるには、それはまたもあります、あなたの目的関数の勾配を必要とreturn -result
は-result
の勾配を与えるように配合することができます。
制約
これで、制約を表す関数を作成する必要があります。制約は、各制約を表す辞書のタプルとして入力されます。辞書は以下の形式で構築される:scipy
ドキュメントから
{'type': 'ineq', 'fun': const_func, 'jac': const_func_grad, 'args': (m, n, ..)}
:
不等式が非負であることがあることを意味するのに対し
等式制約は、制約関数の結果がゼロであることがあることを意味。
したがって、すべての場合、 'ineq'を使用して関数を設定し、満足したら値> = 0.0を返します。あなたの場所fun
関数とそのjac
機能は次のようになります。loc_a_grad
は、Xを使用していないことを
def loc_a_const(x):
return 25 - (x * sales_list[0] + x * sales_list[5])
def loc_a_grad(x):
return - sales_list[0] - sales_list[5]
注意、しかしSLSQP
方法は、両方の機能にargs
の同じ番号を渡すしようとします。
側注
最適化の方法なしで、あなたの問題を書き出して、代わりに初期の推測を持っているし、あなたの制約ごとに偽のtrueを返すために簡単でした。私は、働いていた0以外の整数値がx = 1
であることを発見しました。ツールではなくソリューションが必要な場合は、試行錯誤を使用して小数点以下の桁数に対応するソリューションを見つけることができます。
の作業例
import scipy.optimize as opt
sales_list = [10, 2, 4, 15, 8, 7, 12, 1]
# Function and gradient
def func(x):
return - x
def func_prime(x):
return - 1
# Constraints
def loc_a_const(x):
return 25 - (x * sales_list[0] + x * sales_list[5])
def loc_a_const_grad(x):
return - sales_list[0] - sales_list[5]
def loc_b_const(x):
return 25 - (x * sales_list[1] + x * sales_list[2] + x * sales_list[6])
def loc_b_const_grad(x):
return - sales_list[1] - sales_list[2] - sales_list[6]
def loc_c_const(x):
return 25 - (x * sales_list[3] + x * sales_list[4] + x * sales_list[7])
def loc_c_const_grad(x):
return - sales_list[3] - sales_list[4] - sales_list[7]
loc_a_dict = {'type': 'ineq', 'fun': loc_a_const, 'jac': loc_a_const_grad}
loc_b_dict = {'type': 'ineq', 'fun': loc_b_const, 'jac': loc_b_const_grad}
loc_c_dict = {'type': 'ineq', 'fun': loc_c_const, 'jac': loc_c_const_grad}
# Initial guess
x0 = 1
results = opt.minimize(
fun=func,
x0=x0,
method='SLSQP',
jac=func_prime,
constraints=(loc_a_dict, loc_b_dict, loc_c_dict))
print results
こんにちはJ. Hollom、この場合、設計変数があるX1-X8すなわち制約和(X1:X8)と、各営業担当者に割り当てることがどのくらいのボーナスの= 1 。目的関数は、sum(x * Sales)を最大にする、すなわち最も高いボーナスシェア(x)を最良の販売人に割り当てるべきである。ドキュメンテーション(または私の経験不足)から明らかではないので、どのようにコード化されますか。万一、制約を設定する例、つまりsum(x1-x8)= 1?ありがとう。 – Kal
答えでは、設計変数の数を8個(x1-x8)から1個の設計変数(x)に減らすことをお勧めします。あなたの希望する重みを得る。悪い点は、その答えとある制約の例で答えてください。 – Wokpak
SciPyのドキュメントは私の見解では理解しにくいので、これをコード化する方法はまだ不明です。さらなる助けを提供し、コードを明示することができますか?ありがとう。 – Kal