SciPy优化最小化找到非最小答案

时间:2018-09-26 20:52:08

标签: python optimization scipy mathematical-optimization

在下面的示例中使用Scipy Minimum时,它找到了一个非最小的解决方案-有人可以帮我修改一下以找到最小的解决方法吗?

我有四个约束:1)猜测数组的猜测总和必须为1,2)猜测必须> 0,以及3)初始猜测数组中任何超过阈值的猜测都必须设置为等于阈值并保持恒定。
编辑:第四个约束条件-猜测不能大于阈值。

我没有对最后三个约束使用约束。对于约束2,我使用了界限。对于约束3,在调用scipy的minimum方法之前,我在performMinimize方法中做到了。

from scipy.optimize import minimize
import numpy as np
from numpy import array

def objective(initialGuesses, threshold):
    overThreshold = initialGuesses[np.where((threshold < initialGuesses[:]))]
    underThreshold = initialGuesses[np.where((threshold >= initialGuesses[:]))]

    overThreshold[:] = threshold
    sumUnderThreshold = np.sum(underThreshold)
    oppositeSumOverTreshold = 1 - np.sum(overThreshold)

    transformedGuess = underThreshold / sumUnderThreshold * oppositeSumOverTreshold

    thresholdedResults = np.concatenate((overThreshold, transformedGuess))

    squaredError = np.square(thresholdedResults - initialGuesses) / initialGuesses

    return np.sum(squaredError)


def performMinimizeSo(initialGuesses, threshold):
    overThreshold = initialGuesses[np.where((threshold < initialGuesses[:]))]
    overThreshold[:] = threshold
    underThreshold = initialGuesses[np.where((threshold >= initialGuesses[:]))]

    # Says one minus the sum of all variables minus the sum of weights over the threshold must be zero
    cons = ({'type': 'eq', 'fun': lambda x: 1 - sum(x) - sum(overThreshold)})

    minimum = minimize(objective, underThreshold, args=(threshold), method='SLSQP',
                       constraints=cons,
                       bounds=[(0, None) for i in range(len(underThreshold))],
                       )

    allGuesses = np.append(overThreshold, minimum.x)

    return allGuesses


def testCaseForSo():
    initialGuesses = array([
        [0.1],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.05],
        [0.025],
        [0.025]])

    threshold = .09
    output = (performMinimizeSo(initialGuesses, threshold))
    print(output)

testCaseForSo()

excel找到的最小答案是:

0.09
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.050555556
0.025277778
0.025277778

Scipy Minimum认为这是答案,这很接近,但不是正确的最小值:

0.09
0.050526315
0.050526315
0.050526315
0.050526315
0.050526315
0.050526315
0.050526315
0.050526315
0.050526315
0.050526315
0.050526317
0.050526317
0.050526317
0.050526317
0.050526317
0.050526317
0.050526317
0.025526317
0.025526317

在运行scipy.minimize之后,输出的属性如下所示(如您所见,即使我们不知道,scipy也认为它找到了最小值):

minimum.sucess == True
minimum.status == 0
minimum.message == 'Optimization terminated successfully'

0 个答案:

没有答案