CS 415, Section 001 Sonoma State University Spring, 2023
 
Algorithm Analysis
Instructor: Henry M. Walker

Lecturer, Sonoma State University
Professor Emeritus of Computer Science and Mathematics, Grinnell College

Although much of this course is well developed, some details can be expected to evolve as the semester progresses.
Any changes in course details will be announced promptly during class.

Worksheet:  Analysis of Nonrecursive Algorithms

Summary

In this lab, you will analyze the complexity of some code and experimentally test your analyses.

Preparation

Download the file analysis.tgz, and decompress it with the line

     tar -xvf analysis.tgz

Upon decompression, a new directory analysis should have been created, and this directory should contain TestAnalysis.cpp, a main program, and functions (run1.cpp) ... run5.cpp)). TestAnalysis.cpp allows you to conduct experiments for the subsequent exercises. To compile this program use the line:

     make TestAnalysis

The program uses command-line input with two arguments.

For example, to run the code for Exercise 1 with n=100, you would type

 ./testAnalysis 1 100

Note: In this lab, a variable NUMBER_REPETITIONS is specified to repeat a segment of code NUMBER_REPETITIONS2 times. This allows reasonable timings to be compared within the accuracy of the clock.

Exercises

Exercise 0

Run program testAnalysis.cpp for Exercise 3 with n=100, following the instructions above:

 ./testAnalysis 3 100

Although timings will vary from machine to machine, `lThe output likely will look similar to the following:

Program to run and time loop-based code segments
Running Exercise 3 with time iterations = 300
   run repeated 800 squared times
result returned:  45000
looping time:           0.00 
method execution time  72.34 
loop execution time:   72.34 

Within the code, adjust the variable NUMBER_REPETITIONS, so that the time reported for "method execution time" is about a minute or a little more.

Now review the code to answer the following:

  1. Explain what is meant by the output line, "run repeated 800 squared times".
  2. What is measured by the "looping time"?
  3. Run the program several times with the same command-line parameters. To what extent does the "looping time" vary from run to tun?
  4. Run the program several times with different values for the Exercise number (but keeping the value of n at 100 in each case. To what extent does the "looping time" change with each experiment?
  5. What is measured by the "method execution time"?
  6. What is measured by the "loop execution time"?

Exercise 1

run1.cpp
#include "loop.h"

int run1(int n) {
  
  int sum = 0;

  for (int i=0 ; i < 2*n ; i+=4)
    sum++;

  return sum;
}

  1. Perform a careful micro-analysis of the time required for each line of this code. In your analysis, use the following constants for the time it takes a machine to do specific operations:

    Note: In your answer, be sure to give a separate time required for each line of the code. Likely, the amount of time for a line will involve some expression involving at least some of the variables n, A, B, S, M, and P.

  2. Once time is determined for each line, add to obtain the total time needed.
  3. If your answer for the total time involves a long summation of terms, use one or more Common Computational Formulae to obtain a relatively simple algebraic expression for the total time.
  4. Use your result for the total time to determine the Big-O, Big-Ω, and Big-Θ running times for run1, and explain your conclusions. For example, you likely will want to highlght which terms will dominate for large n and which will have minimal impact on the total time.
  5. Run the run1 procedure, with n equal 100, 200, 300, and 400, and record the times.
    1. Rounding to the nearest integer, about how many times longer does the actual run time for 200, 300, and 400 take versus the time for 100? (Hint: Simply divide the larger time by the smaller time and round to answer this question.)
    2. Based on your determination of Big-Ω from part d, how many times longer would the code for 400 take over the time for 100? (Hint: Compare n = 100 and n = 400 in your expression for Big-Ω, and divide.)
    3. To what extent is the factor for actual run time similar to the factor based on Big-Ω?

Exercise 2

run2.cpp
#include "loop.h"

int run2(int n) {

  int sum = 0;

  for (int i=0 ; i < n ; i++)
    sum++;
  for (int j=0 ; j < n ; j++)
    sum++;
  
  return sum;
}
  1. Using the constants defined in Step 1, perform a micro-analysis to determine Big-O, Big-Ω, and Big-Θ for this code segment. (That is, repeat parts a-d of Step 1 above.)
  2. Run the run2 procedure, with n equal 100, 200, 300, and 400, and record the times.
    1. Rounding to the nearest integer,about how many times longer does the time for 200, 300, and 400 take versus the time for 100?
    2. Based on your determination of Big-Ω from part a, how many times longer would the code for 400 take over the time for 100? (Hint: Compare n = 100 and n = 400 in your expression for Big-Ω, and divide.)
    3. To what extent is the factor for actual run time similar to the factor based on Big-Ω?
    4. How does the micro-analysis (from part 2a) compare to the micro-analysis (from 1d)?
    5. To what extent does the theoretical comparison predict with the actual times for the code in Exercises 1 and 2.

Exercise 3

run3.cpp
#include "loop.h"

int run3(int n) {

  int sum = 0;
  
  for (int i=0 ; i < n ; i++)
    for (int j=0 ; j < n/2 ; j++)
      sum++;
  
  return sum;
}
  1. Using the constants define in Step 1, perform a micro-analysis to determine Big-O, Big-Ω, and Big-Θ for this code segment.
  2. Run the run3 procedure, with n equal 100, 200, 300, and 400, and record the times.
    1. Rounding to the nearest integer,about how many times longer does the time for 200, 300, and 400 take versus the time for 100?
    2. Based on your determination of Big-Θ from part a, how many times longer would the code for 400 take over the time for 100? (Hint: Compare n = 100 and n = 400 in your expression for Big-Θ, and divide.)
    3. To what extent is the factor for actual run time similar to the factor based on Big-Θ?
    4. How does the micro-analysis (from part 3a) compare to the micro-analysis from 1d and 2a?
    5. To what extent does the theoretical comparison predict with the actual times for the code in Exercises 1, 2, and 3.

Exercise 4

run4.cpp
#include "loop.h"

int run4(int n) {

   int sum = 0;

   for (int i = 1 ; i <= n ; i++ )
     for (int j = i-1; j <= i+1; j++)
     sum++;
   
   return sum;

}
  1. Using the constants define in Step 1, perform a micro-analysis to determine Big-O, Big-Ω, and Big-Θ for this code segment.
  2. Run the run4 procedure, with n equal 100, 200, 300, and 400, and record the times.
    1. Rounding to the nearest integer,about how many times longer does the time for 200, 300, and 400 take versus the time for 100?
    2. Based on your determination of Big-Θ from part a, how many times longer would the code for 400 take over the time for 100? (Hint: Compare n = 100 and n = 400 in your expression for Big-Θ, and divide.)
    3. To what extent is the factor for actual run time similar to the factor based on Big-Θ?
    4. How does the micro-analysis (from part 4a) compare to the micro-analysis (from 1d)?
    5. To what extent does the theoretical comparison predict with the actual times for the code in Exercise 1 and 4.

Exercise 5

run5.cpp
#include "loop.h"

int run5(int n) {

   int sum = 0;

   for (int i = 1 ; i <= n * n ; i++ )
     for (int j = i-1; j <= i+1; j++)
     sum++;
   
   return sum;
 }
  1. Using the constants define in Step 1, perform a microanalysis to determine Big-O, Big-Ω, and Big-Θ for this code segment.
  2. Run the run5 procedure, with n equal 100, 200, 300, and 400, and record the times.
    1. Rounding to the nearest integer,about how many times longer does the time for 200, 300, and 400 take versus the time for 100?
    2. Based on your determination of Big-Θ from part a, how many times longer would the code for 400 take over the time for 100? (Hint: Compare n = 100 and n = 400 in your expression for Big-Θ, and divide.)
    3. To what extent is the factor for actual run time similar to the factor based on Big-Θ?
    4. How does the micro-analysis (from part 5a) compare to the micro-analysis from 1d and 4a?
    5. To what extent does the theoretical comparison predict with the actual times for the code in Exercises 1, 4, and 5.
created December 21, 2021
revised December-January 2021
revised Summer 2022
revised 1-2 January 2023
typos corrected 27 January 2023
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.
ccbyncsa.png

Copyright © 2011-2022 by Henry M. Walker.
Selected materials copyright by Marge Coahran, Samuel A. Rebelsky, John David Stone, and Henry Walker and used by permission.
This page and other materials developed for this course are under development.
This and all laboratory exercises for this course are licensed under a Creative Commons Attribution-NonCommercial-Share Alike 4.0 International License.