如何使用 Ruby 中的二分法找到小数的最低固定余额
How to find lowest fixed balance in decimals using bisection in Ruby
如何使用 ruby 中的二等分找到 2 dp 的最低固定月付款以支付 12 个月的复利余额?
免责声明:我正确地应用了 upperBound 和 unpaidBalance 公式。
测试用例:
find_fixed_payment(320000, 0.2) should return 29157.09
但我目前的方法returns中间值29591.87作为固定支付已经绰绰有余了(需要降低到最低)。
我的代码哪里出错了,因为我不确定如何进行二分法(我使用的是二进制搜索)?
def find_fixed_payment(balance,annualInterestRate)
lowerBound = balance/12
upperBound = (balance * (1 + annualInterestRate/12)**12) / 12.0
unpaidBalance = balance
while true
middle = (lowerBound + upperBound )/2
#use middle as the monthly payment at first
(1..12).each do |i|
unpaidBalance = (unpaidBalance - middle) +
annualInterestRate / 12 * (unpaidBalance - middle)
end
temp = unpaidBalance.floor
if temp < 0
middle -= 0.01
upperBound = middle
# should go to for loop to reduce unpaid balance
# with new middle but not happening, why?
else
middle += 0.01
lowerBound = middle
end
if temp == 0
return middle
end
if upperBound == lower+1
return -1
end
return middle.round(2)
end
end
你犯了很多错误,我假设你是从某处的阅读中抄录这个方法的,只是没能理解它描述的过程。
基本上你初始化所有的起始变量,然后你需要创建循环。一旦进入循环,每次计算时,您都需要将余额重置回 320,000,否则它会变成一个移动的目标,我们将永远无法得到您想要的答案。
我在整数 12 上使用了 times 方法来模拟 12 个月的周期,在你的尝试中你使用了一个范围并调用了 each 方法。
现在,我不确定你为什么要那样调整 middle 的值,但这是一个有争议的问题,因为一旦它循环回到你的 while true
循环的开头,它就回到原来的中间值。在我的版本中,我适当地更改了上限或下限。把它想象成猜 1-10 的数字,你足够聪明,知道每次都只选择中间的数字,直到你猜到为止,然后你会从下限 1 和上限 10 开始,然后猜 5。如果我告诉你更高,你现在知道 5 是你的下限,10 仍然是你的上限。
注意:希望这对您有所帮助,欢迎其他用户随时批评和重构我的代码,我最近才开始 ruby。
def find_fixed_payment(balance,annualInterestRate)
monthlyInterestRate = annualInterestRate / 12
lowerBound = balance/12
upperBound = (balance * (1 + monthlyInterestRate)**12) / 12.0
unpaidBalance = balance
accuracy = 0.01
while unpaidBalance.abs > accuracy
balance = unpaidBalance
middle = (lowerBound + upperBound) / 2
12.times do
newUnpaidBalance = unpaidBalance - middle
monthInterest = monthlyInterestRate * newUnpaidBalance
unpaidBalance = newUnpaidBalance + monthInterest
end
if unpaidBalance < 0
upperBound = middle
unpaidBalance = balance
elsif unpaidBalance > accuracy
lowerBound = middle
unpaidBalance = balance
end
end
middle.round(2)
end
find_fixed_payment(320000, 0.2)
如何使用 ruby 中的二等分找到 2 dp 的最低固定月付款以支付 12 个月的复利余额?
免责声明:我正确地应用了 upperBound 和 unpaidBalance 公式。
测试用例:
find_fixed_payment(320000, 0.2) should return 29157.09
但我目前的方法returns中间值29591.87作为固定支付已经绰绰有余了(需要降低到最低)。
我的代码哪里出错了,因为我不确定如何进行二分法(我使用的是二进制搜索)?
def find_fixed_payment(balance,annualInterestRate)
lowerBound = balance/12
upperBound = (balance * (1 + annualInterestRate/12)**12) / 12.0
unpaidBalance = balance
while true
middle = (lowerBound + upperBound )/2
#use middle as the monthly payment at first
(1..12).each do |i|
unpaidBalance = (unpaidBalance - middle) +
annualInterestRate / 12 * (unpaidBalance - middle)
end
temp = unpaidBalance.floor
if temp < 0
middle -= 0.01
upperBound = middle
# should go to for loop to reduce unpaid balance
# with new middle but not happening, why?
else
middle += 0.01
lowerBound = middle
end
if temp == 0
return middle
end
if upperBound == lower+1
return -1
end
return middle.round(2)
end
end
你犯了很多错误,我假设你是从某处的阅读中抄录这个方法的,只是没能理解它描述的过程。
基本上你初始化所有的起始变量,然后你需要创建循环。一旦进入循环,每次计算时,您都需要将余额重置回 320,000,否则它会变成一个移动的目标,我们将永远无法得到您想要的答案。
我在整数 12 上使用了 times 方法来模拟 12 个月的周期,在你的尝试中你使用了一个范围并调用了 each 方法。
现在,我不确定你为什么要那样调整 middle 的值,但这是一个有争议的问题,因为一旦它循环回到你的 while true
循环的开头,它就回到原来的中间值。在我的版本中,我适当地更改了上限或下限。把它想象成猜 1-10 的数字,你足够聪明,知道每次都只选择中间的数字,直到你猜到为止,然后你会从下限 1 和上限 10 开始,然后猜 5。如果我告诉你更高,你现在知道 5 是你的下限,10 仍然是你的上限。
注意:希望这对您有所帮助,欢迎其他用户随时批评和重构我的代码,我最近才开始 ruby。
def find_fixed_payment(balance,annualInterestRate)
monthlyInterestRate = annualInterestRate / 12
lowerBound = balance/12
upperBound = (balance * (1 + monthlyInterestRate)**12) / 12.0
unpaidBalance = balance
accuracy = 0.01
while unpaidBalance.abs > accuracy
balance = unpaidBalance
middle = (lowerBound + upperBound) / 2
12.times do
newUnpaidBalance = unpaidBalance - middle
monthInterest = monthlyInterestRate * newUnpaidBalance
unpaidBalance = newUnpaidBalance + monthInterest
end
if unpaidBalance < 0
upperBound = middle
unpaidBalance = balance
elsif unpaidBalance > accuracy
lowerBound = middle
unpaidBalance = balance
end
end
middle.round(2)
end
find_fixed_payment(320000, 0.2)