[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.
*/
public static double sqrt(double val, long n) {
// Compute 1/nth of the range of possible values
double accuracy = 1.0/((double) n);
// Start with an initial guess
double guess = 0;
// Determine the difference between the square of the guess
// and the actual square root.
double diffsquared = val;
// Step through all the possible values between 0 and val.
for (double nextguess = 0.0;
nextguess <= val;
nextguess = nextguess + accuracy) {
// Compute the difference between the square of the guess
// and the actual value.
double nextdiff = Math.abs(nextguess*nextguess-val);
// If it's better, use it.
if (nextdiff < diffsquared) {
guess = nextguess;
diffsquared = nextdiff;
}
} // for
return guess;
} // 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.
*/
public static int minimumStamps(
int val,
int[] stampValues)
{
// Base case: You need no stamps for 0 cents.
if (val == 0) {
return 0;
}
// Recursive case: Minimize alternatives
else {
int i = 0; // An index into stampValues
int guess; // Our best guess so far as to the minimum.
int nextGuess; // Another guess to try
int stampToBuy; // 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];
int guess = 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 done
return guess;
} // 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
Thursday, 2 March 2000
Monday, 6 March 2000
[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