CMPS 144L Spring 2022
Lab #4: 3-Color Partitioning

In lecture, algorithmic solutions to the 2-Color Partitioning Problem were presented. In this lab, you are given the task of solving, in two different ways, the slightly more difficult 3-color version of the problem.

In each of your two solutions —embodied in the methods partition() and partition2()— you will use Java's assert statement for the purpose of verifying that the method's intended loop invariant is true immediately before and immediately after each iteration of its loop.

Resources

The following Java classes are provided, which you should load into jGrasp.

The functionality that an instance of the RWB_Partitioner class is intended to provide is basically this:

Before embarking upon the first activity, you should carefully examine the source code of the RWB_Partitioner class so that you come to an understanding of, generally, how it is organized and, specifically, the purpose of each instance variable and method.


Activity #1: Complete the partition() method

The partition() method has some missing pieces that you are to provide. Every occurrence of ?? (a pair of adjacent question marks) indicates that some code is missing. The method's purpose is to partition the array provided to it via its parameter so that, upon completion, the array elements (and the instance variables rw and wb) are consistent with this picture:

 0                 rw                  wb                 N
+-----------------+-------------------+------------------+
|     all RED     |     all WHITE     |     all BLUE     |
+-----------------+-------------------+------------------+

As the comments in the partition() method indicate, the code you supply must be consistent with the loop invariant depicted by this figure:

 0             rw            wq             wb             N
+-------------+-------------+--------------+--------------+
|   all RED   |  all WHITE  |      ?       |   all BLUE   |
+-------------+-------------+--------------+--------------+

Remember that rw and wb are instance variables, so they are not declared as local variables in the partition() method. On the other hand, wq is declared inside partition(), as its value is meaningful only during execution of that method. (Its name is intended to suggest that it marks the boundary between the WHITE segment and the ?-segment. (Specifically, it stores the starting location of the ?-segment.)

You will notice that there are two assert statements in the partition() method; their purpose is to verify that the loop invariant is true immediately before and immediately after each iteration of the loop. They do so by calling the loopInvariant() method, which, as its name suggests, evaluates the loop invariant. If the condition specified in an assert statement evaluates to false, an exception is thrown.

Before you run the "tester" program to test your work, make sure that you enable assertions (or else they will be ignored during execution).


Enabling Assertions:

To enable assertions in jGrasp:

Note: In the less likely event that you are running a Java program from the command line (using the java command), to enable assertions you need to include the -ea (or the more verbose -enableassertions) option. For example, you would enter

java -ea RWB_PartTester

End of note.

To verify that assertion testing is turned on, try running the AssertTest program. It should abort due to an AssertionError. If it does not, it means that assertion testing has not been turned on.


Activity #2: Complete the partition2() and loopInvariant2() Methods

Having completed the partition() method, now you are to devise a second method having the same purpose. Call it partition2(). (A stubbed version of the method has been provided to you.)

It should look much like the first version of the method, but it should be based upon the loop invariant depicted here:

 0             rw            wb             bq              N
+-------------+-------------+--------------+---------------+
|   all RED   |  all WHITE  |   all BLUE   |     ?         |
+-------------+-------------+--------------+---------------+

Remember that rw and wb are instance variables; thus, variables with those names should not be declared in partition2(). But bq (you can call it whatever you want) is a local variable indicating the boundary between the BLUE segment and the ?-segment.

You should find that the loop body necessary to maintain this loop invariant is a little bit more complicated than that needed in partition(). Indeed, you will probably find that, during certain loop iterations, two swaps of array elements are called for rather than only one.

Of course, to verify that your loop is consistent with the loop invariant described here, you should introduce and make use of a new loopInvariant2() method to check that the loop invariant holds before and after each loop iteration. (A stubbed version of the method has been provided.)


Submitting Your Work

Submit your RWB_Partitioner.java file to the appropriate folder using the Student File Submission System (to which there is a link on the CMPS 144L course web page). Make sure that you include comments indicating the names of all the members of your team. If your class does not meet all the specifications described here, include a comment that indicates its flaws.