在下面的示例中使用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'