码迷,mamicode.com
首页 > 编程语言 > 详细

一次二分法在python中的利用

时间:2015-05-10 22:14:53      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:

  此次博客来自我选修课的一次作业,初学python, 我的程序难免有许多不合理的地方,希望大家指正。

  问题描述:

  每个月信用卡都会提示你还钱,至少要还的是你借款数额的2%。但是信用卡机构要收取未还清金额的利息,即使你及时还了要求偿还的最少金额的钱,你仍旧要支付利息,利息要累积在仍欠的钱上面,也就是还没有还款的一部分。

  譬如,你用信用卡透支了5000美金,年利率是18%,每个月最少要还款2%,如果你每个月都是按照最小额度,也就是2%进行支付,1年之后还有多少钱没还。

设计思想:

  你可以这样来考虑。

 

   ub0=b0-p0

  开始的第一个月记做0(这个时候信用卡状态开始显示欠款)。假设你的欠款是 b0(b代表需平账目,角标0代表0月),你在这一个月里要支付的金额由b,也就是需平账目金额决定。第0个月还款p0,那你的欠款ub0 = b0 – p0(ub0代表你的欠款,也就是未平账金额)。

  b1=ub0+r/12.0*ub0

 

   在“1”月开始,银行会收取你所欠款金额的利息,如果你的年利率是r%,那么你在“1”月开始,你的需平账目金额为“0”月未支付金额和由这笔欠款产生的利息,即“1”需平账目金额为 b1=ub0+r/12.0*ub0。

   在“1”月,我们将再次进行付款p1,这次支付需包含部分利息。因此它不完全是原始金额,余额ub1 = b1 – p1

   在“ 2”月开始的需平账金额计算,可以由支付了p1之后计算未平金额,即余额b2 = ub1 + r/12 * ub1

  1.编写一个程序计算如果一个人每个月只支付银行要求的最低还款金额,一年后该信用卡所欠余额。

代码实现:

balance=4213 #在此输入欠款
annualInterestRate=0.2 #年利率
monthlyPaymentRate=0.04 #最少还款百分比
print "balance=%d"%(balance)
print "annualInterestRate=%.1f"%(annualInterestRate)
print "monthlyPaymentRate=%.2f"%(monthlyPaymentRate)
monthlyInterestRate=annualInterestRate/12
total=0
for i in range(12):
    MIN=monthlyPaymentRate*balance
    total+=MIN
    balance-=MIN
    balance=balance+balance*monthlyInterestRate
    print"Month:%d"%(i+1)
    print"Minimum monthly payment:%.2f"%(MIN)
    print"Remaining balance:%.2f"%(balance)
print"Total paid:%.2f"%(total)
print"Remaining balance:%.2f"%(balance)

   2.写一个程序实现12个月还清信用卡透支金额,计算出每月最少支付的固定金额,the number is fixed 固定的数值。

设计思想:

    假定利息是月末累积,每个月支付金额的必须是10美金的倍数,(这种方案如果出现最后一个月支付出现欠额为负值,也是ok的,就是说如果按10美金每月支付固定金额,最后一个月可能出现多付钱的情况)。

样例程序:

def pay(balance,payment):
    for i in range(12):
         balance-=payment
         balance=balance+balance*monthlyInterestRate 
    return balance
balance=3329  #测试时请修改此处
annualInterestRate=0.2  #年利率
monthlyInterestRate=annualInterestRate/12 #月利率
print "balance=%d"%(balance)
print "annualInterestRate=%.2f"%(annualInterestRate)
payment=int(balance/12)/10*10
while pay(balance,payment)>0:
    payment+=10
print "Lowest Payment:%d"%(payment)

 分析:

  在2中,你每月支付必须是10整数倍。why?你可以试试在本地运行的代码,每月支付0.01美元的倍数,你的Program是否还能正常run?应该是可以的,但是你的Program会运行的很慢,特别是当balance和rate很大的时候(就是数据计算量大的时候)。

  对于Problem我们要怎么才能算出才能使自己的程序时间效率O()好一点,当然是二分大法好!O(logn)的速度不是盖的…..最简单粗暴的就是从0-b0依次枚举ans,O(n)的枚举效率加一个迭代时间复杂度是O(n^2),二分是可以优化到总效率达到O(nlogn),可利用完全二叉树的性质简单证明,跟冒泡到归并的优化是一样的证明。简单描述,二分ans可能出现的范围这里应该是[0,b0],利用二分的单调性,来不断缩小搜索区间,最后得到精确解。也就是减治法,每次减去一半的问题规模。

  为解决这个问题,我们需要搜索每月最小支付额度以保证我们在一年内能全部偿还。那么支付金额的合理下限是多少呢?$0是显而易见的答案,但你可以做到更好。如果没有利息产生,每月支付金额只需原始透支金额的十二分之一。因此我们必须每月最少支付这么多,原始透支金额的十二分之一是个很好的下限。

  那好的上限呢。假想我们不是每月支付,而是在年底一次性支付完整个金额,那么我们最终支付必然大于我们将按月分期支付,因为产生了未支付金额的利息。因此一个好的每月支付上限是(透支价额加上一整年所附加的每月利息)/12。

改进程序:

def pay(balance,payment):
    for i in range(12):
         balance-=payment
         balance=balance+balance*monthlyInterestRate 
    return balance
balance=320000  #测试时请修改此处
annualInterestRate=0.2 #修改年利率
monthlyInterestRate=annualInterestRate/12
print "balance=%d"%(balance)
print "annualInterestRate=%.2f"%(annualInterestRate) 
lower=balance/12
upper=(balance*(1+annualInterestRate))/12
payment=(lower+upper)/2
while pay(balance,payment)<-0.01or pay(balance,payment)>0:
    if pay(balance,payment)<-0.01:
        upper=payment
    else:
        lower=payment
    payment=(lower+upper)/2  
print "Lowest Payment:%.2f"%(payment)

注:以上程序均为自己编写,初学python,许多功能不是很了解,只能用很繁琐的形式来编写。

一次二分法在python中的利用

标签:

原文地址:http://www.cnblogs.com/zhangminli/p/4493113.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!