一次二分法在python中的利用

此次博客来自我选修课的一次作业,初学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,许多功能不是很了解,只能用很繁琐的形式来编写。

时间: 2024-12-15 14:51:04

一次二分法在python中的利用的相关文章

【Python】Python中对象管理与垃圾回收中两个很有意思的问题

再Python中是利用引用计数来实现对象管理和垃圾回收的,即其他对象引用该对象时候,其引用计数加1,反之减1,当引用计数为0时候,被垃圾收集器回收. Python解释器对对象以及计数器的管理分为以下两步: 1)其引用计数减1 2)判断引用计数是否为0,为0的话,销毁对象 因为使用引用计数,造成两个问题,GIL和循环引用 一.GIL(Global Interpreter Lock)全局解释器锁 试想一下在多线程中使用引用计数,比如线程a,b同时引用obj,那么obj的引用计数为2. 1)当a撤销对

python中如何将一个list打乱

在java中,打乱list使用collections.shuffle()方法来实现的, python中要利用random模块中的shuffle方法 import random x = [i for i in range(5)] print(x) random.shuffle(x) print(x) 原文地址:https://www.cnblogs.com/amy7758/p/10894096.html

python中利用正则表达式匹配ip地址

现在有一道题目,要求利用python中re模块来匹配ip地址,我们应如何着手? 首先能想到的是ip地址是数字,正则表达式是如何匹配数字的呢? \d或[0-9] 对于这个问题,不要一下子上来就写匹配模式,应该一步步分解,把复杂的问题简单化 比如ip地址,我们可以总结一下规律 1. 它是一个字符串 2. 字符串内部是由4个1-3位的数字和3个.组成 3. 数字的范围是0-255 接下来,我们先试一下匹配第1个数字 第一步:尝试匹配192.168.100.123中的192 >>> import

Python中利用Tesseract软件来识别图片中的英文与中文

OCR与Tesseract介绍   将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition,OCR).可以实现OCR 的底层库并不多,目前很多库都是使用共同的几个底层OCR 库,或者是在上面进行定制. Tesseract 是一个OCR 库,目前由Google 赞助(Google 也是一家以OCR 和机器学习技术闻名于世的公司).Tesseract 是目前公认最优秀.最精确的开源OCR 系统. 除了极高的精确度,Tesseract 也具有很高的灵活性.它

Python中的切片操作

Python中的切片操作功能十分强大,通常我们利用切片来进行提取信息,进行相关的操作,下面就是一些切片的列子,一起来看看吧,希望对大家学习python有所帮助. 列如我们从range函数1-100中取7的倍数,函数及结果如下所示: >>> for i in range(1,100)[6::7]: print i 7 14 21 28 35 42 49 56 63 70 77 84 91 98 取一个list或tuple的部分元素是非常常见的操作.比如,一个list如下: >>

python 中 深拷贝和浅拷贝的理解

在总结 python 对象和引用的时候,想到其实 对于python的深拷贝和浅拷贝也可以很好对其的进行理解. 在python中,对象的赋值的其实就是对象的引用.也就是说,当创建一个对象,然后赋给另外一个变量之后,实际上只是拷贝了这个对象的引用. 我们先用  利用切片操作和工厂方法list方法 来阐述一下浅拷贝. 举个栗子: Tom = ['Tom', ['age', 10]] Jack = Tom[:] ……切片操作 June = list(Tom) 接下来查看一下 上述三个变量的引用: >>

Python中的几种数据类型

大体上把Python中的数据类型分为如下几类: Number(数字)                  包括int,long,float,complex String(字符串)                例如:hello,"hello",hello List(列表)                    例如:[1,2,3],[1,2,3,[1,2,3],4] Dictionary(字典)              例如:{1:"nihao",2:"h

python中如何表示多维数组(即矩阵形式)

python中如何表示多维数组 在java或者c以及其他语言中,表示个"整型3行4列"的矩阵,可以这样声明:int a[3][4]; 但是在python中一不能声明变量int,二不能列出维数.我们只能利用列表中夹带列表形式表示. 以实际例子为例,想将文件中如下格式的数据读取出来,,文件中的每行数据是一个样本,列数是每个样本的属性个数.我们希望将其读取出来组合成N*2的矩阵形式,以便于对这些数据进行处理. 实现的代码如下: dataSet = [] #列表,用来表示,列表中的每个元素也是

Python学习笔记整理(三)Python中的动态类型简介

Python中只有一个赋值模型 一.缺少类型声明语句的情况 在Python中,类型是在运行过程中自动决定的,而不是通过代码声明.这意味着没有必要事声明变量.只要记住,这个概念实质上对变量,对象和它们之间的关系都适用.那么这个概念也容易理解并掌握. 1.变量,对象和引用 变量创建:一个变量,当代码第一次给它赋值时它就被创建了.之后的赋值将会改变已创建的变量名的值.Python在代码运行之前先检测变量名,可以当成是最初的赋值创建变量. 变量类型:变量永远不会有任何的它关联的类型信息或约束.类型的概念