CS 241 Frequently Asked Questions (FAQs)

Lab 4 Questions
Homework Questions
Old Lab Questions

Lab 4 Related Questions:

In BinaryHeapTester.java why is the Handle of type BinaryHeap.Handle?

BinaryHeapTester.java assumes that Handle is an innerclass of BinaryHeap. If you did not implement it that way then you can change the driver to just have:
   Handle[] handles = new Handle[5];
Note: Some students have had trouble making Handle an innerclass of BinaryHeap. A common problem is to have a class, call it BinaryHeapNode, which is NOT an innerclass of BinaryHeap but uses the Handle class. Both Handle and BinaryHeapNode should be an innerclass of BinaryHeap. As stated on the FAQ page (since early last week), if you do not want to use inner classes, you can change both occurences of BinaryHeap.Handle in the provided Driver to Handle.

For the "A" and "B" portions are we suppose to write a driver that reads the data from the test data and makes the appropriate calls to the WeightedUndirectedGraph class?

Yes, your driver needs to read the data from the provided testdata file and use this to make appropriate calls to your WeightedUndirectedGraph class (such as a constructor function that takes as input the number of vertices and a method to add an edge). You can do this using the Terminal class by just using the following four methods.
  Terminal.readInputFromFile("inputFileName");
  Terminal.startTranscript("transcriptFileName");
  int i = Terminal.readInt();
  double d = Terminal.readDouble();
Note that inputFileName, transcriptFileName, i and d can be placed by whatever names you want. Full documentation for the
Terminal class is on the course web page. This should be very easy to do.

Homework Related Questions:

For problem 2, do I have to use summation notation?

No, you do not. Here's an alternate way to work out the solution for this practice problem which is taken from HW 1 practice problems.
for (i=0; i<=n-1; i++){
   for (j=i+1; j<=n-1; j++){
      loop body
   }
}
Let's figure out how many times the loop body is executed for each value of i. Here's a table to show that:
  i         # times loop body executed for that i
-------     -------------------------------------
  0               n-1  (j goes from 1 to n-1)
  1               n-2
  .                . 
  .                . 
  .                . 
 n-2               1
 n-1               0
Hence the number of times the loop body is executed is given by
(n-1) + (n-2) + ... + 1 = (n-1)n/2 = n^2/2 - n/2 = Theta(n^2)
If you understand this you may find it useful to compare this to the solution that uses summations to see that they are really doing exactly the same thing.

For problem 4, how do I show that f(n) + g(n) = Theta(g(n))

To do this you must show that
(1) f(n) + g(n) = O(g(n)), and
(2) f(n) + g(n) = Omega(g(n))
Think of these as two independent proofs. If either is false (as demonstrated by a counterexample) then you will have a counterexample to the original statement that f(n) + g(n) = Theta(g(n)). And of course if you prove (1) and (2) above are both true then you have proven that
f(n) + g(n) = Theta(g(n)).

Also for Problem #4, remember that if you, for example, are showing that

If f(n) = O(g(n)) then g(n) = Omega(f(n))
then you first assume that f(n) = O(g(n)). This means that there exists constants c>1 and n0 such that for all n >= n0 f(n) <= c g(n).

Remember, you CANNOT pick a value for c and n0. You just know that they exist.

To prove that this is true, you must show that there exists constants c' and n0' such that for all n >= n0', g(n) >= c' f(n).

You can pick c' and n0' to be any constants that you want since you just need to prove the existence of such constants. They may depend on c and n0 but don't have to.

If lim as n -> infinity of f(n)/g(n) = 0, how does this relate to big-Oh, big-Omega and big-Theta notation?

As discussed in class, in this case when the given limit of f(n)/g(n) goes to 0 as n goes to infinity, we know that f(n) is asymptotically SLOWER growing. Informally, f(n) asymptotically < g(n).

Hence f(n) = O(g(n)), yet f(n) != Omega(g(n)) and f(n) != Theta(g(n)).

Similarly, if lim as n -> infinity of f(n)/g(n) = infinity then f(n) is the asymptotically FASTER growing function.
Informally, f(n) asymptotically > g(n).

Hence f(n) != O(g(n)), yet f(n) = Omega(g(n)) and f(n) != Theta(g(n)).

Finally if the limit goes to a constant then f(n) and g(n) grow asymptotically at the same rate so

f(n) = O(g(n)), f(n) = Omega(g(n)) and f(n) = Theta(g(n)).


Don't forget about the practice problems.


Lab Related Questions:

Lab 2 Related Questions:

What packages do I need to import to use the file I/O demonstrated in fileEx.java?

import java.io.*;

Can I use Java's built-in hashtable?

As clearly indicated in class, you may NOT use Java's hashtable class. The goal of this lab is for you to write your own hashtable class.

What do I use for my hash table?

Your hashtable will be an array of objects which hold a key and a DataRecord. (Suppose that you define a DictionaryRecord class. In Java remember that when you have an array of type DictionaryRecord, each entry of the array is really a reference to a DictionaryRecord).

When I open a transcript file and read the inpt from a file, no output goes to the screen. Is this okay?

Yes. The Terminal class was modified to do this. The reason is that without the answers to the questions (and the associated line feeds) the output to the Terminal isn't meaningful and hence I thought it would be better to only put the name of the transcript file. All of your output (as well as the answers to the questions) will be in the transcript file.

Lab 1 Related Questions:

The points being drawn by the Plotter don't seem to match the x and y-coordinates of the points?

The distribution that was selected for the test data generates points where the x-coordinate is an integer between 0 and 100000 and where the y-coordinate is an integer between 0 and 300000. However, the calls made to the Plotter class scaled them to fit into a square. While it is doing this correctly, it causes a distortion in terms of the physical distance on the screen corresponding to the true distance. If you would like to remove this distortion, change the 100000 in the "new Plotter" lines to 300000. That is by changing:
	new Plotter(ptsByX,0,0,100000,300000,true,"Sorted by X-coordinate");
	new Plotter(ptsByY,0,0,100000,300000,true,"Sorted by Y-coordinate");
        new Plotter(ptsByX,0,0,100000,300000,false,"Output");
correspondingly to
	new Plotter(ptsByX,0,0,300000,300000,true,"Sorted by X-coordinate");
	new Plotter(ptsByY,0,0,300000,300000,true,"Sorted by Y-coordinate");
        new Plotter(ptsByX,0,0,300000,300000,false,"Output");
the distortion will no longer be there. Of course you'll see that all of the x-coordinates are on the leftmost third of the plot -- this is just the way the data is.

How am I supposed to create the graph requited in the "A" portion?

You can create the graph anyway you would like (including by hand on a piece of graph paper).

I'm using C++ and getting a compile error with the provided code

You can correct this by replacing
    p->y(200000 - p->x);
    p->y(p->y + randint(-100000,100000));
by
    p->y(200000 - p->x());
    p->y(p->y() + randint(-100000,100000));
Each of those lines was missing a set of parentheses (in the first after the p->x and in the second after the second occurence of p->y). The provided code has been changed if you would find it easy to just get a new copy.

Where can I find the transcript file?
How do I create a transcript file?

One way to do this is simply give the name you would like for the transcript file as a command line argument when you run the program. For example:
   Java Lab1 transcript.txt
will create the transcript file "transcript.txt". In the PC environments there should be a menu item to give a command line argument.

If you do not know how to give a command line argument then you can just add the following line to your program:

   Terminal.startTranscript("transcript.txt");
and the output will be saved in the file transcript.txt. Of course you can pick any file name that you like. Just put this line before the line that starts java.util.Random or anywhere before the first println occurs.

For my Java implementation of Lab 1, do I have to implement the closest pair procedure as a static method?

No, you do not have to. Feel free to modify any of the provided code. However, there is no probem with having this as a static method. If you are having trouble with how to call a static method, see the next question.

In my Java implementation of Lab 1, is it possible for me to call the closestPair method without instantiating a FastClosestPair object?

Yes. Suppose that your closestPair method returns a double. Then you can make it a public static method by using:
public static double closestPair(XYPoint[] ptsByX, XYPoint[] ptsByY){

   Put your method here... Also, of course you can pick whatever 
    variable names you want for the two arrays.
}
Then, for example, your call from Lab1.java would look like:
    double ans = FastClosestPair.closestPair(ptsByX,ptsByY);

Approximately what run times should I be seeing for my correct implementation of Lab 1?

Of course this will vary based on the speed of the processor you have. To give you a ballpark on a UltraSparc 30 using C++ with 6525 points it took approximately 0.4 seconds (versus 20 seconds for the naive algorithm) and using Java with 6525 points it took approximately 1 second (versus 1 minute for the naive algorithm). Of course, the naive algorithm gets substantially worse as the number of points increases! By 50,000 points there's a difference of 12.76 secs for the divide-and-conquer algorithmv ersus about 55 minutes for the naive algorithm.

While these times will vary based on the hardware you use, if you plot a graph of time versus the number of points the only thing that really differs is the scale for the y-axis.

For my Java implementation of Lab 1, do I have to use the provided Plotter class?

No, it is just there to help you in debugging.

I'm using C++ but would prefer to use a different compiler than the one on CEC. Is this possible?

Sure. However, you will be responsible for making any needed modifications to the provided code. The provided IntervalTimer will not work on other platforms since it makes calls into the Unix operating system. You can replace this by whatever system utility you have to get the time. Then by getting the time before and after the algorithm runs you can take their difference to determine the elapsed time. Just be sure that your procedure is the only process running. Only small changes (if any) should be required for the rest. If you have further questions, come see us.

What do I use instead of infinity for my Lab 1 implementation?

In the Java implementation (in FastClosestPair.java) I've defined INF to be the maximum double possible which will work fine here since the maximum distance for the coordinate ranges you are given will always have a distance less than this quantity. For those using C++, I've already defined maxfloat as 400000.0 in the provided stdinc.h which is larger than the distance between any two points for the coordinate ranges that are used..

For my C++ implementation of Lab1, I get a segmentation fault but only for large values of n. What could this be?

Recall that in C++ when you access an array out of bounds, if the memory address you are accessing is allocated to your process (although not in the array you intended to access) then there will be no run-time error generated. Nevertheless, you may still be accessing an array out of bounds.

In your C++ lab if you are getting a segmentation fault then I would be willing to bet (with a good stake) that you are accessing an array out of bounds. Furthermore, you are probably doing this for small values of n even if the segmentation fault isn't occuring. So how do you find this if you don't see it in the code? What I suggest is that EVERY time you access an array, print out the name of the array, the size you allocated for it and the index you are accessing. The index should be between 0 and the size of the array-1.

How do I allocate an array of a size given by a variable?
Look at the driver where X, Y, and P are allocated.

My program works correctly for some values of n, but not all of them. Any ideas why?

Often this problem is related to forgetting how for loops work. Suppose you have a loop of the form:
         for (i=0; i < n; i++){
            loop body
         }
Remember that the value of i in the last iteration of the loop is n-1 (since it is the last integer value less than n). Recall that the above loop is equivalent to:
        i=0;
        while (i < n){
          loop body
          i++;
        }
I personally discourage the use of less than above but rather recommend the for loop is written like:
         for (i=0; i <= n-1; i++){
            loop body
         }
The most common place where I'm seeing this error is in the final loop. In class I put:
          for i = 0 to |Y'|-2
First, by |Y'| I mean the number of elements placed into the Y' array. In the above for loop i should go from 0 (the lowest point) to |Y'|-2 (the second to highest point).

How do I compile and run my C++ procedures for Lab 1?

For the "B" part (including the version in which you also return the pair of points along with the distance), you are expected to put your divide-and-conquer algorithm in a file called "closest-pair.cc" You will also need to modify lab1b.cc as indicated. A makefile is included with the provided code. Copy that into the directory with the rest of the code. Then just type "make". After successfull compilation and linking there will be a file called "lab1b.out". Just type "lab1b.out" to run it.

For timing the naive routine, notice that the sort routine is no longer needed and thus the calls to it (and the prototype at the top) should be removed.


Return to the CS 241 Home Page