-1

Forewarning, I have just started learning python so please bear with me on my beginner code.

So in the MIT6_0001 course on python. You are given a problem where you are supposed to find the "optimal monthly saving rate" for a 25% downpayment on a 1 million dollar house in a 36 month time period using a bisection search algorithm, where you're starting salary is 150,000 and a semi-annual raise of 7%. You must also account for an annual ROI 4% on your savings.

I have been working on this for a week. at first, I tried it without the for loop and that pretty much returned best savings rate as 100% which is where my main problem lies, I can't get around the fact that each time I bisect the value it will always be low so it just keeps trying to get closer and closer to 1 until the epsilon value is reached in the while loop. I have seriously been losing sleep over this please help

total_cost = 1000000
annual_salary =150000
current_savings = 0
epsilon = 100
low = 0
high = 10000
savings_rate= (low + high)/2
down_payment = .25 * total_cost 
raise_rate = .07
month_count = 0
r = .04/12
step_count = 0 


while current_savings-down_payment <= epsilon :
    for i in range(36):
        if month_count != 0 and month_count % 6 == 0:
            annual_salary += annual_salary * raise_rate 
        current_savings += current_savings * r + (annual_salary/12) * (savings_rate/10000)         

        if  current_savings < down_payment:
            low = savings_rate
            print("low =",low)    
        else:
            high = savings_rate
            print("high =",high)

        month_count += 1
        savings_rate= (low + high)/2
step_count += 1
print("Best savings rate:​ ",savings_rate/10000)
print("Steps in bisection sear: ",step_count)  

expected output Best savings rate:​ 0.4411
Steps in bisection search:​ 12

actual Best savings rate:​ 0.5
Steps in bisection search:​ 1

v0iidb0x
  • 1
  • 2

2 Answers2

0

Remember our goal is to take a continuous function and find the approximate points where it is zero in our graph. Our function in this case is abs(current_savings-down_payment)-epsilon = 0.I think the problem your having is that the absolute value of current savings minus down payment has to be less than epsilon and you are testing whether it is greater than epsilon instead.

West
  • 722
  • 7
  • 16
  • Your right, If I understand you correctly The loop should be running while the resultant current savings less down payment is greater then epsilon, but even after tweaking the code I'm still running into incorrect outputs or infinite loops. Is there a better approach to implementing this type of bisectional search? – v0iidb0x Apr 12 '19 at 22:06
0

I figured out the solution.

total_cost = 1000000
annual_salary = 150000
current_savings = 0
epsilon = 100
low = 0
high = 10000
down_payment = .25 * total_cost
raise_rate = .07
r = .04/12
step_count = 0



while abs(current_savings - down_payment) >= epsilon:
    savings_rate = float(low + high) / 2.0  #take care of integer division
    current_savings = 0 # reset for next itteration
    annual_salary = 150000 #reset for next itteration

#    print("savings_rate = %f " % (savings_rate/10000)) #4debugging
#    print("current_savings= ", current_savings) #4debugging

    for i in range(1,36): #initiate range at 1, easier to handle 6 month raise 
        if i != 1 and i % 6 == 0:
            annual_salary += annual_salary * raise_rate
        current_savings += current_savings * r + (annual_salary/12) * (savings_rate/10000)
#        print("count =",i) #4debugging
#        print("annual_salary: ", annual_salary) #4debugging

    print ("current_savings=%f, down_payment=%f" % (current_savings, down_payment) )
    print ("diff = %f " % abs(current_savings - down_payment) )

    if (step_count > 20): 
        print('**********ERROR**********: inf loop') 
        break # exit infinite loop         

    elif current_savings < down_payment:
        low = savings_rate #update range low if less than down payment
        print("new range: %f -> %f" % (low, high) )

    elif current_savings > down_payment:
        high = savings_rate #update range high if greater than down payment
        print("new range: %f -> %f" % (low, high) )

    print("")
    step_count += 1 

print ("current_savings=%f, down_payment=%f" % (current_savings, down_payment) )
print ("diff = %f " % abs(current_savings - down_payment) )
print("best savings rate: ",savings_rate/10000)
print("number of bisection steps: ",step_count)
v0iidb0x
  • 1
  • 2