簡體   English   中英

為什么我的二等分算法不起作用? 蟒蛇

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM