如何使用约束和多个最优值正确设置scipy.optimize最小化?

时间:2016-04-16 14:10:36

标签: python optimization scipy constraints minimization

我对Python很新,并且在使用scipy.optimize的最小化部分时遇到了一些麻烦。我已经设置了一个简单的例子来展示我想要做的事情。我的目标是确定最小化库存的最低购买数量。

我购买的所有东西都分为两种产品 - 其中25%用于产品A,75%用于产品B.一个产品A的单位尺寸为100,而产品B的单位尺寸为300.我最低购买数量为100,最大购买数量为2000.

以下代码是我的目标函数的设置。

import math
from scipy.optimize import minimize

unitsize =  [100, 300]
proportion = [0.25, 0.75]
minpurchase = 100
maxpurchase = 2000

def stock (purchase):
    test = []
    for i in xrange(len(unitsize)):    
        product_purchase = purchase * proportion[i]
        units = math.floor(product_purchase / unitsize[i])
        y = product_purchase - (units * unitsize[i])
        test.append(y)
        z = sum(test)
    return z

我已经测试了库存功能,它似乎可以按预期工作。例如,当我调用股票(500),股票(400)和股票(300)时,它分别正确地返回100,0和300.

然后我尝试按照以下方式实施最小化,并根据最小和最大购买金额进行约束。

然而,当我以初始猜测零开始时,它返回100的结果,我认为这是错误的结果,因为它将导致100个库存而没有完整的单位。我期待着,例如400的结果(股票为零)。当我例如发生同样的问题时首先猜测为100。

cons = ({'type': 'ineq', 'fun': lambda x:  x[0] - minpurchase},
        {'type': 'ineq', 'fun': lambda x:  x[0] + maxpurchase}
        )


print minimize(lambda x: stock(x[0]), [0],
                   method='COBYLA',
                   constraints = cons,
                   options={'maxiter':10000})
  status: 1
    nfev: 106
   maxcv: -0.0
 success: True
     fun: 100.0
       x: array([ 100.])
 message: 'Optimization terminated successfully.'

当我从初始猜测500开始时,返回的结果在400处是正确的。但是,当我例如从1900开始,它也返回1600作为结果,因为此时股票也为零。

几个问题:

  1. 有没有办法让它的初始猜测为0?
  2. 在此示例中,解空间中存在多个最佳值(400,800,1200,1600,2000)。是否有可能设置优化,以便找到最终的最佳矢量,然后返回最低的项目(即400)?
  3. 在尝试解决问题2时,我考虑将一系列测试值传递到初始猜测中,如下所示,但它返回“IndexError:数组索引太多”。

    知道我在这里做错了吗?

    testvalues = [1000,2000]
    
    for j in range(len(testvalues)):
        print minimize(lambda x: stock(x[0]), testvalues[j],
                           method='COBYLA',
                           constraints = cons,
                           options={'maxiter':10000})
    
    [...]
    IndexError: too many indices for array
    

    任何帮助和指示非常感谢,我一直试图让这一整天都在工作。

1 个答案:

答案 0 :(得分:1)

此错误引发,因为COBYLA方法不处理边界。只有BFGS,L-BFGS-B和SLSQP方法可以。看到: documentation link