[英]Why doesn't my bisection algorithm work? Python
我正在為我的Python類編寫一個信用卡支付計算器。 任務是為計算器寫一個定義,計算出使您的余額在x個月內達到零所需的每月付款。
該定義采用3個參數:initialBalance,apr,months。
據我所知,分配的重點是讓我們使用二等分法找到答案,並且我寫了另外兩個有助於分配的定義:
1)newBalance()-確定付款后的新余額; 2)balances()-返回付款后的余額清單;
因此,balances()[-1]返回最終余額,因此我的行動計划是將列表中的最后一項評估為等於0(或至少在0.005的0!之內!),如果是,則返回付款使我到了那里。
如果最終余額為負(我支付了太多!):付款=付款-(付款/ 2); 如果余額為正(我還沒有付清!):付款=付款+(付款/ 2);
盡我所能,我的算法應該最終得出結論,但是它永遠找不到足夠接近的答案...
這是我的代碼,(以及教授的測試定義最后):
def newBalance(prevBalance, apr, payment):
"""
- prevBalance: the balance on the credit card statement.
- apr: the annual percentage rate (15.9 here means 15.9%).
- payment: the amount paid this month to the credit card company.
- returns: the new balance that will be owed on the credit card
(assumes no purchases are made).
"""
interestCharge = float(((apr / 12.0) / 100) * prevBalance)
return float((interestCharge + prevBalance) - payment)
def balances(initialBalance, apr, payments):
"""
- initialBalance: the initial balance on the credit card.
- apr: the annual percentage rate (15.9 here means 15.9%).
- payments: a list of monthly payments made on the credit card.
- returns: a list giving the balance on the credit card each
month. The first number in the list is the initial
balance, the next number is the balance after the first
payment is made, and so on. Note that the length of the returned
list is len(payments) + 1.
"""
balancelist = []
balancelist.append(initialBalance)
for x in range(0, len(payments)):
balancelist.append(newBalance(balancelist[x], apr, payments[x]))
return balancelist
def findMonthlyPayment(initialBalance, apr, months):
"""
- initialBalance: the starting balance on the card.
- apr: the APR.
- months: the number of equal monthly payments you wish to
make in order to reduce the balance to zero.
- returns: the monthly payment amount needed to reduce the
balance to zero (well, "zero" to within $0.005, anyway)
in the given number of months.
"""
guess = float(initialBalance / months)
listo = months*[guess]
while True:
if abs(float(balances(initialBalance, apr, listo)[-1]) - initialBalance) < 0.006:
print "BINGO", guess ##for debugging
print balances(initialBalance, apr, listo)[-1]
return guess
else:
if float(balances(initialBalance, apr, listo)[-1]) < -0.005:
guess = guess - (guess / 2)
print "BOO", guess ##for debugging
print balances(initialBalance, apr, listo)[-1]
else:
guess = guess + (guess / 2)
print "NAY", guess ##for debugging
print balances(initialBalance, apr, listo)[-1]
listo = months*[guess]
def testFindMonthlyPayment():
answer = findMonthlyPayment(1000, 18.9, 60)
print
myString = "Monthly payment to pay off $%.2f in %d months at %.2f%% APR:"
print myString % (1000, 60, 18.9)
print "$%.2f" % answer
# Output should look approximately like this:
"""
iteration: 1 guess: 500.0 final bal: -46777.3384635
iteration: 2 guess: 250.0 final balance: -22111.7016729
iteration: 3 guess: 125.0 final balance: -9778.88327752
iteration: 4 guess: 62.5 final balance: -3612.47407985
iteration: 5 guess: 31.25 final balance: -529.269481021
iteration: 6 guess: 15.625 final balance: 1012.3328184
iteration: 7 guess: 23.4375 final balance: 241.531668687
iteration: 8 guess: 27.34375 final balance: -143.868906167
iteration: 9 guess: 25.390625 final balance: 48.83138126
iteration: 10 guess: 26.3671875 final balance: -47.5187624535
iteration: 11 guess: 25.87890625 final balance: 0.656309403241
iteration: 12 guess: 26.123046875 final balance: -23.4312265251
iteration: 13 guess: 26.0009765625 final balance: -11.387458561
iteration: 14 guess: 25.9399414062 final balance: -5.36557457885
iteration: 15 guess: 25.9094238281 final balance: -2.35463258781
iteration: 16 guess: 25.8941650391 final balance: -0.849161592282
iteration: 17 guess: 25.8865356445 final balance: -0.0964260945206
iteration: 18 guess: 25.8827209473 final balance: 0.27994165436
iteration: 19 guess: 25.8846282959 final balance: 0.0917577799204
iteration: 20 guess: 25.8855819702 final balance: -0.00233415730086
Monthly payment to pay off $1000.00 in 60 months at 18.90 APR:
$25.89
"""
謝謝您的幫助。 除非我用Google搜索的所有內容都在stackoverflow上,否則大概不會加入compsci。
這不是你一分為二的方法
guess = guess - (guess / 2)
通常,您保持low_guess和high_guess。 你試試
guess = (low_guess+high_guess)/2
然后根據結果,您可以設置
low_guess = guess
要么
high_guess = guess
並重復
注意:在Python2中,如果分母和分子均為整數,則/
是整數除法,因此最好確保最初的guess
是浮點數
def findMonthlyPayment(initialBalance, apr, months):
"""
- initialBalance: the starting balance on the card.
- apr: the APR.
- months: the number of equal monthly payments you wish to
make in order to reduce the balance to zero.
- returns: the monthly payment amount needed to reduce the
balance to zero (well, "zero" to within $0.005, anyway)
in the given number of months.
"""
low_guess = 0
high_guess = initialBalance
guess = float((low_guess + high_guess) / 2)
listo = months*[guess]
while True:
if abs(float(balances(initialBalance, apr, listo)[-1])) < 0.006:
print "BINGO", guess ##for debugging
print balances(initialBalance, apr, listo)[-1]
return guess
elif float(balances(initialBalance, apr, listo)[-1]) < -0.005:
high_guess = guess
print "BOO", guess ##for debugging
print balances(initialBalance, apr, listo)[-1]
else:
low_guess = guess
print "NAY", guess ##for debugging
print balances(initialBalance, apr, listo)[-1]
guess = float((low_guess + high_guess) / 2)
listo = months*[guess]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.