[Instructions] [Search] [Current] [News] [Syllabus] [Glance] [Links] [Handouts] [Project] [Outlines] [Labs] [Assignments] [Quizzes] [Exams] [Examples] [EIJ] [JPDS] [Tutorial] [API]

**Assigned:** Friday, March 3, 2000

**Due:** Friday, March 10, 2000

While you may discuss this assignment with other students, and even work out solutions together, I would prefer if each student wrote up his or her own solutions.

You may find the following programs helpful for problems 2 and 3:

Bound the running time using Big-O notation of each of the following algorithms. Try to make the bound as close as possible. Note that you may have to come up with an appropriate metric for the size of each problem.

To find the smallest value in a collection ...Set smallestSoFar to one value in the collection While unchecked values remain in the collection Pick one If that value is smaller than guess then Set smallestSoFar to that value Return smallestSoFar

To find the smallest value in a collection ...If the collection is empty then Report an error Otherwise, if the collection has only one value then Return that value Otherwise Split the collection into two parts Find the smallest value in each part Take the minimum of those two values

To find the smallest difference between any two different numbers in a collection ...List all pairs of different numbers in the collection Set estimate to the difference between the values in the first pair For each remaining pair Compute the difference between the two values If that differences is less than estimate then Set estimate to that difference Return estimate

To find the smallest difference between any two different numbers in a collection ...Set estimate to ``infinity'' For each value, v, in the collection For each value, u, not equal to v If |u-v| < estimate then Set estimate to |u-v| Return estimate

Here's an iterative algorithm that finds the square root of a value to a specified accuracy.

/** * Compute the square root of val to accuracy 1/n. * Pre: (1) val >= 0 * (2) n > 0 * (3) The square root of val can be represented. * Post: (1) Returns a value v such that |v-sqrt(val)| < 1/n. */publicstaticdoublesqrt(doubleval,longn) {// Compute 1/nth of the range of possible valuesdoubleaccuracy = 1.0/((double) n);// Start with an initial guessdoubleguess = 0;// Determine the difference between the square of the guess// and the actual square root.doublediffsquared = val;// Step through all the possible values between 0 and val.for(doublenextguess = 0.0; nextguess <= val; nextguess = nextguess + accuracy) {// Compute the difference between the square of the guess// and the actual value.doublenextdiff = Math.abs(nextguess*nextguess-val);// If it's better, use it.if(nextdiff < diffsquared) { guess = nextguess; diffsquared = nextdiff; } } // forreturnguess; } // sqrt(double,double)

As you might be able to tell, what this algorithm basically does
is divide the interval between 0 and *val* into potential
guesses that occur every 1/n units. It then tries each of these
guesses and uses the best. Why 0 and *val*? Because we
know that the square root of *val* is at least 0 and no more
than *val*.

The running time of this algorithm is somewhat strange. It's based
on both *n* and *val*. More or less, this algorithm
is O(*n***val*).

Make the algorithm more efficient by using a divide-and-conquer strategy. You need not write working Java code, although you will receive a modicum of extra credit for writing working code.

Determine the running time of the revised algorithm.

[This problem is based on a similar problem discussed in
Duane Bailey's *Java Structures*.]

Suppose we have a package to send. We know how much it will cost to send the package. We'd like to minimize the number of stamps to purchase in order to send the package without paying extra. For example, if the package costs $0.40 to mail and the post office sells $0.50, $0.33, $0.20, $0.05, and $0.01 stamps, we'd purchase two $0.20 stamps (even though one $0.50 stamp would require fewer stamps).

Here's an approximate algorithm to determine the number of stamps we need. We assume that it is always possible to come up with a combination of stamps, no matter what value. (For example, we disallow the case when we want $0.07 and only $0.02 stamps are available.)

Our strategy is to see which stamp is best to buy now, and then go on (more or less). How do we know which is best to buy know? We recursively check how many steps it would cost if we bought each stamp and take the minimum of those numbers.

/** * Compute the minimum number of stamps that exactly * totals val cents. * Pre: (1) val >= 0 * (2) All stamps values are positive. * (3) It is possible to combine stamps for any value. * Post: Returns N such that it is possible to buy N stamps * for exactly val and it is not possible to buy M < N * stamps for exactly val. */publicstaticintminimumStamps(intval,int[] stampValues) {// Base case: You need no stamps for 0 cents.if(val == 0) {return0; }// Recursive case: Minimize alternativeselse{inti = 0;// An index into stampValuesintguess;// Our best guess so far as to the minimum.intnextGuess;// Another guess to tryintstampToBuy;// The stamp to buy in this round.// Find the first stamp that's still worth buying.while(stampValues[i] > val) i++;// We might buy that stamp.stampToBuy = stampValues[i];intguess = 1 + minimumStamps(val-stampValues[i], stampValues);// But we might also buy other stamps.for(i = i+1; i < stampValues.length; i++) {if(stampValues[i] <= val) { nextGuess = 1 + minimumStamps(val-stampValues[i], stampValues);if(nextGuess < guess) { stampToBuy = stampValues[i]; guess = nextGuess; } } // if the stamp is worth buying. } // for// That's it, we're donereturnguess; } // recursive case } // minimumStamps(int, int[])

Augment `Stamps.java`

so that it counts the number of calls (recursive and otherwise) to
`minimumStamps`

. How many calls are made when you compute
the number of stamps for 1, 5, 8, 10, 15, 20, 35, 40, 50, and 53 cents?

As you may have noticed, this algorithm gets very slow as *val*
gets large. Using the technique of caching smaller results in a table
(a technique we call *dynamic programming*) that we used with
such success in the box-packing and Fibonacci algorithms, rewrite this
algorithm. You need not write working code, but it would be nice if you
did.

Wednesday, 1 March 2000

- Created.

Thursday, 2 March 2000

- Filled in the details.
- Part 1 is based in part on assignment 3 of CS152 99F.
- Parts 2 and 3 are new.

Monday, 6 March 2000

- Corrected confusing sentence.

[Instructions] [Search] [Current] [News] [Syllabus] [Glance] [Links] [Handouts] [Project] [Outlines] [Labs] [Assignments] [Quizzes] [Exams] [Examples] [EIJ] [JPDS] [Tutorial] [API]

**Disclaimer** Often, these pages were created "on the fly" with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.

This page may be found at http://www.math.grin.edu/~rebelsky/Courses/CS152/2000S/Assignments/assign.03.html

Source text last modified Mon Mar 6 08:13:02 2000.

This page generated on Mon Mar 6 08:40:06 2000 by Siteweaver. Validate this page's HTML.

Contact our webmaster at rebelsky@grinnell.edu