3

To find the number of iterations of the inner while loop, is it the same as finding the run time of inner loop? Also since, the inner loop is dependent on on the outer loop,I know I should multiply the number of times the inner while loop runs with the outer while loop to get the number of times it is iterated, right? I'm kind of confused on how to calculate # of iterations for while loops. Any help would be appreciated. Thanks!

def nested(n):
    b = 1 
    while b <= n:
        i = 1
        while i < b:
            print(i)
            i = i*3
        b += 1

Thanks everyone for all the help!

I think I understand what the answer is. So, since we're trying to find the number of times the inner loop iterates (which is n-1), I also need to consider the # of times the outer loop iterates of the inner loop (which is n). Therefore, we'll iterate the inner loop (n-1), n times, thus giving us (n(n-1))/2 if we use summation notation. Hopefully that's right.

6
  • You may try printing both b and i for each inner loop iteration. Then run with different n and glance at the output to get the overall idea. Commented Mar 22, 2017 at 19:30
  • @Gassa Yeah , i tried that for numbers n 1 to 7, got: 0, 1, 2, 4, 6, 8, 10, 12. However, I just can't seem to connect the dots or figure out a summation equation from it.. Commented Mar 22, 2017 at 19:33
  • @Gassa is there a specific way to find running times of while loops? Commented Mar 22, 2017 at 19:33
  • I just think every time. Sure there are patterns, like "b = 1, while b <= n: ... b += 1" is just "for b in range (1, n+1)", and "i = 1, while i < b: ... i *= 3" is "how many times should I multiply by three until I get b?", and that's the definition of logarithm. Commented Mar 22, 2017 at 19:36
  • After a hundred or thousand loops, you just get used to it, and see the patterns intuitively. Commented Mar 22, 2017 at 19:37

3 Answers 3

3

You've got a two questions, so I've broken them apart.

To find the number of iterations of the inner while loop, is it the same as finding the run time of inner loop?

No. I've taken the liberty to modify your code a bit to use time.process_time to measure run time without interference from the operating system's scheduler, and to eliminate your interior print statement (I/O calls are deceptively expensive).

import time

def nested(n):
    loops = list()

    #Start outer timer
    func_start = time.process_time()

    b = 1 
    while b <= n:

        #Start loop timer
        loop_start = time.process_time()

        i = 1
        while i < b:
            #print(i)
            i = i*3
        b += 1

        #Finish loop timer
        loop_finish = time.process_time()
        loops.append(loop_finish - loop_start)

    #Finish outer timer
    func_finish = time.process_time()

Then I add a logging statement:

print("Function time: %f, Sum loop times: %f, iterations: %i, iterations by runtime: %.0f" 
        % (func_finish - func_start, 
            sum(loops), 
            len(loops), 
            (func_finish - func_start) / (sum(loops)/len(loops)))  )

Finally, I run it a few times. Here are the results:

Function time: 0.000019, Sum loop times: 0.000010, iterations: 10, iterations by runtime: 19
Function time: 0.000135, Sum loop times: 0.000102, iterations: 100, iterations by runtime: 132
Function time: 0.001461, Sum loop times: 0.000875, iterations: 1000, iterations by runtime: 1670
Function time: 0.017174, Sum loop times: 0.011532, iterations: 10000, iterations by runtime: 14892
Function time: 0.193567, Sum loop times: 0.133996, iterations: 100000, iterations by runtime: 144457

As you can see, as the number of iterations increases, using relative run times to try to estimate the number of iterations becomes less accurate.

Also since, the inner loop is dependent on on the outer loop,I know I should multiply the number of times the inner while loop runs with the outer while loop to get the number of times it is iterated, right?

This is true for theoretical applications. If I have n instructions in an inner loop, and the inner loop is run m times, I'd predict that the total run time is in fact, mn. However, you have to keep in mind that a line of code does not equal a single instruction. In fact, even some instructions don't equal other instructions in terms of execution time (floating point arithmetic versus integer arithmetic, for example). We saw that in our timed example.

For purposes of calculating Big-O runtime bounds, the technique you suggest for multiplying inner loop statement counts by number of loops works. In the real world, it gets more complicated, and doubly so for interpreted languages like Python.

Sign up to request clarification or add additional context in comments.

3 Comments

About the second part, it's often not that simple. For example, Sieve of Eratosthenes has two nested loops, neither of which is O (log log n) by itself, but runs in O (n * log log n) as a whole.
@Gassa my favorite example is for(int i=1;i<n;i*=2) for (int j=0;j<i;j++), which is O(n).
@amit Yeah, that one is even better.
1

The short answer is: sum{i=1; i<=n ;i++} log3(i) = log3(n!)

Comments

1

Time complexity is O(nlogn) (and this is the number of times the inner loop repeats itself).

Outer loop runs n times. For the bth iteration of the outer loop, the inner loop runs log_3(n-b) times.

Summing it together we get:

T(n) = sum{log_3(n-b) | for b=1 to b=n}
T(n) = log_3(n) + log_3(n-1) + log_3(n-2) + ... + log_3(1) =
T(n) = log_3(n * (n-1) * (n-2) * .... * 1) = log_3(n!)

And since log(n!) is in Theta(nlogn), this is your time complexity.

1 Comment

I don't understand how you come to the conclusion that there's log involved, moreover how you knew it was log_3. Mind elaborating on that please?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.