我正在尝试使用以下方法计算每月最低付款以偿还贷款:
balance = 999999
annualInterestRate = .18
monthlyInterestRate = annualInterestRate/12
balanceCOPY = balance
#Bisection search parameters
lo = balance/12
hi = (balance*(1+monthlyInterestRate**12))/12
epsilon = .01
guess = (lo + hi)/2
while True:
for month in range(1,13):
balance = balance - guess
balance = balance + (monthlyInterestRate*balance)
if balance > 0 and balance > epsilon:
lo = guess
balance = balanceCOPY
elif balance < 0 and balance < -epsilon:
hi = guess
balance = balanceCOPY
else:
print('Lowest payment: ',str(round(guess,2)))
break
guess = (lo + hi)/2
Run Code Online (Sandbox Code Playgroud)
但是,我似乎陷入某种无限循环,我的guess变量没有被更新.如何突破无限循环并guess更新变量?
问题出在我的数学上.我的意思是说
hi = (balance*(1+monthlyInterestRate)**12)/12
Run Code Online (Sandbox Code Playgroud)
谢谢大家的帮助!
小智 7
首先,如果您正在进行MITx练习并完成之前的测试(只是在猜测中增加10),那么您只需要迈出一小步.只需要对条件进行一些调整并检查年度结果.
关于二分法搜索我将尝试澄清这个概念.你总会有两个肢体,最小值和最大值.而且总是会在四肢中间开始猜测.
在第一次猜测之后,您需要根据年度结果调整四肢.如果在一年之后支付最低限度的饮料,女孩,程序书籍和其他你没有支付总余额的东西,你肯定需要增加最低限度.否则,例如,如果您在第10个月支付总余额,那么明年你需要多喝酒并结识新女孩!开玩笑......你需要减少最低限度.这是您在完成一年的硬支付后需要进行的检查
在练习中,我们有:
第一个猜测是(最小+最大)/ 2我调用guessMinimum所以:
guessMinimum = (minimum + maximum)/2
Run Code Online (Sandbox Code Playgroud)
所以你将开始使用第一个猜测(guessMinimum).一年后,你会检查剩余的.如果遗骸是负数,则表示您已经支付了太多.你需要减少每月付款.另外,如果一个月后剩余是积极的(例如,超过你的精确度(例如0.10))你需要减少每月付款,好吗?!
试图设计思路.....
+------------------------------------------------+
| /\ /\ /\ |
| \/------------------\/-------------------\/ |
|MINIMUM guess MAXIMUM|
| Minimum |
+------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
如果一年后,"保持"是负面的(例如).意味着'guessMinimum'非常多!你需要......不是你,程序!! 程序需要调整它,降低最小值......
+---------------------------------------------------+
| Got negative 'remain' |
| ++ |
| /\ || /\ /\ |
| \/-------------||---\/-------------------\/ |
| MINIMUM || guess MAXIMUM |
| ++ Minimum-, |
| ', |
| `. |
| `., |
| ', |
| ', |
| `. |
| ` |
| /\ /\ /\ |
| \/------------------\/-------------------\/ |
| MINIMUM guess MAXIMUM |
+---------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
对不起大家.我试图插入图像,但作为新成员.我不能.需要至少10个声望....帮助我!!!! 使用角色的工作太多!!!!
并且CODE需要做这项艰苦的工作来调整最小值,直到'保持'可接受(在你的精度,epsilon,或任何字母或变量或......之内)好吧.:)
在理解了概念和图纸之后..让我们检查一下CODE.
balance = 999999;
annualInterestRate = 0.18
monthlyInterestRate = annualInterestRate / 12
minimum = balance / 12
maximum = (balance * (1 + monthlyInterestRate)**12) / 12.0
guessMinimum = (minimum + maximum)/2
remain = balance #if you payed nothin, the remain is the balance!!!!
precision = 0.10 #you choose....
while (remain >= precision):
guessMinimum = (minimum + maximum)/2
for i in range (1,13):
newBalance = remain - guessMinimum
monthInterest = annualInterestRate/12*newBalance
remain = newBalance+monthInterest
# after one month, the CODE need to check about the remain
if (remain < 0): #paying too much.... need to decrease the value
maximum = guessMinimum #remember my beautiful draw above!!
remain = balance # reset the remain to start again!!
elif (remain > precision): #paying less .... need to increase the value
minimum = guessMinimum
remain = balance # reset the remain to start again!!
print "Lowest Payment: %.2f" %(guessMinimum)
Run Code Online (Sandbox Code Playgroud)
而已.
我认为这个解决方案应该有效,
balance = 999999
annualInterestRate = 0.18
monthlyInterestRate = annualInterestRate / 12
lowerBound = balance / 12
upperBound = (balance * (1 + annualInterestRate / 12) ** 12) / 12
originalBalance = balance
lowestBalance = 0.01 # Error margin e.g. $0.01
# Keep testing new payment values until the balance is +/- lowestBalance
while abs(balance) > lowestBalance:
# Reset the value of balance to its original value
balance = originalBalance
# Calculate a new monthly payment value from the bounds
payment = (upperBound - lowerBound) / 2 + lowerBound
# Test if this payment value is sufficient to pay off the entire balance in 12 months
for month in range(12):
balance -= payment
balance *= 1 + monthlyInterestRate
# Reset bounds based on the final value of balance
if balance > 0:
# If the balance is too big, need higher payment so we increase the lower bound
lowerBound = payment
else:
# If the balance is too small, we need a lower payment, so we decrease the upper bound
upperBound = payment
# When the while loop terminates, we know we have our answer!
print "Lowest Payment:", round(payment, 2)
Run Code Online (Sandbox Code Playgroud)
要找出这样的错误,一个好方法就是添加一些打印内容,例如,我将以下内容添加到您的代码中:
print(balance, lo, hi, guess)
Run Code Online (Sandbox Code Playgroud)
然后看看会发生什么,你就能弄清楚发生了什么。事实证明:
hi = (balance*(1+monthlyInterestRate**12))/12
Run Code Online (Sandbox Code Playgroud)
计算的上限太低。也许你的意思是:
hi = (balance*(1+monthlyInterestRate*12))/12
Run Code Online (Sandbox Code Playgroud)