我试图使用scipy.optimize包来找到我的成本函数的最大值。
在这种情况下: 我有一张价格表,每天都有变动。为了方便起见,假设一天有8小时,每小时的价格如下:
price_list = np.array([1,2,6,8,8,5,2,1])
在这个简单的例子中,我想从价格表中选择4个最高的价格。出于各种原因,我不想简单地排序和选择最好的四个价格,而是使用一些优化算法。我有几个约束条件,因此我决定使用scipy中的最小二乘算法scipy.optimize.fmin_slsqp。
我首先为选择的时间创建计划:
schedule_list = np.zeros( len(price_list), dtype=float)
接下来我需要定义我的逆利润函数。对于所有选定的时间,我想总结一下我的利润。当我想优化我的日程安排时,价格表是固定的,因此我需要把它放到*参数中:
def price_func( schedule_list, *price_list ):
return -1.*np.sum( np.dot( schedule_list, price_list ) )
一旦我明白了事情的原理,我会把一些东西搬来搬去。所以,我只是避免使用更多的*参数,并用硬编码的运行小时数定义我的约束。我希望我选择的时间正好是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最小化包装中,假设不等式大于0,而在fmin_slsqp中,则反之亦然。解被约束到负约束函数?
SLSQP算法是一种基于梯度的优化算法,它期望目标和约束的导数是连续的。据我所知,您似乎在试图解决整数规划问题(计划列表中的连续值是不可接受的)。您需要一个算法,为自变量选择适当的值(0或1),而不是试图找到连续值空间的最小值。不幸的是,我不确定scipy有没有这样的人。
你有一个简单的线性程序,对吗?
所以二阶导数矩阵aka Hessian正好是0。
slsqp
正在尝试反转这一点---不可能。同意,错误消息可能更好。(其他二次方法也会发生同样的情况,在任何包中: 它们在平滑函数上收敛得快得多,但在粗糙的悬崖上会崩溃。)
另见 why-cant-i-rig-scipys-constrained-optimization-for-integer-programming--
但是LP应该做这个工作(最多4个),Integer programming更难。
相关问题 更多 >
编程相关推荐