我将使用scipy.optimize包来寻找成本函数的最大值。
在这个特定的例子中: 我有一个价格列表,这些价格在一天内变化。为了简单起见,假设一天有8小时,并且每小时的价格如下:
在这个简化的案例中,我想从价格列表中选择前四个最高的价格。由于各种原因,我不想简单地对价格进行排序并选择最好的四个价格,而是使用一些优化算法。我有几个约束条件,因此我决定使用scipy中的最小二乘算法,即scipy.optimize.fmin_slsqp。
首先,我为我选择的小时创建一个时间表:
在这个特定的例子中: 我有一个价格列表,这些价格在一天内变化。为了简单起见,假设一天有8小时,并且每小时的价格如下:
price_list = np.array([1,2,6,8,8,5,2,1])
在这个简化的案例中,我想从价格列表中选择前四个最高的价格。由于各种原因,我不想简单地对价格进行排序并选择最好的四个价格,而是使用一些优化算法。我有几个约束条件,因此我决定使用scipy中的最小二乘算法,即scipy.optimize.fmin_slsqp。
首先,我为我选择的小时创建一个时间表:
schedule_list = np.zeros( len(price_list), dtype=float)
接下来,我需要定义我的倒数利润函数。对于所有选择的时间,我想要将我的利润加总起来。虽然我想要优化我的日程安排,但价格列表是固定的,因此我需要将其放在*args中:
def price_func( schedule_list, *price_list ):
return -1.*np.sum( np.dot( schedule_list, price_list ) )
一旦我理解了原理,我会移动一些东西。目前为止,我避免使用更多的*args,并通过硬编码运行小时数来定义我的约束条件。我想要选择的小时数恰好为4,因此我使用等式约束:
def eqcon(x, *price_list):
return sum( schedule_list ) - 4
此外,我希望将我的时间表值限制为0或1。目前我不确定如何实现,因此我只是使用了边界关键字。
有界优化很好用,我只需将我的时间表列表作为第一个猜测即可。
scipy.optimize.fmin_slsqp( price_func, schedule_list, args=price_list, bounds=[[0,1]]*len(schedule_list) )
输出结果是最好的:
Optimization terminated successfully. (Exit mode 0)
Current function value: -33.0
Iterations: 2
Function evaluations: 20
Gradient evaluations: 2
Out[8]: array([ 1., 1., 1., 1., 1., 1., 1., 1.])
不加任何限制,这是最优解决方案!
使用以下命令的约束优化:
scipy.optimize.fmin_slsqp( price_func, schedule_list, args=price_list, bounds=[[0,1]]*len(schedule_list), eqcons=[eqcon, ] )
出现错误:
Singular matrix C in LSQ subproblem (Exit mode 6)
Current function value: -0.0
Iterations: 1
Function evaluations: 10
Gradient evaluations: 1
Out[9]: array([ 0., 0., 0., 0., 0., 0., 0., 0.])
我知道从gnuplot得出这通常与无意义的问题或不良初始值有关。我尝试了几乎最优的初始值,但没有帮助。有人有任何想法或者甚至是解决方案吗?
接下来,我已经制定了不等式约束条件。我是否正确地理解,在scipy minimize包装器中,不等式被认为大于0,而在fmin_slsqp中则相反。解决方案受到负约束函数的限制?