Project1
Hard Performance Measurement (A+B)
王子轩
Date: 2024-3-13
Chapter 1: Introduction
Given S as a collection of N positive integers that are no more than V. For any given number c, you are supposed to find two integers a and b from S, so that a+b=c.
What needs to be done: Use Srand to randomly generate a non-repeating S array, then find two numbers from it and output them when they add up to equal C. You can consider using bucket sorting.
Why do it: Srand plus an array of record duplicates can meet the requirements of the topic S array, and then there can be two algorithms to solve the problem.And bucket sorting is very efficient.
Chapter 2: Algorithm Specification
Main function
sketch:
1 | graph TD; |
Algorithm 1 : a brute-force approach to iterate through all pairs of numbers.
Input: n(the number of digits),c(the summed target value),cnt(Used to record the number of solutions),x(Iterations),s(the numeric set).
Output: cnt(the number of solutions),all the solutions(a and b)
sketch:
1 | graph TD; |
Pseudo code:
- Let cnt $\leftarrow$ 0;
- for i = 0 to n-1
- for j = i+1 to n-1
- When s[i] + s[j] == c, print s[i] + s[j] = c and let cnt $\leftarrow$ cnt + 1;
- return cnt;
Algorithm 2 : a bucket sorting to optimize the search process.
Input: n(the number of digits),c(the summed target value),cnt(Used to record the number of solutions),x(Iterations),s(the numeric set).
Output: cnt(the number of solutions),all the solutions(a and b)
sketch:
1 | graph TD; |
Pseudo code:
- define an array ton and let each element $\leftarrow$ 0;
- Let cnt $\leftarrow$ 0;
- for i = 0 to n-1
- when s[i] < c, let ton[s[i]] $\leftarrow$ 1;
- for i = 1 to c/2
- if not ((c mod 2 == 0) and (i == c/2)) and ton[i] + ton[c - i] == 2
- print i + (c-i) = c and let cnt $\leftarrow$ cnt + 1;
- return cnt;
Chapter 3: Testing Results
Test Case Sheet :I tested the program’s runtime at different V-times and plotted the N-run_time graphs.
the purpose :
Study the growth of time required by the algorithm with N.
Compare horizontally the difference in efficiency, complexity, etc. between the two algorithms.
Study how the algorithm reacts when V changes until it reaches the maximum value of the integer V.
the expected result:
Algorithm 1’s running time grows with N in an O(n2) trend, while Algorithm 2 grows more gently.
Algorithm 2 is more efficient and less complex than Algorithm 1.
As V becomes large until it reaches an integer maximum, It takes more time.
the actual behavior of your program:
Note: In the case above, when V is smaller than N, the set S that satisfies the condition cannot be found and does not satisfy the question, so it is counted as /.
The figure shows the running time of the two algorithms versus N when V is 50000, and it is clearly found that Algorithm 1 takes longer, showing a trend of O($n^2$), and Algorithm 2 is more efficient.
The figure shows the running time of the two algorithms versus N when V is 200000.The efficiency gap between the two algorithms widens.
The figure shows the running time of the two algorithms versus N when V is 1000000.The gap between the efficiency of the two algorithms widens further.
The figure shows the running time of the two algorithms versus N when V is 100000000.
The figure shows the running time of the two algorithms versus N when V is 2147483647.
From the last two charts above, I found a strange phenomenon:
For the second algorithm, why does the running time become less while V becomes bigger?
After continuous testing and pondering, I came to the following conclusion:
When V is much larger than n,a wide range of non-repeating random numbers are taken, which leads to a more scattered distribution of random numbers, and thus for a particular objective and c,there are fewer solutions that meet the requirements.
Precisely because no reasonable value can be found, many fewer “printf(…)” statements are executed, resulting in much less time.
So now I understand this phenomenon.
Chapter 4: Analysis and Comments
Time Complexity Derivation:
Algorithm func1:
The number of outer loop iterations is n and the average number of inner loop iterations is n/2.
Therefore, the total number of iterations is n * (n/2) = n^2 / 2.
The time complexity is O(n^2).
Algorithm func2:
The first loop iteration is n, and the time complexity is O(n).
The second loop iteration is c/2, and since c is a constant, the time complexity is O(1).
Thus, the total time complexity is O(n) + O(1) = O(n).
Derivation of space complexity:
Algorithm func1:
- Uses only the extra space at the constant level to store the variables, with a space complexity of O(1).
**Algorithm func2: **
An array ton of size 2500000000 is used, with a space complexity of O(2500000000), i.e. O(1).
Other than that, only constant-level extra space is used to store variables, with a space complexity of O(1).
**In summary, **
Algorithm func1 has a time complexity of O(n^2) and a space complexity of O(1); Algorithm func2 has a time complexity of O(n) and a space complexity of O(1).
Why is Algorithm 1 slower than Algorithm 2?
Because Algorithm 1 performs nesting of for loops and therefore grows at a fast rate, whereas Algorithm 2 just grows linearly, so when n is large, Algorithm 2 is very much faster.
Directions for improvement:
For the Algorithm func1 with a time complexity of O(n^2) and a space complexity of O(1), one potential optimization could be to implement a more efficient sorting algorithm if sorting is a bottleneck in the algorithm. Using a faster sorting algorithm like Quicksort or Mergesort could improve the overall performance.
As for Algorithm func2 , one way to optimize it could be to reduce the space complexity by finding ways to store data more efficiently or by utilizing data structures that require less memory. Additionally, optimizing the code logic to reduce redundant operations or improving the overall algorithm design could also lead to performance enhancements.
Appendix: Source Code (in C)
1 |
|
Declaration
I hereby declare that all the work done in this project titled “Hard Performance Measurement (A+B)” is of my independent effort.