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.
The functionality that an instance of the RWB_Partitioner class is intended to provide is basically this:
To support these observer methods, instance variables are declared.
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.
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).
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
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.
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.)