使用二分法计算购房最优储蓄率的Python代码为何出现无限循环?
代码无限循环的核心问题
- 初始年薪未重置:每次二分法测试新储蓄率时,
annual_salary已经被上一次测试中的涨薪逻辑修改,不是用户输入的初始值,导致所有后续储蓄时长计算全部错误。 - 内层循环终止条件逻辑错误:原判断
current_savings < portion_down_payment or current_savings-100< portion_down_payment等价于只要储蓄小于「首付+100」就会一直累加月数,无上限控制,极易陷入死循环。 - 二分终止条件过于严格:强制要求储蓄时长严格等于目标月数,实际场景中很可能不存在刚好卡着目标月数的储蓄率,会导致二分在两个相邻值之间反复横跳永远无法退出。
- 无边界校验逻辑:没有先判断100%储蓄率的情况下能不能在目标月数内凑够首付,如果连全额储蓄都达不到要求,二分永远找不到结果,直接死循环。
修正后可运行代码
print('what is the cost of your dream home?') total_cost = float(input()) print('what is your annual salary?') annual_salary = float(input()) # 保存初始年薪副本,每次测试重置用 initial_annual_salary = annual_salary portion_down_payment = 0.25 * total_cost print('enter a semi-annual raise, as a decimal') semi_annual_raise = float(input()) print('in how many months do you want to buy your house?') target_months = int(input()) first = 0 last = 10000 steps_in_bisection = 0 # 先做边界校验:100%储蓄率能不能达到要求 test_saving = 0 test_months = 0 test_salary = initial_annual_salary while test_saving < portion_down_payment and test_months <= target_months: test_saving += (1 * (test_salary/12)) + (test_saving * 0.04)/12 test_months += 1 if test_months %6 ==0: test_salary += semi_annual_raise * test_salary if test_months > target_months: print("即便100%储蓄也无法在目标月数内凑够首付") exit() # 二分搜索主逻辑 while last - first > 1: saving_rate = int((first + last)/2) current_savings = 0 number_of_months = 0 # 每次测试重置年薪为初始值 current_annual = initial_annual_salary while current_savings < portion_down_payment: current_savings += ((saving_rate/10000) * (current_annual /12)) + (current_savings * 0.04)/12 number_of_months += 1 if number_of_months %6 ==0: current_annual += semi_annual_raise * current_annual # 调整二分边界 if number_of_months > target_months: first = saving_rate else: last = saving_rate steps_in_bisection +=1 best_rate = last / 100 print(f"best savings rate: {best_rate}%") print(f"number of bisection steps: {steps_in_bisection}")
内容的提问来源于stack exchange,提问作者abdelrahman moataz
相关产品推荐
相关产品推荐

