Big O analysis for this for loop - java

sum = 0;
for (i = 1; i <= n; i++) { //#1
for (j = 1; j <= i * i; j++) { //#2
if (j % i == 0) { //#3
for (k = 1; k <= j; k++) { //#4
sum++;
}
}
}
}
The above got me confusing
Suppose #1 runs for N times
#2 runs for N^2 times
#3 runs for N/c since for N inputs N/c could be true conditions
#4 runs for N times
Therefore roughly I could be looking at O(N^5) . I am not sure. Please help clarify.
EDIT I was wondering the runtime at the if(j%i==0). Since it takes N^2 inputs from its parent loop it could be doing (N^2)/c executions instead of N/c

I would say its O(N^4) as its the same as.
for (int i = 1; i <= n; i++) //#1 O(n ...
for (int j = i; j <= i * i; j+=i) //#2 ... * n ...
for (int k = 1; k <= j; k++) //#4 ... * n^2) as j ~= i^2
sum++;
or
public static void main(String... args) {
int n = 9000;
System.out.println((double) f(n * 10) / f(n));
}
private static long f(long n) {
long sum = 0;
for (long i = 1; i <= n; i++) //#1
for (long j = 1; j <= i; j++) //#2
sum += i * j; // # 4
return sum;
}
prints
9996.667534360826
which is pretty close to 10^4

#PeterLawrey did the math, here are benchmarks plotted on chart (my data set - n vs. execution time in microseconds).
Basically I run the code in question several times with different n input (X-axis). Then I divided average execution time by n^5, n^4 and n^3 functions and plotted that:
Full size image
Note that this is a logarithmic scale and that all functions were scaled to more-or-less be in the same range.
Guess what, avergae execution time t(n) divided by n^5 keeps getting decreasing, while t(n)/n^3 keeps growing. Only t(n)/n^4 is stabilizes when approaching infinity which proves that the average execution time is in fact O(n^4).

I think the answer, using Sigma notation, would be like the following:

Related

What is Big O of two loops

I am trying to find the Big-O for the Summing function. I know the two loops usually mean that N^2 run time but this is just one N but j is running many more than N itself.
int Summing( int n )
{
int i
int j
int s = 0;
for(i=0; i < n; i++){
for(j=0; j < i; j++) {
s += i*i;
}
}
You can calculate the exact time the inner loop takes as a function of i and then sum it up over all values that i takes.
Here the number of times the innermost section is run is 0 + 1 + 2 + ... + (n-1) = (n-1)*n/2 = (n^2)/2 - n/2 which is O(n^2)

How do I find the first number that divides with the first 20 numbers?

I want to find the smallest number that can be divided with no reminder(perfect division) by the first 20 numbers (1, 2, 3... 20).
I've tried something that I thought would not fail, that goes like this:
for (int i = 20; i < Integer.MAX_VALUE; i++) {
int seImparte = 0;
for (int j = 1; j <= 20; j++) {
if (i % j != 0) {
seImparte++;
}
}
if (seImparte == 0) {
System.out.println(i);
break;
}
}
I thought I would get the first number and then the program would exit, but it runs and nothing happens.
Thank you for your time and help!
#raulGLD Your code works fine but it is not optimezed,
You can break inner loop, after invalid condition
Also you can start from 3 or 7 as [1,2,3,4,5,6 can be tested by [4,6,8,10,12] -This is optional but break is important
for (int i = 20; i < Integer.MAX_VALUE; i++) {
int seImparte = 0;
for (int j = 7; j <= 20; j++) {
if (i % j != 0) {
seImparte++; break;
}
}
if (seImparte == 0) {
System.out.println(i);
break;
}
}
output : 232792560
Instead of optimizing of brute-force approach, it is worth to use simple math rules.
Resulting complexity is O(n*log(n)) against "huge count"
Python code uses Least common multiple function
def gcd(a, b):
while b > 0:
a, b = b, a % b
return a
def lcm(a, b):
return a * b // gcd(a, b) # integer division
d = 1
for i in range(2, 21): #last i=20
d = lcm(d, i)
print(d)
>>[Dbg]>>> 232792560
Also we can make factorization of all numbers in range into primes and remember the largest powers for every prime. In this case: 2:4; 3:2; 5:1; 7:1; 11:1; 13:1; 17:1; 19:1 and multiply these powers. More complex code (but this way might be useful sometimes)
232792560 = 16 * 9 * 5 * 7 * 11 * 13 * 17 * 19
Hope this is what you are looking:
for (int i = 2; i < Integer.MAX_VALUE; i++) {
for (int j = 2; j <= 20; j++) {
if (i % j == 0) {
System.out.println("i : "+i+" j : "+j);
break;
}
}
}

Big O for 3 nested for loops?

public int Loop(int[] array1) {
int result = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1.length; j++) {
for (int k = 1; k < array1.length; k = k * 2) {
result += j * j * array1[k] + array1[i] + array1[j];
}
}
}
return result;
}
I'm trying to find the complexity function that counts the number of arithmetic operations here. I know the complexity class would be O(n^3), but I'm having a bit of trouble counting the steps.
My reasoning so far is that I count the number of arithmetic operations which is 8, so would the complexity function just be 8n^3?
Any guidance in the right direction would be very much appreciated, thank you!
The first loop will run n times, the second loop will run n times however the third loop will run log(n) times (base 2). Since you are multiplying k by two each time the inverse operation would be to take the log. Multiplying we have O(n^2 log(n))
If we can agree that the following is one big step:
result += j * j * array1[k] + array1[i] + array1[j]
then let's call that incrementResult.
How many times is incrementResult called here? (log n)
for (int k = 1; k < array1.length; k = k * 2) {
// incrementResult
}
Lets call that loop3. Then how many times is loop3 called here? (n)
for (int j = 0; j < array1.length; j++) {
// loop 3
}
Let's call that loop2. Then, how many times is loop2 called here? (n)
for (int i = 0; i < array1.length; i++) {
// loop 2
}
Multiply all of those and you'll get your answer :)
That depends on the loops. For instance:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
sum += i * j * k;
}
}
}
has complexity O(1), because the number of iterations does not depend on the input at all.
Or this:
for (int i = 0; i < n*n*n*n*n*n; i++) {
sum += i;
}
is O(n^6), even though there is a single loop.
What really matters is how many iterations each loop makes.
In your case, it is easy to see that each iteration of the innermost loop is O(1). How many iterations are there? How many times do you need to double a number until you reach n? If x is the number of iterations, we'd exit the loop at the first x such that k = 2^x > n. Can you solve this for x?
Each iteration of the second loop will do this, so the cost of the second loop is the number of iterations (which are easier to count this time) times the cost of the inner loop.
And each iteration of the first loop will do this, so the cost of the first loop is the number of iterations (which is also easy to count) times the cost of the second loop.
Overall, the runtime is the product of 3 numbers. Can you find them?

Multiply arrays representing integers (Similar to BigInteger)?

Basically, the integer array (named digits of class BigInteger) is used to represent a single large integer. Up to this point, I have solved how to add-with-carry two of the arrays and also subtract-with-carry, but multiplication is giving me problems. Below is the code I have written:
public BigInteger multiply(BigInteger n) {
int carry = 0;
for(int i = n.digits.length - 1; i >= 0;i--) {
for(int j = this.digits.length - 1; i >= 0; i--) {
int val = (this.digits[i] * n.digits[j]) + carry;
this.digits[i] = val % 10;
carry = val / 10;
}
}//for
return this;
}
This code works as long as the invoking this is larger and the parameter n is a single digit. But as soon as n exceeds 1 digit, the code fails. I am at a loss, and guidance in the right direction would be appreciated.
Replace
for(int j = this.digits.length - 1; i >= 0; i--) {
with
for(int j = this.digits.length - 1; j >= 0; j--) {
You don't want to decrement i while iterating through the inner loop. After you make this correction, you should be good to go.

Big-Oh Notation?? Approximating the value of sum after the following code fragment, in terms of variable n

Okay, so I don't know what Big-Oh is because I swear my professor didn't cover it, and I need help for something I assume to be simple asap. I know the answers to it, but she wants code for it, and I don't know how to compile it. Basically, I googled help w/ this & they just simply have the answer, w/o an example of how to get it, or they have n = 1000 or something, but I don't see that in the prompt or what n should equal to. I hope someone understands me. Advice, please? lol.
This is the prompt:
1) Approximate the value of sum after the following code fragment, in terms of variable n in Big-Oh notation.
2) Answer the estimated run time of the following program segment in Big-Oh notation:
int sum = 0;
for (int i = 1; i <= n - 3; i++) {
for (int j = 1; j <= n + 4; j += 5) {
sum += 2;
}
sum++;
}
for (int i = 1; i <= 100; i++) {
sum++;
}
3) Answer the estimated run time of the following program segment in Big-Oh notation:
int sum = 0;
for (int i = 1; i <= n; i++) {
sum++;
}
for (int j = 1; j <= n / 2; j++) {
sum++;
}
I'm used to just sticking public static void main(String[] args) { in front of everything, so I did this:
public class BigO {
public static void main(String[] args) {
}
public static void main(int n) {
int sum = 0;
for (int i = 1; i <= n - 3; i++) {
for (int j = 1; j <= n + 4; j += 5) {
sum += 2;
}
sum++;
}
for (int i = 1; i <= 100; i++) {
sum++;
}
}
}
Of course that doesn't work.
Big O notation isn't about getting the program to work. It's about looking at the code to see how quickly the running-time of the program increases when you increase some variable (frequently the number of inputs but in this case, simply n).
Suppose that you analyse the running time of the program for successive values of n -> n=1, n=2, n-3, etc. and find that the running time is described by a linear equation like An + B. The dominant term here is the An term so you ignore the B. You can also ignore the A and say that it's order O(n).
If the running time is described by An^2 + Bn + C then it's order O(n^2).
You understand the nature of the performance by analyzing the code and determining how it's looping not by actually getting the code to run.

Categories

Resources