Problem 34 Binary Search

Back to Problem Solutions forum

hogarth45     2015-01-20 21:31:37
User avatar

Binary Search

Hi I was just looking for clarification on this; If I plug in the coeffecients provided in the example:

A * x + B * sqrt(x ^ 3) - C * exp(-x / 50) - D = 0 0.59912051 0.64030348 263.33721367 387.92069617 so A= 0.59912051 B= 0.64030348 C= 263.33721367 D= 387.92069617

and if I set x = 73.595368554162 I should be getting 0, correct?

Currently I have this in my code:

            decimal x = 73.595368554162M;
            //A,B,C, and D are read in from a file above this section, they are of the decimal type
            swine = A * x;
            swine = swine+(B*(decimal)Math.Sqrt((double)Math.Pow((double)x,2)));
            swine = swine - (C * (decimal)Math.Exp((double)(x * -1) / 50));
            swine = swine - D;

At the end of this swine= -357.13739013707045530548286M

Quandray     2015-01-21 07:13:46
User avatar

Check how you are doing x^3

hogarth45     2015-01-21 21:28:10
User avatar

Thank you Quandray, appreciate the help!

mario_luigi     2015-02-05 05:52:40

I'm having the same problem. My check with answer plugged in gives me 4.898771521766321e-08.
check = a * x + b * math.sqrt(x**3) - c * math.exp(-x / 50) - d

Vadim Tukaev     2015-02-05 13:38:12

NB: Solution should be calculated with precision 0.0000001 = 1e-7 or better.

Rodion (admin)     2015-02-05 14:23:44
User avatar

Yes, Vadim is correct - the answer need not be "indefinitely exact" :)

mario_luigi     2015-02-05 17:33:23

Right but I thought the answer was supposed to be 0?

Rodion (admin)     2015-02-05 18:20:37
User avatar

Answer is not the value of this expression, but the value of x which, if plugged into expression, yields value close to 0.

Or have I misunderstood your question?

mario_luigi     2015-02-05 18:35:00

You got it. When I plug x in with the answer given for the example problem it's returns a value not equal to 0

mario_luigi     2015-02-05 21:21:27

I feel dumb I didn't realize that was less than 0 but closest.

mario_luigi     2015-02-06 03:19:09

Okay so I solved the problem but the way i broke out of my loop I don't like. I definentally feel like I cheated. if step > 32: return print('%.7f ' % (x)) that's what i used to break out since I couldn't figure out how to get it to stop close to the answer. Interesting enough it was correct for all the answers.

Matthew Cole     2015-02-10 05:22:05

Mario,

I've taken a look at your code, and I'd like to propose some hints.

On lines 40-45, while processing each of the input's test cases, you have the following code:

for l in testdata:
    for a in l[::4]:
        for b in l[1::4]:
            for c in l[2::4]:
                for d in l[3::4]:
                    bsearch(float(a),float(b),float(c),float(d))

There's a couple of minor problems with this. First, you could make this code more compact and pythonic by taking advantage of the power of the tuple. Second, you've got unnecessary list splicing and control looping that might make your code tougher to debug for later problems with lists of variable length from test case to test case. Instead, try this code:

for l in testdata:
    a,b,c,d = l
    print('%.7f ' % (str( bsearch(float(a),float(b),float(c),float(d)) )) )

If you're not familiar with tuples and assigning variables from tuples, I challenge you to try print(a,b,c,d) before the function call to see what happened inside this loop. Also note that I moved the print statement outside the function. It's better to have a function return a value rather instead of returning None after performing a side effect (like printing). It will make the function more reusable.

Matthew Cole     2015-02-10 05:22:28

Next, you mentioned that you don't like the way you broke out of the control loop within the bsearch function. I see two issues. First, you have a range generator assigned to i within a loop, but you never use the value of i. Currently, you run until you've done 32 iterations. This works for our smaller monotonic coefficients. But if the difference between minimum and maximum values in the codomain of f(x) = a * x + b * math.sqrt(x**3) - c * math.exp(-x / 50) - d for a given domain of x is large, you might not get a zero to the function with the necessary precision.

Instead, consider the following code inside your bsearch() function.

    while abs(check) > differ: #### Note that the looping condition has changed
        ####for i in range(x, y):#### Line no longer needed.

        ###TO DO: Calculate the median of the boundaries, and recalcuate <check>
        ...

        ####step += 1#### Line no longer needed.

        ###TO DO: Determine if check was too high, too low, and move your search boundaries
        ###       to cover half of the previous range.
        ###       (one boundary stays the same, the other becomes the old median value)
        ...

        ####if step > 32:#### Line no longer needed.

    ###TO DO: now that you've found a median value that provides a zero within the needed <differ> precision,
    ###       return that median value from the function.            

Once you've improved your code, you can take a look at my implementation of the Binary Search to compare.

mario_luigi     2015-02-10 19:38:13

Awesome cole yea thats alot to go thru. I figured later I could've exited the loop that exact same way. Thanks for the help tho.

randaliert     2015-10-07 00:33:34

I have a different problem than any that I see listed above. I am getting an error message because my exp function is being performed on a nonpositive number. Looking at the equation, it seems inevitable that this will happen for any positive value of x, because it is set to negative in the parentheses (-x/50). What am I not understanding correctly here? Thanks for any help.

Rodion (admin)     2015-10-07 10:44:24
User avatar

> I am getting an error message because my exp function is being performed on a nonpositive number

Well, it is strange for exponent is well defined for negative values.

Technically exp(-x) = 1 / exp(x). See for example: http://ideone.com/ErAgBk

I'm sorry for this problem being bit more mathy than it should. We have array-based version of binary search in the problems list - but it was added later...

randaliert     2015-10-07 16:01:56

No problem, thanks for the explanation. I think I am reaching the limit of my math knowledge on a challenge like this one. But I will change my code to the equivalent you have listed above, and try it again.

Diego Cruz     2017-11-11 21:16:24
User avatar

Good afternoon and sorry, I'm new in this place, I don't understand if the function exp() refers to number "e" raise the power ... or if its meaning is another. Thanks.

Quandray     2017-11-12 07:23:24
User avatar

Hi and welcome. exp(x) is e to the power x.

Diego Cruz     2017-11-13 19:56:44
User avatar

Thank You for your help Quandray!

jayskerdoo     2018-03-29 08:13:13
User avatar

This problem is kicking my butt! Can't wait to solve it. . .

ghewadesumit     2019-03-29 15:04:11

What should be the initial value of x and the way given in this article https://www.codeabbey.com/index/wiki/binary-search is the one used to change the value of until it meets the condition that 0<= x<=100?

Rodion (admin)     2019-03-29 19:58:09
User avatar

Hello! I'm not sure I understand the question well, but your initial values are x_right and x_left - the ends of the range at which you are searching for root. In this problem we want to search for root between x=0 and x=100. According to problem statement it is guaranted that function is monotonic (i.e. it would be negative at x=0 and positive at x=100) - and we want to find such x where it crosses the line of y=0. Hope this helps... Though probably I should add a picture...

Please login and solve 5 problems to be able to post at forum