2016-06-27 7 views
1

私はPythonには新しく、SciPyを使って次の問題を解決したいが、どの方法が最善の方法であるか分からない。私はすでにこのフォーラムを見て、私が持っている問題に似た何かを見つけることができません。Pythonでこの最適化問題をどのように解決しますか?

私は、次の売上データを持っている: Sales Data 2016

このデータは、異なる場所で、様々な営業担当者のパフォーマンスをまとめたものであり、その目的は、彼らの販売の数字ではなくてもとのボーナス配分(X1-X8)を割り当てることです次の制約:ボーナス配分(x1 to x8) = 100%

和、

最大ボーナス配分<=10% of total

ロケーション別の最大ボーナス割り当て<=25%

非常に高く評価されています。ありがとう。

答えて

0

最適化方法を使用する必要がある場合は、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 
+0

こんにちはJ. Hollom、この場合、設計変数があるX1-X8すなわち制約和(X1:X8)と、各営業担当者に割り当てることがどのくらいのボーナスの= 1 。目的関数は、sum(x * Sales)を最大にする、すなわち最も高いボーナスシェア(x)を最良の販売人に割り当てるべきである。ドキュメンテーション(または私の経験不足)から明らかではないので、どのようにコード化されますか。万一、制約を設定する例、つまりsum(x1-x8)= 1?ありがとう。 – Kal

+0

答えでは、設計変数の数を8個(x1-x8)から1個の設計変数(x)に減らすことをお勧めします。あなたの希望する重みを得る。悪い点は、その答えとある制約の例で答えてください。 – Wokpak

+0

SciPyのドキュメントは私の見解では理解しにくいので、これをコード化する方法はまだ不明です。さらなる助けを提供し、コードを明示することができますか?ありがとう。 – Kal

関連する問題