我有一系列收取利率的帐户,我每天必须决定从哪个帐户借钱。我对每个帐户都有借款限额。 显然,最简单的答案是先用尽最便宜的价格,依此类推。
由于我们每天必须计算几次,因此帐户数量会有所不同,我们计划前滚现金流,我试图编写一些Python代码以使其自动化。
要最小化的目标函数是加权平均利率,确定从每个帐户(x
)借来的钱,从0到整数(取决于每个协议)的范围以覆盖未偿还金额。
下面的代码似乎运行良好,但是我在一张纸上做了数学运算,但未达到全局最小值。我有什么想念的吗?
import numpy as np
from scipy.optimize import minimize
outstanding = -106332403
limit = [15000000, 29250000, 15000000, 22000000, 52567324, 5000000, 5000000, 40000000, 7398262]
interest = [0.73, 0.63, 0.78, 0.75, 0.6084, 0.97, 0.84, 0.625, 0.40]
limit = np.asarray(limit)
interest = np.asarray(interest)
def objective(x):
product = x * interest
sumproduct = sum(product)
return sumproduct / -outstanding
def constraint1(x):
return sum(x) + outstanding
# initial guesses
n = len(interest)
x0 = [1,1,1,1,1,1,1,1,1]
bnds = []
for value in limit:
b= (0,value)
bnds.append(b)
con1 = {'type': 'eq', 'fun': constraint1}
cons = (con1)
solution = minimize(objective,x0,method='SLSQP',bounds=bnds,constraints=cons)
x = solution.x
答案 0 :(得分:0)
我对您的脚本进行了一些更改。最重要的是设置一个更大的最大迭代,并在有限差分步长和收敛容限上发挥作用。我还重写了您的目标,以改变数量级。通过这种方式,我可以获得接近您在评论中提供的值的解决方案。
import numpy as np
from scipy.optimize import minimize
outstanding = -106332403
limit = np.array([15000000, 29250000, 15000000, 22000000, 52567324, 5000000, 5000000, 40000000, 7398262])
interest = np.array([0.73, 0.63, 0.78, 0.75, 0.6084, 0.97, 0.84, 0.625, 0.40])
# initial guesses
n = len(interest)
x0 = np.ones(len(interest)) * 1e6 * 1
def objective(x):
return np.dot(x, interest)
def constraint1(x):
con = sum(x) + outstanding
return con
bnds = [(0, value) for value in limit]
con1 = {'type': 'eq', 'fun': constraint1}
solution = minimize(objective,x0,method='SLSQP',bounds=bnds,constraints=con1,
options={"eps": 01e-3, "maxiter": 1000}, tol=1e-8)
print(solution)
结果:
fun: 63952359.431600004
jac: array([0.72999299, 0.62999874, 0.77999383, 0.74999779, 0.60839951,
0.96999854, 0.84000081, 0.6249994 , 0.40000677])
message: 'Optimization terminated successfully.'
nfev: 1635
nit: 147
njev: 145
status: 0
success: True
x: array([0.00000000e+00, 6.36681700e+06, 0.00000000e+00, 0.00000000e+00,
5.25673240e+07, 1.77575799e-16, 2.32417370e-17, 4.00000000e+07,
7.39826200e+06])