我是Python的新手,希望使用SciPy解决以下问题,但不知道哪种方法是最好的方法。我已经看过这个论坛,找不到类似我遇到的问题。
我有以下销售数据: Sales Data 2016
此数据总结了不同地点的各种销售人员的表现,目的是根据销售数据分配奖金分配(x1-x8),但有以下限制:
奖金分配总和CMakeLists.txt
,
最高奖金分配(x1 to x8) = 100%
,
按地点<=10% of total
分配的最高额外奖金。
非常感谢。感谢。
答案 0 :(得分:0)
如果您需要使用优化方法,可以使用scipy.minimize,特别是'SLSQP'方法。这是一种受约束的,基于梯度的最小化算法。
请注意,scipy.minimise
只是scipy.fmin_slsqp方法的包装。
优化的第一步是确定设计变量,目标函数和约束。虽然你的约束条件很明确,但其他两个不太明显。
您尚未指定目标函数的方向。我认为这是为了最大化所有员工分配的奖金百分比。
对于设计变量,您有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
需要一个最小化的函数。在您的情况下,仅使用一个设计变量,整体目标函数将在满足约束条件的同时最大化x0。要将最大化切换为最小化问题,您可以return -result
它还需要你的目标函数的梯度,它也必须被公式化以给出-result
的渐变。
您现在需要构造表示约束的函数。约束被输入为表示每个约束的字典元组。字典以下列形式构建:
{'type': 'ineq', 'fun': const_func, 'jac': const_func_grad, 'args': (m, n, ..)}
来自scipy
文档:
等式约束意味着约束函数结果为零,而不等式意味着它是非负的。
因此,对于您的所有情况,您都希望使用&#39; ineq&#39;并设置函数,然后在满足时返回值> = 0.0。您的位置fun
功能及其jac
功能如下所示:
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]
请注意,loc_a_grad
并未使用x,但SLSQP
方法会尝试将相同数量的args
传递给两个函数。
在没有优化方法的情况下写出问题很简单,而是有一个初始猜测,并为每个约束返回true。我发现唯一有效的非零整数值是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