我尝试使用scipy.optimize包来找到我的成本函数的最大值。
在这种情况下:我有一张一天内价格变化的列表。为了简单起见,让我们假设一天有8个小时,每小时的价格如下:
price_list = np.array([1,2,6,8,8,5,2,1])在这个简化的例子中,我想从该price_list中选择4个最高的价格。出于各种原因,我不想简单地排序和选择最佳的四个价格,而是使用一些优化算法。我有几个约束,因此我决定使用scipy的最小二乘算法scipy.optimize.fmin_slsqp。
我首先为我选择的小时数创建一个计划:
schedule_list = np.zeros( len(price_list), dtype=float)接下来,我需要定义我的反向profit_function。对于所有选定的时间,我想汇总我的利润。虽然我想优化我的时间表,但price_list是固定的,因此我需要将它放到*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。我现在不确定如何实现这一点,因此我简单地使用bounds关键字。
具有边界的无限制优化工作得很好。我只是简单地通过我的schedule_list作为第一次猜测。
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中,不等式被假定大于0。解被约束到负约束函数吗?
发布于 2014-02-17 18:31:14
你有一个简单的线性规划,对吗?
min: - prices . x
constrain: x >= 0, sum x = 4所以二阶导数矩阵,也就是Hessian,恰好是0。
slsqp正试图颠倒这一点-不可能。同意,错误消息可能会更好。
(在任何软件包中,其他二次方法也会发生同样的情况:它们在光滑函数上的收敛速度要快得多,但在粗糙的悬壁上会崩溃。)
另见why-cant-i-rig-scipys-constrained-optimization-for-integer-programming --
但是LP应该可以完成这项工作(最大值为4),Integer programming更难。
发布于 2014-02-15 22:35:09
SLSQP算法是一个基于梯度的优化器,这意味着它希望目标和约束的导数是连续的。根据我的理解,您似乎是在尝试解决整数规划问题(调度列表中的连续值是不可接受的)。您需要一种算法来为自变量选择合适的值(0或1),而不是试图寻找连续值空间的最小值。不幸的是,我不确定在scipy中有没有这样做的。
发布于 2020-01-15 17:48:52
您的代码中有一些错误。正确的:
1. def price_func( schedule_list, price_list )
2. def eqcon(schedule_list , price_list):
       return sum( schedule_list ) - 4
3. scipy.optimize.fmin_slsqp( price_func, schedule_list, args=(price_list,), bounds=[[0,1]]*len(schedule_list), eqcons=[eqcon, ] )然后它就起作用了。
https://stackoverflow.com/questions/21758760
复制相似问题