cs205: engineering software? |
(none) 25 June 2008 |
Problem Set 2 Procedural Abstraction and Using Abstract Datatypes |
Out: 30 August Due: Friday, 8 September (beginning of class) |
Collaboration Policy - Read Carefully: For this problem set, you may work alone or with one other student in the class. If you work with another student, you should both participate fully in all parts of the assignments and turn in one assignment with both of your names on it. Either way, feel free to ask other students for help and offer help to other students.
Purpose
For the next question, consider these two specifications for the sort procedure:
A. From the Java 2 Platform API documentation (java.util.Arrays):
public static void sort(int[ ] a) Sorts the specified array of ints into ascending numerical order. The sorting algorithm is a tuned quicksort, adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November 1993). This algorithm offers n*log(n) performance on many data sets that cause other quicksorts to degrade to quadratic performance. |
B. From the textbook (p.46):
public static void sort(int[ ] a) MODIFIES: a |
public static int [] histogram (int [] a) // unspecified { int maxval = 0; for (int i = 0; i < a.length; i++) { if (a[i] > maxval) { maxval = a[i]; } } int histo [] = new int [maxval + 1]; for (int i = 0; i < a.length; i++) { histo[a[i]]++; } return histo; }For example,
int [] test = { 1, 2, 3, 4, 6, 4, 3, 3, 0 } ; int [] hist = histogram (test);the value of hist will be [1, 1, 1, 3, 2, 0, 1].
The input file lists a task, followed by a number (which could represent the time required to complete the task), followed by a list of tasks upon which this dask depends. Lines that start with a # are treated as commments.
For example,
# Based on Figure 13.9 (p. 323) of textbook Engine 30 { Comm.getDocs TitleTable Doc Query WordTable } Comm.getDocs 50 { } TitleTable 60 { Doc } Doc 15 { } Query 30 { WordTable } WordTable 20 { Doc }describes the dependency graph shown in Figure 13.9 of the textbook.
The first task listed in the file (Engine in the example) is the main task. The output of your program should be a schedule of tasks that can be used to complete the main task, and the total time needed to complete it. For the example there are many possible valid schedules; one valid output would be:
Schedule: [Comm.getDocs, Doc, TitleTable, WordTable, Query, Engine] Completion time: 205Note that every task in the list is preceeded by all tasks upon which it depends.
We have provided you with several abstract datatypes that you should find helpful in building your implementation. Their specifications are at the end of this document. Note that we provide only the specifications and class file implementations, not the source code. Your code should work with any implementations of these datatypes that satisfy the provided specifications.
You should implement your program by creating a new TaskScheduler class (in the ps2 package) with a main method.
public class DirectedGraph<T> OVERVIEW: A DirectedGraph is a directed graphwhere V is a set of nodes (of type T), and E is a set of edges. Each edge is a pair (v1, v2), representing an edge from v1 to v2 in G. public DirectedGraph() EFFECTS: Creates a new, empty DirectedGraph: < {}, {} > public void addNode(T s) throws DuplicateException MODIFIES: this EFFECTS: If s is the name of a node in this, throws DuplicateNodeException. Otherwise, adds s to the nodes in this, with no adjacent nodes: Gpost = < Vpre U { s }, Epre > public void addEdge(T s, T t) throws NoNodeException, DuplicateException MODIFIES: this EFFECTS: If s and t are not nodes in this, throws NoNodeException. If there is already an edge between s and t, throws DuplicateEdgeException. Otherwise, adds an edge between s and t to this: Gpost = < Vpre, Epre U > public Set<T> getAdjacent(T s) throws NoNodeException EFFECTS: If s is not a node in this, throws NoNodeException. Otherwise, returns a set containing the nodes adjacent to s That is, returns the set of nodes { e | <s, e> is in E }
public class Set<T> implements Iterable<T>, Collection<T> { OVERVIEW: A Set is a mutable, unbounded set of objects of type T. A typical Set is {x_1, ..., x_n }. public Set() EFFECTS: Initializes this to an empty set: { }. public Set(Set<T> s) EFFECTS: Initializes this to a set containing the same elements as the set s (a shallow copy). public boolean add(T el) MODIFIES: this EFFECTS: Adds el to the elements of this: thispost = thispre U { el } Returns true iff el was not an element of thispre. public void union(Set<T> t) MODIFIES: this EFFECTS: this_post = this_pre U t public Iterator<T> iterator() REQUIRES: this must not be modified while the iterator is in use. EFFECTS: Returns an iterator that yields each element of this. public T choose() REQUIRES: this has at least one element EFFECTS: Returns an element of this. public boolean contains(Object el) EFFECTS: Returns true iff el is an element of this. public int size() EFFECTS: Returns the number of elements in this. public boolean isEmpty() EFFECTS: Returns true iff this has no elements. public boolean remove(Object el) MODIFIES: this EFFECTS: Removes el from this: this_post = this_pre - { el } Returns true iff el is in thispre
public class Task OVERVIEW: A typical Task is < name, time, dependencies > where name is the name of this task, time is the time it takes to complete it (in minutes), and dependencies is a set of tasks that must be completed before this task can be done. public Task (String p_name, int p_time, String [] p_dependencies) EFFECTS: Initializes this to the task. public String getName () EFFECTS: Returns the name of this. public int getTime () EFFECTS: Returns the time of this. public String [] getDependencies () EFFECTS: Returns the dependencies of this. public String toFullString () EFFECTS: Returns a detailed string description of this. public String toString () EFFECTS: Returns a short string description of this (just the name).
The most useful java.util.Vector methods are specified below:
public class Vector<T> { OVERVIEW: A Vector is a mutable, unbouded, ordered collection of objects of type T. A typical Vector is [x_0, ..., x_n]. public Vector() EFFECTS: Initializes this to an empty vector, []. public boolean add(T el) MODIFIES: this EFFECTS: Appends el to the end of this. Returns true. If this_pre = [x_0, ..., x_n], this_post = [x_0, ..., x_n, el]. public void add(int index, T el) REQUIRES: 0 <= index <= size MODIFIES: this EFFECTS: Inserts el at location index in this. All elements before index are preseved unchanged, and all elements after index are advanced one position. public boolean remove(Object el) MODIFIES: this EFFECTS: Removes the first occurance of an element whose value is equal to el (as matched using equals) from this. Returns true there is a matching occurance; otherwise, returns false and leaves this unchanged. public boolean contains(Object el) EFFECTS: Returns true iff an object with the same value as el is an element of the Vector as determined by equals.The Vector class also implements the Iterator interface, so you can iterate through the elements of a Vector (in order) using:
Vectorv = new Vector (); ... for (String el : v) { ... // Do something on each element }
public class Scanner { OVERVIEW: A Scanner provides an abstract interface to textual data. A typical Scanner is < c1, c2, c3, ..., cn > ^ where ci is the ith character in the text, and the cursor (^) points to the next character to process. A Scanner may be open or closed; a closed Scanner has no cursor. public Scanner(File source) throws FileNotFoundException EFFECTS: If source is not a readable file, throws FileNotFoundException. Otherwise, initializes this to a scanner containing the characters in the file source with the cursor pointing to the first character. public Scanner(String source) EFFECTS: Initializes this to a scanner containing the characters in the source string with the cursor pointing to the first character. public boolean hasNextLine() REQUIRES: this is an open scanner EFFECTS: Returns true iff there is another line in the text for this scanner. public String nextLine() REQUIRES: this is an open scanner and the cursor is not at the end of the input MODIFIES: this EFFECTS: Returns the next line in the text (from the current cursor to either the end of the text or a line separator character). The line separator is not included in the return value. The text of the scanner is unchanged. The cursor advances to the position immediately following the line separator if one was reached, or to the end of the text. public boolean hasNextInt() REQUIRES: this is an open scanner EFFECTS: Returns true if the characters starting from the current cursor can be interpreted as a valid integer. public int nextInt() REQUIRES: this is an open scanner and the cursor points to a sequence of characters that can be interpreted as an integer. MODIFIES: this EFFECTS: Return the value of the next integer in the file (using as many characters as possible to form a valid integer), and advances the cursor to the position immediately following the input used. public boolean hasNext() REQUIRES: this is an open scanner EFFECTS: Returns true if this scanner has another token. public String next() REQUIRES: this is an open scanner with at least one more token. MODIFIES: this EFFECTS: Returns the next token in this scanner, and advances the cursor to point to the position immediately following the returned token. The next token is as many non-whitespace characters as can be read until the next whitespace character.