在 Python 中用递归实现二分算法
Implementing the bisection algorithm with recursion in Python
我在 Python 中用递归实现了二分法算法,在一个玩具示例中,我的目标是找到我应该在 12 个月内每月支付的最低每月分期付款,以便在12 个月我的余额为零或略少。
假设我的期初余额是320000,年利率是0.2。正确答案是 29157.09.
我的代码 运行 出现异常,但无法收敛。
代码如下(我插入了打印语句方便调试)
balance = 320000
annualInterestRate = 0.2
Balance = balance
Annual_interest_rate = annualInterestRate
Monthly_interest_rate = (Annual_interest_rate) / 12.0
Monthly_payment_lower_bound = Balance / 12
Monthly_payment_upper_bound = (Balance * (1 + Monthly_interest_rate)) / 12.0
def bisect(Balance, Annual_interest_rate, a, b ):
Previous_balance = Balance
for i in range(12):
Monthly_unpaid_balance = (Previous_balance) - a
Updated_balance_each_month = (Monthly_unpaid_balance) + (Monthly_interest_rate * Monthly_unpaid_balance)
Previous_balance = Updated_balance_each_month
f_a = Previous_balance
for i in range(12):
Monthly_unpaid_balance = (Previous_balance) - b
Updated_balance_each_month = (Monthly_unpaid_balance) + (Monthly_interest_rate * Monthly_unpaid_balance)
Previous_balance = Updated_balance_each_month
f_b = Previous_balance
c = (a + b)/2
for i in range(12):
Monthly_unpaid_balance = (Previous_balance) - c
Updated_balance_each_month = (Monthly_unpaid_balance) + (Monthly_interest_rate * Monthly_unpaid_balance)
Previous_balance = Updated_balance_each_month
f_c = Previous_balance
print('a is {0}, b is {1}, c = {2}, f_a = {3}, f_b = {4}, f_c = {5}'.format(a, b, c, f_a, f_b, f_c))
if abs(f_c) <=0.01:
return(c)
elif f_c * f_a >0:
a =c
print('a is {0}, b is {1}, c = {2}, f_a = {3}, f_b = {4}, f_c = {5}'.format(a, b, c, f_a, f_b, f_c))
return(bisect(Balance, Annual_interest_rate, a, b ))
else:
b = c
print('a is {0}, b is {1}, c = {2}, f_a = {3}, f_b = {4}, f_c = {5}'.format(a, b, c, f_a, f_b, f_c))
return(bisect(Balance, Annual_interest_rate, a, b ))
当我 运行 函数时,我得到以下打印输出:
bisect(Balance, Annual_interest_rate, Monthly_payment_lower_bound, Monthly_payment_upper_bound )
a is 26666.666666666668, b is 27111.11111111111, c = 26888.88888888889, f_a = 33328.98239049623, f_b = -322183.0368628964, f_c = -752717.255677314
a is 26666.666666666668, b is 26888.88888888889, c = 26888.88888888889, f_a = 33328.98239049623, f_b = -322183.0368628964, f_c = -752717.255677314
a is 26666.666666666668, b is 26888.88888888889, c = 26777.77777777778, f_a = 33328.98239049623, f_b = -319209.06882307003, f_c = -747603.8415428438
a is 26666.666666666668, b is 26777.77777777778, c = 26777.77777777778, f_a = 33328.98239049623, f_b = -319209.06882307003, f_c = -747603.8415428438
a is 26666.666666666668, b is 26777.77777777778, c = 26722.222222222226, f_a = 33328.98239049623, f_b = -317722.08480315685, f_c = -745047.1344756087
a is 26666.666666666668, b is 26722.222222222226, c = 26722.222222222226, f_a = 33328.98239049623, f_b = -317722.08480315685, f_c = -745047.1344756087
以下使用前端函数,因此用户不必处理 "magic" 参数,例如您的 a
和 b
。它将年利率重新调整为月利率,并通过将递归输入缩放 100 将计算转换为整数,然后在返回之前重新调整解决方案。
def calculate_payment(balance, interest):
balance = int(100 * balance)
return bisect(balance, interest / 12.0, 0, balance) * 0.01
def bisect(balance, monthly_interest, low, high):
payment = round((high + low) / 2)
remaining_balance = balance
for _ in range(12):
remaining_balance -= payment
remaining_balance += int(monthly_interest * remaining_balance)
if remaining_balance > 0:
return bisect(balance, monthly_interest, payment, high)
elif remaining_balance <= -12:
return bisect(balance, monthly_interest, low, payment)
else:
return payment
print(calculate_payment(320000.00, 0.2))
我在 Python 中用递归实现了二分法算法,在一个玩具示例中,我的目标是找到我应该在 12 个月内每月支付的最低每月分期付款,以便在12 个月我的余额为零或略少。
假设我的期初余额是320000,年利率是0.2。正确答案是 29157.09.
我的代码 运行 出现异常,但无法收敛。
代码如下(我插入了打印语句方便调试)
balance = 320000
annualInterestRate = 0.2
Balance = balance
Annual_interest_rate = annualInterestRate
Monthly_interest_rate = (Annual_interest_rate) / 12.0
Monthly_payment_lower_bound = Balance / 12
Monthly_payment_upper_bound = (Balance * (1 + Monthly_interest_rate)) / 12.0
def bisect(Balance, Annual_interest_rate, a, b ):
Previous_balance = Balance
for i in range(12):
Monthly_unpaid_balance = (Previous_balance) - a
Updated_balance_each_month = (Monthly_unpaid_balance) + (Monthly_interest_rate * Monthly_unpaid_balance)
Previous_balance = Updated_balance_each_month
f_a = Previous_balance
for i in range(12):
Monthly_unpaid_balance = (Previous_balance) - b
Updated_balance_each_month = (Monthly_unpaid_balance) + (Monthly_interest_rate * Monthly_unpaid_balance)
Previous_balance = Updated_balance_each_month
f_b = Previous_balance
c = (a + b)/2
for i in range(12):
Monthly_unpaid_balance = (Previous_balance) - c
Updated_balance_each_month = (Monthly_unpaid_balance) + (Monthly_interest_rate * Monthly_unpaid_balance)
Previous_balance = Updated_balance_each_month
f_c = Previous_balance
print('a is {0}, b is {1}, c = {2}, f_a = {3}, f_b = {4}, f_c = {5}'.format(a, b, c, f_a, f_b, f_c))
if abs(f_c) <=0.01:
return(c)
elif f_c * f_a >0:
a =c
print('a is {0}, b is {1}, c = {2}, f_a = {3}, f_b = {4}, f_c = {5}'.format(a, b, c, f_a, f_b, f_c))
return(bisect(Balance, Annual_interest_rate, a, b ))
else:
b = c
print('a is {0}, b is {1}, c = {2}, f_a = {3}, f_b = {4}, f_c = {5}'.format(a, b, c, f_a, f_b, f_c))
return(bisect(Balance, Annual_interest_rate, a, b ))
当我 运行 函数时,我得到以下打印输出:
bisect(Balance, Annual_interest_rate, Monthly_payment_lower_bound, Monthly_payment_upper_bound )
a is 26666.666666666668, b is 27111.11111111111, c = 26888.88888888889, f_a = 33328.98239049623, f_b = -322183.0368628964, f_c = -752717.255677314
a is 26666.666666666668, b is 26888.88888888889, c = 26888.88888888889, f_a = 33328.98239049623, f_b = -322183.0368628964, f_c = -752717.255677314
a is 26666.666666666668, b is 26888.88888888889, c = 26777.77777777778, f_a = 33328.98239049623, f_b = -319209.06882307003, f_c = -747603.8415428438
a is 26666.666666666668, b is 26777.77777777778, c = 26777.77777777778, f_a = 33328.98239049623, f_b = -319209.06882307003, f_c = -747603.8415428438
a is 26666.666666666668, b is 26777.77777777778, c = 26722.222222222226, f_a = 33328.98239049623, f_b = -317722.08480315685, f_c = -745047.1344756087
a is 26666.666666666668, b is 26722.222222222226, c = 26722.222222222226, f_a = 33328.98239049623, f_b = -317722.08480315685, f_c = -745047.1344756087
以下使用前端函数,因此用户不必处理 "magic" 参数,例如您的 a
和 b
。它将年利率重新调整为月利率,并通过将递归输入缩放 100 将计算转换为整数,然后在返回之前重新调整解决方案。
def calculate_payment(balance, interest):
balance = int(100 * balance)
return bisect(balance, interest / 12.0, 0, balance) * 0.01
def bisect(balance, monthly_interest, low, high):
payment = round((high + low) / 2)
remaining_balance = balance
for _ in range(12):
remaining_balance -= payment
remaining_balance += int(monthly_interest * remaining_balance)
if remaining_balance > 0:
return bisect(balance, monthly_interest, payment, high)
elif remaining_balance <= -12:
return bisect(balance, monthly_interest, low, payment)
else:
return payment
print(calculate_payment(320000.00, 0.2))