CSC 207 Grinnell College Spring, 2015
 
Algorithms and Object-Oriented Design
 

Supplemental Problems

Supplemental Problems extend the range of problems considered in the course and help sharpen problem-solving skills. Problems numbered 8 or higher may be turned in for extra credit.

Quick links: 1, 2, 3

Format:

In turning in any programs for the course, please submit the following materials, in the order specified (so the program with you name and box will be on top).

  1. Print and submit a paper copy of each Java class (copying and pasting from Eclipse is ok)

  2. Include within your code javadoc documentation for

    In particular, print and submit the javadoc documentation for your files.

  3. A printed copy of relevant test runs (copying and pasting ok)

  4. Commentary (typed or handwritten) regarding your testing of the code, including:

Email lab each class, test plan, test runs, and statement of correctness as separate attachments to grader-207-01@cs.grinnell.edu. Please include the assignment title (e.g., Lab 2) and the name of all co-authors in the Subject line.

Some Grading Notes:

Grading Forms

Two grading forms will be used in the grading of each supplemental problem.


A Simple Class Hierarchy

  1. This problem introduces some simplified elements related to a program to track shopping in a grocery store. Many details would be expanded greatly for a real application, but this problem might make a [small] start.

    Items available in a grocery store might be categorized as produce (e.g., vegetables, fruit, cheese, meat, etc.), beverages (bottled water, milk, soft drinks, energy drinks, etc.), and packages (boxes of crackers, noodles, tea, etc.). A class hierarchy to model this categorization of items follows:

    The Item class and its subclasses

    To clarify,

    For this problem, you should implement the following:

    1. Class definitions for Item and its subclasses Produce, Beverage, and Package

    2. A ShoppingCart class, modeled upon the SchoolDirectory class from the CSC 207 lab Generalization, Polymorphism, and Exceptions. The ShoppingCart class should have these features:

      • A private array Cart of Item objects:
        • The size of Cart is given by private field maxSize.
        • Field currentSize gives the actual number of objects stored in Cart, in positions Cart[0] to Cart[currentSize-1].
      • A method addItem places a new item object into the array, expanding the array as needed, and incrementing currentSize
      • A method printCart should provide a listing of all items in the cart.
      • A method totalCost should compute the total cost of all items in the cart.
      • A method numberInCart should take a parameter String groceryName and return how many items in the current shopping cart have that name.
        Notes:
        • An easy way to compare strings is to use the built-in compareTo method. That is, if str1 and str2 are two strings, then str1.equals(str2) returns true if the two strings are the same (including case) and false if the two strings differ in any way.
        • Although class Item and its subclasses contain a name field, this field is protected. Explain why numberInCart cannot be implemented in ShoppingCart with the specified fields and method for Item and its subclasses.
        • To implement numberInCart, class Item could be expanded in two ways (for reasons of correctness and security, we do not consider changing name to public.)
          • A method getName() could be added to class Item to return the name string.
          • A method equals (String str) could be defined in class Item which returns true if the name in the Item matches str and returns false otherwise.
          Modify Item with one of these approaches in order to implement numberInCart. Include a comment explaining why you chose this approach for expanding Item.

    Draft problem-specific grading form

Student Academic Status

  1. Students taking courses at Grinnell College may be considered to fall into one of four main categories: regular, alum, employee, and special. The following descriptions bend the rules somewhat, but provide a basic outline of each category.

    Note: The actual rules for Alum, Employee, and Special students involve courses, not credits. Alum and Employee students may take 1 course; Special students may take 2 courses. In the interests of sanity for this problem, however, the above rules will be considered in effect.

    Hierarchy of Enrolled-Student
                                              Categories

    Observations:

    Directions for this Problem:

    1. Implement the above class hierarchy: EnrolledStudent, NonRegular, Regular, Alum, Special, and Employee.
      • Use inheritance as much as possible to keep the writing of code to a minimum!
      • Once you have started EnrolledStudent with the definition of the relevant fields, check the "Generate Getters and Setters" option in Eclipse under the "Source" menu.
    2. Implement a Registrar class that contains an ArrayList of EnrolledStudents of the four types. (Note that Java's ArrayList is an expandable array, much like the arrays used with our SchoolDirectory example — but since ArrayList is already implemented, you need not do that!) Within the context of a Registrar class (either in an object or in main),
      • Several students of each type should be created and added to the ArrayList.
      • The Registrar class should contain a method to print all students in the ArrayList. For each student, the methods of EnrolledStudent should be called. If the information is available, it should be printed (Just put the method call into a print statement — do not test if the result is valid.) If an exception is thrown, processing should skip that part of output. Note that getMajor throws an exception for Special students, in which case getClassStanding and makingGoodProgress can be skipped as well. Also getClassStanding and makingGoodProgress throw exceptions for Alum students, so if one of these methods is called and generates an exception, then the other of these methods need not be called.

      Note that the idea of the Registrar class is to provide a mechanism for testing the various other classes. In most (all?) cases, careful design of tests for the Registrar class may cover testing for this entire assignment.

    3. Comments for each class and for all methods should be prepared in Javadoc format. Submission of the final code should include a URL where the generated Javadoc documentation can be found.

Queues of Different Priorities for Printing

  1. When a printer serves multiple users, users may sent several print requests to the operating system, but only one file can be printed at a time. Thus, the operating system can direct a file from one print request to the printer, but the other requests must be stored in some type of data structure. The simplest approach involves a single queue. Each user sends one or more files to the operating system, and the operating system places the print requests on a queue. The operating system then sends the files to the printer one-at-a-time from the print queue. Of course, once a printer starts to print a file, the printer must complete that job before moving onto the next print request. Although this approach is simple and treats all jobs equally, this approach has the disadvantage that many short printing jobs (of only a few pages) may have to wait substantial amounts of time for a large print job (hundreds of pages) to finish.

    One way to give some preference to certain print jobs is to create multiple queues of varying priorities. For convenience of notation, suppose a system has n queues, labeled q0, q1, q2, ..., qn-1. Suppose qi has priority i, where priority 0 is top priority, priority 1 is the next highest priority, ..., and priority n-1 is the lowest priority. That is requests in q0 are chosen before print requests in any other queue, and requests in qn-1 must wait until requests from all other queues have been printed.

    The division of print requests into queues of varying priorities can work well in many cases, but this approach has the drawback that low priority print requests may never be printed if a steady stream of higher priority requests enter the system. In operating-systems jargon, this situation is called starvation; some work is never done because the system spends all of its time on other processing.

    To avoid the possibility of starvation, a typical approach is to periodically move a print request from a low-priority queue to the next higher priority queue, as this would cause any print request to eventually move up to the head of the highest priority queue. To specify this promotion from one queue to the next more precisely, suppose that every time k requests from queue qi have been sent to the printer, the system removes a request from queue qi+1 and enqueues the request on queue qi.

    The Printing Protocol

    The following diagram provides an overview of the process of user submission of print requests, their placement on an appropriate queue, and their subsequent transmission to the printer for printing:

    a queue hierarch

    The formal protocol follows:

    Determining Initial Print-request Priority

    The print-queue protocol above requires the operating system to determine which queue should be used for each new print request submitted by the user. Three assignment approaches follow:

    1. All print requests are put on queue q0; that is, only one queue is used, and requests are printed in strict FIFO order.
    2. n queues are used, and print requests are assigned initially to queues based on their size.
      • Files of size 1-10 pages go initially to queue q0,
      • Files of size 11-20 pages go initially to queue q1,
      • Files of size 21-30 pages go initially to queue q2,
      • ...
      • Files of size i pages go initially to queue qi/10 (for i < 10 (n-1)),
      • ...
      • All files of 10(n-1) or more pages go to queue qn-1,
    3. n queues are used, and a print request for a file of size i is initially assigned to queue qi%n.

    Problem to be Solved

    Supplemental Problem 3 is to investigate the extent to which multiple queues and different assignment algorithms have an impact on the average waiting time for users' print requests.

    For the purposes of this problem, suppose that printing one page requires one unit of time. The simulation described below will cover 1000 units of time, and the simulation will need a "clock" variable that keeps time units 0, 1, 2, ..., 999.

    1. Identify a Queue class for use with this problem. (If possible, use a queue class from the Java Library, although you may need to expand it to know how many times a dequeue operation has been called since the queue was last empty.)
    2. Define a PrintRequest class that contains relevant information regarding a user request for printing. Likely, this PrintRequest class will need fields to record the number of pages to be printed and the clock time when the user submitted a print request.
    3. Define a Printer class with [at least] these methods (beyond a constructor)
      • a boolean printerIdle() method that returns true if the printer currently is not processing a print request, and false if the printer is busy processing a Print Request (i.e., the printer is printing a requested file).
      • a boolean printFile (PrintRequest pr) method:
        • if the printer is idle, the printer will start processing the given print request, and the method returns true
        • if the printer is already processing another Print Request, the new Print Request pr is ignored, and the method returns false
      • a PrintRequest processForOneUnit() method that prints one page of the current print request
        • if the printer is idle, or if the current Print Request is NOT completed within 1 unit of time, then processForOneUnit returns null. (Internally, the printer object should record that one additional page of the current Print Request has been printed.)
        • if the current Print Request is completed in the current time unit, the method returns the current PrintRequest object that just finishes printing.
    4. Write a Simulation class for the following simulation:
      • The program will read four parameters from the terminal:
        • The probability that some user will make a print request in a single time interval
        • The number n of queues to be used
        • The number k of dequeue operations from one queue before an item from a lower-priority queue is promoted
        • The algorithm ("A", "B", or "C" from above) for determining how the operating system will decide which queue will be used for a user's print request.
      • Processing proceeds one time unit at a time, based upon a "clock" variable.
        Processing in one time unit involves the following:
        • If the printer is in use, then 1 page of the current job is printed (so the print job is 1 page closer to completion).
        • A user may or may not make a print request. For this simulation, the likelihood that a print request is generated in one time of time should be based on a random number generator and a user-entered probability. If a print request is generated, processing in the simulation should depend upon these parameters.
          • The number of pages for the print request should be determined randomly between 1 and 100 pages.
          • A new Print Request object is created, containing the number of pages for the job and the starting "clock" time that this request entered the queue.
          • The user's request is submitted to the operating system in the form of an object with the clock time and print size.
          • The operating system places the new Print Request object on the appropriate queue.
        • If the printer is idle, and if at least one print request is pending, then
          • a print request is selected from the multiple queues, as described above.
          • the wait time (number of time intervals of waiting) for this Print Request is used to update both a maximum wait time and a total average wait.
          • the print request is sent to the printer object.
      • After the "clock" reaches 1000 time units, no new Print Requests should be generated, but the simulation should continue until all existing Print Requests have been processed.
    5. At the end of the simulation, the program prints:
      • the maximum waiting time for any Print Request
      • the average waiting time for all processed Print Requests

    To investigate the impact of different queue-selection strategies, testing should include each of the queue-selection approaches and several loads (numbers of Print Requests entering over the simulation).

    Draft problem-specific grading form


    This document is available on the World Wide Web as

    http://www.cs.grinnell.edu/~walker/courses/207.sp13/suppl-prob.shtml
    

    created 22 May 2008
    last revised 23 April 2013
    Valid HTML 4.01! Valid CSS!
    For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.