Как исправить бесконечный цикл при поиске пополам

Мой код проходит тестовые случаи, но если вводится что-то около ~ 949 000, он входит в бесконечный цикл.

Мне нужно рассчитать наилучшую ставку, по которой нужно откладывать часть ежемесячного дохода, чтобы позволить себе авансовый платеж через 36 месяцев с двумя значащими цифрами. Я думаю, что это как-то связано с тем, что я не совсем понимаю, как рассчитывается эпсилон - я пытался рассчитать эпсилон как 0,0001 * общая_стоимость, 0,0004 * часть_авансового_платежа и 0,0001 * годовой_доход, все безрезультатно.

#House Hunting ps1c

low = int(0)
high = int(10000)
percent_saved = (low + high)/2.0

current_savings = 0
annual_salary = int(input("What is your starting anual salary? "))
total_cost = 1000000
semi_annual_raise = 0.07
portion_down_payment = total_cost * 0.25
epsilon = 100

r = 0.04

total_months = 0
steps = 0
while True:
    current_savings = 0
    monthly_salary = annual_salary/12
    for i in range(1,37):
        current_savings += (current_savings*r/12)
        current_savings += (monthly_salary * (percent_saved / 10000))     
        total_months += 1
        if total_months % 6 == 0:
            monthly_salary += monthly_salary * semi_annual_raise
    steps +=1   

    if abs(current_savings - portion_down_payment) <= epsilon:
        print("Steps in bisectional search: ", steps)
        best_savings_rate = str(percent_saved / 100)
        print("Best savings rate: ", (best_savings_rate + "%"))
        break
    elif (portion_down_payment - 100) - current_savings > 0:
        low = percent_saved
        percent_saved = int((low + high) / 2.0)
    else:
        high = percent_saved       
        percent_saved = int((low + high) / 2.0)

    if percent_saved >= 9999:
        print("It is not possible to afford this in 3 years")
        break

Тестовый пример 1

Enter the starting salary: 150000
Best savings rate: 0.4411  
Steps in bisection search: 12 

Тестовый пример 2

Enter the starting salary: 300000
Best savings rate: 0.2206 
Steps in bisection search: 9 

Тестовый пример 3

Enter the starting salary: 10000
It is not possible to pay the down payment in three years

Мой код проходит все тестовые случаи, но когда ввод слишком высок, он входит в бесконечный цикл, который я не знаю, как согласовать.


person A. M. Parfitt    schedule 05.01.2019    source источник
comment
Вы пытались поставить точку останова в своем коде, чтобы увидеть, почему одни тесты проходят, а другие нет?   -  person John Douma    schedule 05.01.2019
comment
Или даже просто несколько операторов печати, чтобы распечатать переменные при каждом проходе цикла, чтобы увидеть, ведут ли они себя так, как вы ожидаете?   -  person John Gordon    schedule 05.01.2019
comment
Цикл for, который накапливает 36-месячную экономию : поместите его в функцию и проверьте — работает ли он? если это так, вы знаете, что это не так - это оставит ошибки в логике if/elif/else или в том, как вы рассчитываете/определяете новый процент экономии.   -  person wwii    schedule 05.01.2019
comment
int((low + high) / 2.0 - почему вы конвертируете в int? Что делает (percent_saved / 10000)?   -  person wwii    schedule 05.01.2019


Ответы (1)


По существу, когда годовая заработная плата становится выше, оптимальные нормы сбережений становятся меньше. Когда оптимальная норма сбережений становится меньше уровня точности, необходимого для

abs(current_savings - portion_down_payment) <= epsilon

становится выше. Когда вы переводите процент_сохранено в целое число в

percent_saved = int((low + high) / 2.0)

он искусственно ограничивает точность, а затем код входит в бесконечный цикл.

Удалите приведение, и код будет работать всегда.

person N.Clarke    schedule 05.01.2019
comment
Я сделал это, а также удалил свое int-преобразование low и high ранее в программе. Чтобы ограничить значащие цифры, я использовал best_savings_rate = best_savings_rate[0:5] print("Best savings rate: ", (best_savings_rate + "%")) - person A. M. Parfitt; 05.01.2019