Comparing Execution time with Time Complexity in Merge & Quick Sort - time-complexity

I have implemented Merge & Quick Sort in the textbook what I've learned, and it says Time Complexities of each sorts are like this:
Merge Sort: O(n.log(n)) / Quick Sort: average O(n.log(n)) and O(n2) in the worst case (if key array is sorted).
So I executed the programs with Two types of Arrays: sorted and random, with different sizes.
Since I wanted to get the Average time, I have tried 10 times per each case.
Here is the code of Merge & Quick Sort:
#include <iostream>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
void Merge(vector<int>& s, int low, int mid, int high) {
int i = low;
int j = mid + 1;
int k = low;
vector<int> u(s);
while (i <= mid && j <= high) {
if (s.at(i) < s.at(j)) {
u.at(k) = s.at(i);
i++;
} else {
u.at(k) = s.at(j);
j++;
}
k++;
}
if (i > mid) {
for (int a = j; a < high + 1; a++) {
u.at(k) = s.at(a);
k++;
}
} else {
for (int a = i; a < mid + 1; a++) {
u.at(k) = s.at(a);
k++;
}
}
for (int a = low; a < high + 1; a++)
s.at(a) = u.at(a);
}
void MergeSort(vector<int>& s, int low, int high) {
int mid;
if (low < high) {
mid = (low + high) / 2;
MergeSort(s, low, mid);
MergeSort(s, mid + 1, high);
Merge(s, low, mid, high);
}
}
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
void Partition(vector<int>& s, int low, int high, int& pvpoint) {
int j;
int pvitem;
pvitem = s.at(low);
j = low;
for (int i = low + 1; i <= high; i++) {
if (s.at(i) < pvitem) {
j++;
swap(s.at(i), s.at(j));
}
pvpoint = j;
swap(s.at(low), s.at(pvpoint));
}
}
void QuickSort(vector<int>& s, int low, int high) {
int pvpoint;
if (high > low) {
Partition(s, low, high, pvpoint);
QuickSort(s, low, pvpoint - 1);
QuickSort(s, pvpoint + 1, high);
}
}
And each of these main() functions are printing the execution times in SORTED, and RANDOM key arrays.
you can see the result with adding one of these main functions in Visual Studio(C++):
//Sorted key array
int main() {
int s;
for (int i = 1; i < 21; i++) { //Size is from 300 to 6000
s = i * 300;
vector<int> Arr(s);
cout << "N : " << s << "\n";
//Assign Random numbers to each elements
Arr.front() = rand() % Arr.size();
for (int j = 1; j < Arr.size(); j++) { Arr.at(j) = ((737 * Arr.at(j - 1) + 149) % (Arr.size() * 5)); }
sort(Arr.begin(), Arr.end());
//QuickSort(Arr, 0, Arr.size() - 1); <- you can switch using this instead of MergeSort(...) below
for (int i = 0; i < 10; i++) { //print 10 times of execution time
clock_t start, end;
start = clock();
MergeSort(Arr, 0, Arr.size() - 1);
end = clock() - start;
printf("%12.3f ", (double)end * 1000.0 / CLOCKS_PER_SEC);
}
cout << endl;
}
return 0;
}
//Random key array
int main() {
int s;
for (int i = 1; i < 21; i++) {
s = i * 3000;
vector<int> Arr(s);
cout << "N : " << s << "\n";
for (int i = 0; i < 10; i++) {
//Assign Random numbers to each elements
Arr.front() = rand() % Arr.size();
for (int j = 1; j < Arr.size(); j++) { Arr.at(j) = ((737 * Arr.at(j - 1) + 149) % (Arr.size() * 5)); }
//QuickSort(Arr, 0, Arr.size() - 1); <- you can switch using this instead of MergeSort(...) below
clock_t start, end;
start = clock();
MergeSort(Arr, 0, Arr.size() - 1);
end = clock() - start;
printf("%12.3f ", (double)end * 1000.0 / CLOCKS_PER_SEC);
}
cout << endl;
}
return 0;
}
And the THING is, the result is not matching with their time complexity. for example, Merge sort in(RANDOM Array)
size N=3000 prints 20 ms, but size N=60000 prints 1400~1600 ms !! it supposed to print almost 400 ms because Time complexity (Not in worse case) in Quick Sort is O(n.log(n)), isn't it? I want to know what affects to this time and how could I see the printed time that I expected.

You posted the same code in this question: Calculate Execution Times in Sort algorithm and you did not take my answer into account.
Your MergeSort function has a flaw: you duplicate the whole array in merge causing a lot of overhead and quadratic time complexity. This innocent looking definition: vector<int> u(s); defines u as a vector initialized as a copy of s, the full array.
C++ is a very powerful language, often too powerful, littered with traps and pitfalls such as this. It is a very good thing you tried to verify that your program meets the expected performance from the known time complexity of the algorithm. Such a concern is alas too rare.

Here are some guidelines:
For getting execution time:
#include <time.h>
int main()
{
struct timeval stop, start;
int arr[10000];
gettimeofday(&start, NULL);
mergeSort(arr, 0, 9999);
gettimeofday(&stop, NULL);
printf("Time taken for Quick sort is: %ld microseconds\n",
(stop.tv_sec-start.tv_sec)*1000000+stop.tv_usec-start.tv_usec);
}

Related

BIG WEIRD ANSWER in a MATRIX multiplication program

this is a program to multiply 2 matrixes which comes in maths, but dont know why, am getting answers like "-1282230" or some weird numbers. I would like to know what is causing it and how could i fix it? THANK YOU!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
int m[3][3],m2[3][3],i,je,k,ans[3][3],sum;
// taking inputs from the user for matrix1
printf("Enter the numbers for first matrix");
je=0;
for(i=0;i<3;i++){
printf(" for row %d\n",i+1);
for(je=0;je<3;je++){
scanf("%d",&m[i][je]);
}
}
// taking inputs from the user for matrix2
printf("Enter the numbers for second matrix");
je=0;
for(i=0;i<3;i++){
printf(" for row = %d\n",i+1);
for(je=0;je<3;je++){
scanf("%d",&m2[i][je]);
}
}
// multiplication OR MATRIX CMS HERE;
sum = 0;
for(k=0;k<9;k++){
for(i=0;i<3;i++){
for(je=0;je<3;je++){
sum = m[k][je] * m2[je][i];
ans[i][je] = sum;
}
}
k++;
}
// it ENDS;
puts("ANSWER IS:: \n");
// Displaying answer, matrix;
for(i=0;i<3;i++){
for(je=0;je<3;je++){
printf("%d\t",ans[i][je]);
}
printf("\n");
}
return 0;
}
Here's a working solution. One of the problem with your code is that you aren't setting the sum to 0 after each multiplication.
#include <stdio.h>
int main() {
int m, n, p, q, c, d, k, sum = 0; int first[10][10], second[10][10], multiply[10][10];
printf("Enter number of rows and columns of first matrix\n"); scanf("%d%d", &m, &n); printf("Enter elements of first matrix\n");
for (c = 0; c < m; c++)
for (d = 0; d < n; d++)
scanf("%d", &first[c][d]);
printf("Enter number of rows and columns of second matrix\n"); scanf("%d%d", &p, &q);
if (n != p)
printf("The matrices can't be multiplied with each other.\n"); else {
printf("Enter elements of second matrix\n");
for (c = 0; c < p; c++)
for (d = 0; d < q; d++)
scanf("%d", &second[c][d]);
for (c = 0; c < m; c++) {
for (d = 0; d < q; d++) {
for (k = 0; k < p; k++) {
sum = sum + first[c][k]*second[k][d];
}
multiply[c][d] = sum;
sum = 0;
}
}
printf("Product of the matrices:\n");
for (c = 0; c < m; c++) {
for (d = 0; d < q; d++)
printf("%d\t", multiply[c][d]);
printf("\n");
}
}
return 0; }

compare images using systemC

I wrote in this forum asking for help to solve this problem that took ame a lot of my time,i write my first program using systemC, I will expain my aim as much as I can , I stored 2 matrix of pixel value of image in two different text files, I write a systemC code that load two matrix and apply somme of absolute difference, if number of different superior of a Threshold the code displays message (motion).
My code composed of two modules, the first module check if there a number stored in a text file, if yes this Module will automates the other module to load the two matrix and compare them, I really need this code for my project graduation any help or suggestion.
#include "systemC.h"
#include "string.h"
#include "stdio.h"
#include"stdlib.h"
#include <time.h>
#include <math.h> /* fabs */
#include <fstream>
#include <iostream>
#include <fstream>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
double elapsed;
int H = 0;
int D = 0;
int a, b;
int in = false;
int L = 0;
char *mode1 = "r";
char *mode2 = "w";
int i, j, k;
int rows1, cols1, rows2, cols2;
bool fileFound = false;
FILE *SwitchContext;
FILE *image1;
FILE *image2;
FILE *image3;
int sum = 0;
clock_t start = clock();
SC_MODULE(synchronization)
{
sc_in<bool>sig ;
SC_CTOR(synchronization)
{
SC_METHOD(synchroprocess)
}
void synchroprocess()
{
cout << "\n Running Automation";
SwitchContext = fopen("F:/SWITCH CONTEXT.txt", mode2);
fscanf(SwitchContext, "%d", &L);
while (L != 0)
{
cout << "waiting...";
}
sig == true;
}
};
SC_MODULE(imageProcess)
{
sc_in<bool>sig;
SC_CTOR(imageProcess)
{
SC_METHOD(MotionDetector)
sensitive(sig);
}
void MotionDetector()
{
image3 = fopen("F:/image3.txt", mode2);
do
{
char *mode1 = "r";
char *mode2 = "w";
image1 = fopen("F:/image1.txt", mode1);
if (!image1)
{
printf("File Not Found!!\n");
fileFound = true;
}
else
fileFound = false;
}
while (fileFound);
do
{
image2 = fopen("F:/image2.txt", mode1);
if (!image2)
{
printf("File Not Found!!\n");
fileFound = true;
}
else
fileFound = false;
}
while (fileFound);
rows1 = rows2 = 384;
cols1 = cols2 = 512;
int **mat1 = (int **)malloc(rows1 * sizeof(int*));
for (i = 0; i < rows1; i++)
mat1[i] = (int *)malloc(cols1 * sizeof(int));
i = 0;
int **mat2 = (int **)malloc(rows2 * sizeof(int*));
for (i = 0; i < rows2; i++)
mat2[i] = (int *)malloc(cols2 * sizeof(int));
i = 0;
while (!feof(image1))
{
for (i = 0; i < rows1; i++)
{
for (j = 0; j < cols1; j++)
fscanf(image1, "%d%", &mat1[i][j]);
}
}
i = 0;
j = 0;
while (!feof(image2))
{
for (i = 0; i < rows2; i++)
{
for (j = 0; j < cols2; j++)
fscanf(image2, "%d%", &mat2[i][j]);
}
}
i = 0;
j = 0;
printf("\n\n");
for (i = 0; i < rows1; i++)
{
for (j = 0; j < cols1; j++) {
a = abs(mat1[i][j] = mat2[i][j]);
b = b + a;
}
}
i = j = 0;
D = b / 196608;
if (D > 0.9)
{
printf("%d,&K");
printf("MOTION...DETECTED");
getchar();
sc_pause;
for (i = 0; i < rows1; i++) {
for (j = 0; j < cols1; j++)
{
fprintf(image3, "%d ", mat2[i][j]);
}
fprintf(image3, "\n");
}
printf("\n Image Saved....");
std::ofstream mon_fichier("F:\toto.txt");
mon_fichier << elapsed << '\n';
}
fclose(image1);
fclose(image2);
fclose(image3);
clock_t end = clock();
elapsed = ((double)end - start) / CLOCKS_PER_SEC;
printf("time is %f", elapsed);
}
};
int sc_main(int argc, char* argv[])
{
imageProcess master("EE2");
master.MotionDetector();
sc_start();
return(0);
}
What you did is basically wrong.
You copy pasted code to SC_MODULE, this code is simple C code
(Do not mix C and C++ files)
This is not how you use clock
What you should do:
You need to check if your algorithm works, for this you do not need SystemC at all
Then you can replace data types with HW one and check if it still works
Then you have to find which data interface is used in HW and how to use this interface
Then you have to tweak your alg. to work with this interface (There you can use SC_MODULE, sc ports etc...)
Also take look at SC_CTHREAD, you will need it.
Without any informations about target platform I can not provide any other help.

TLE in Foe Pairs (Educational Codeforces Round 10)

On implementing O(N+M) complexity code for Foe Pairs problem
http://codeforces.com/contest/652/problem/C, I am getting TLE in Test Case 12.
Constraint : (1 ≤ N, M ≤ 3·105)
I am not getting, why for this constraint O(N+M) is getting TLE.
Here, is the code
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
std::vector<int> v(n+1);
for (int i = 0; i < n; ++i)
{
int x;
cin>>x;
v[x] = i;
}
std::vector<int> dp(n,0);
for (int i = 0; i < m; ++i)
{
int a,b;
cin>>a>>b;
if(v[a]>v[b])
swap(a,b);
dp[v[b]] = max(dp[v[b]], v[a]+1);
}
for (int i = 1; i < n; ++i)
{
dp[i] = max(dp[i], dp[i-1]);
}
long long s = 0;
for (int i = 0; i < n; ++i)
{
s+=(i+1-dp[i]);
}
cout<<s;
}
Is there anything, I am missing?
I changed all cin to scanf, it passed all test cases : http://codeforces.com/contest/652/submission/17014495
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n,m;
scanf("%d%d", &n, &m);
//cin>>n>>m;
std::vector<int> v(n+1);
for (int i = 0; i < n; ++i)
{
int x;
//cin>>x;
scanf("%d", &x);
v[x] = i;
}
std::vector<int> dp(n,0);
for (int i = 0; i < m; ++i)
{
int a,b;
//cin>>a>>b;
scanf("%d%d", &a, &b);
if(v[a]>v[b])
swap(a,b);
dp[v[b]] = max(dp[v[b]], v[a]+1);
}
for (int i = 1; i < n; ++i)
{
dp[i] = max(dp[i], dp[i-1]);
}
long long s = 0;
for (int i = 0; i < n; ++i)
{
s+=(i+1-dp[i]);
}
cout<<s;
return 0;
}
You should always try to use scanf when the amount of input is large as it is faster.
You can read more about scanf being faster here : Using scanf() in C++ programs is faster than using cin?

Confusion about my QuickSort algorithm & Mergesort algorithm

I am currently conducting empirical studies to evaluate the run-time complexities of the quicksort, and mergesort algorithms. To do this I run a random number generator that stores whatever amount of numbers I specify in a binary file. The ranges of those numbers are from 1-1,000,000.I then run tests of each algorithm starting from 100,000 numbers, incrementing by 50,000 each time, until 1,000,000 numbers are sorted on the last run. So 20 tests each. I have successfully completed each algorithm but my results are kind of puzzingly. This is a graph showing my results.
I understand that quicksort has a worst case of O(n2) time, but typically O(n·lg(n)) time. Mergesort has Θ(n·lg(n)) time.
Also I would like to note that when I started the timer I just used clock() from time.h, and calculated the time elapsed. I started my timer one line of code before I called my sorting function.
What I dont understand is how my graph shows mergesort is always double the time, and reaching triple the time to sort numbers compared to quicksort.
My only thought is that for my mergesort algorithm every time I divide my array in half I use malloc to create a new integer array for each half. Of course this means a large amount of calls are made to malloc considering the number sizes I am sorting.
int* mergeSort(int* nums, int size){
int* left;
int* right;
int middle = size/2;
if(size <= 1)
return nums;
split(nums, size, &left, &right, middle);
//I dont understand why the code below wouldnt work in place of the split()
//when i run it, in main, nothing gets printed out. I guess i lose my pointer to the beginning of my array.
//left = nums;
//right = nums+middle;
left = mergeSort(left, middle);
right = mergeSort(right, size - middle);
merge(nums,left,right,middle,size - middle);
free(left);
free(right);
return nums;
}
void split(int* nums, int size, int** left, int** right, int middle){
int *lft = (int*) malloc ((sizeof(int) * middle));
int *rght = (int*) malloc ((sizeof(int) * size - middle));
int mid = middle;
int upMid = size - middle;
int i;
for(i=0; i < mid; i++)
lft[i] = nums[i];
for(i=0; i < upMid; i++)
rght[i] = nums[i+middle];
*left = lft;
*right = rght;
}
void merge(int* num, int* left, int* right, int sizeLeft, int sizeRight){
int i,j,k,n;
i=j=k=0;
n=sizeLeft + sizeRight;
while(k < n){
if(i< sizeLeft){
if(j<sizeRight){
insert(num,left,right,&i,&j,&k);
}
else{
append(num, left, sizeLeft, &i, &k);
}
}
else{
append(num,right,sizeRight,&j,&k);
}
}
}
void insert(int* num, int* left, int* right, int* i, int* j, int* k){
/*int i,j,k,n;*/
if(left[*i]<right[*j]){
num[*k] = left[*i];
(*i)++;
}
else{
num[*k] = right[*j];
(*j)++;
}
(*k)++;
}
void append(int* num, int* half, int sizeHalf, int* i, int* k){
while(*i < sizeHalf){
num[*k]= half[*i];
(*i)++; (*k)++;
}
}
I would greatly appreciate any feedback on this question of mine, and any advice on maybe making my mergesort function more efficient. Thanks!!
I have implemented a merge sort algorithm, you can have a look. I malloc a bak array at the beginning of mergeSort and every merge use the it afterwards.
#include <string>
#include <stdlib.h>
void _mergeSort(int *array, int *bakArray, int len) ;
void mergeSort(int *array, int len)
{
int *bak = (int *)malloc(sizeof(int)*len) ;
_mergeSort(array, bak, len) ;
free(bak) ;
}
void _mergeSort(int *array, int *bakArray, int len)
{
if (len >= 2) {
int leftLen = len/2 ;
_mergeSort(array, bakArray, leftLen) ;
_mergeSort(array+leftLen, bakArray, len-leftLen) ;
int *pa = array ;
int *pb = array+leftLen ;
int aIndex = 0 ;
int bIndex = 0 ;
while (aIndex < leftLen && bIndex < len-leftLen) {
int a = pa[aIndex] ;
int b = pb[bIndex] ;
if (a < b) {
bakArray[aIndex+bIndex] = a ;
++aIndex ;
} else if (a == b) {
bakArray[aIndex+bIndex] = a ;
bakArray[aIndex+bIndex+1] = a ;
++aIndex ;
++bIndex ;
} else {
bakArray[aIndex+bIndex] = b ;
++bIndex ;
}
}
if (aIndex < leftLen) {
memcpy(bakArray+aIndex+bIndex, pa+aIndex, sizeof(int)*(leftLen-aIndex)) ;
} else if (bIndex < len-leftLen) {
memcpy(bakArray+aIndex+bIndex, pb+bIndex, sizeof(int)*(len-leftLen-bIndex)) ;
}
memcpy(array, bakArray, sizeof(int)*len) ;
}
}
static const int MaxArraySize = 100 ;
int main()
{
srand(time(NULL)) ;
int array[MaxArraySize] ;
for (int i = 0 ; i < MaxArraySize; ++i) {
array[i] = rand() % 10000 ;
}
mergeSort(array, MaxArraySize) ;
for (int i = 0 ; i < MaxArraySize; ++i) {
printf("%d ", array[i]) ;
}
printf("\n") ;
return 0 ;
}

Codility extreme large Number error

I have a Codility test to take soon.
I was trying to find a modification in the code to avoid EXTREME LARGE NUMBERS ERROR by using LONG instead of INT... but this did not work.
Has anybody tried using CODILITY demo test and get a 100?
I went through previous posts but no solution to this particular problem.
MY CODE: COMPLEXITY O(N)... Still I got 94.
// you can also use includes for example:
// #include <algorithm>
#include<iostream>
#include<vector>
#include<math.h>
int equi ( const vector<int> &A ) {
if((int)A.size()==0)
return -1;
long int sum_l = A[0];
long int total_sum =0;
for(int i =0; i<(int)A.size();i++){
total_sum = total_sum + A[i];
}
int flag =0;
total_sum = total_sum -A[0];
if(total_sum == 0)
return 0;
for(int i=1; i<(int)A.size()-1;i++){
total_sum = total_sum - A[i];
if(sum_l ==total_sum){
flag=1;
return i;
}
sum_l= sum_l + A[i];
}
if(sum_l ==0)
return (int)A.size()-1;
if(flag ==0)
return -1;
}
I used long long, and I had not problem.
Try this one.
int left = A[0];
int right = 0;
for(int i: A){
right += i;
}
right -= left;
int diff = Math.abs(left - right);
for (int i = 1; i < A.length-1; i++) {
left += A[i];
right -= A[i];
int a = Math.abs(left - right);
if(diff > a){
diff = a;
}
}
return diff;