CIS 263 |
Closest Pair |
Fall 2019 |
Use this GitHub Classroom link to get started: classroom.github.com/a/5jehf_QK
.
Don't edit the test file yet. The tests are still a work in progress. If you want to add tests now, put them in a separate .cpp file.
The Challenge
Implement a divide and conquer algorithm for determining which points in a set are the closest. The algorithm will be similar to the one presented in class, with three additions:
- There can be ties.
- You must return the pairs of closets points (not just determine the minimum distance).
- Your algorithm will take a
tolerance
parameter that determines the threshold for determining a "tie".
Details
Implement the following two methods:
static PointPairSet closestPairsBruteForce(const PointVector &pairs, double tolerance = 0.000001)
static PointPairSet closestPairs(const PointVector &pairs, double tolerance = 0.000001)
closestPairsBruteForce
will just compare allO(n^2)
pairs of points and return the sets that are the closest. Implementing this function will help you work out the details of managing ties -- especially with respect to thetolerance
.closestPairs
must be aO(n log n)
divide and conquer algorithm. (Note: TheO(n log n)
bound applies only to inputs with no ties.)- The following data types are defined in
ClosestPairs.h
. You must use them in the signature of the above methods, otherwise my tests won't run:Point
: Represents an(x, y)
point. It's just a renaming ofstd::pair<double, double>
.PointVector
: A list ofPoints
. It's just a renaming ofstd::vector<Point>
.PointPair
: A pair ofPoint
s. Used to represent two points that are part of the answer. It's just a renaming ofstd::pair<Point, Point>
.PointPairSet
: A set ofPointPair
s. Since there can be a tie for closest points, theclosestPairs
methods return aset
ofPointPair
s.
- The return values for the
closetPairs
methods must order the points within eachPointPair
in lexicographic order. (In other words, sort byx
coordinate, then byy
coordinate. If the closest points are(5, 15)
and(10, 6)
, then they should appear in thePointPair
as{{5, 15}, {10, 6}}
.) The tests will fail ifPointPairs
are in the wrong order. - The
closetPairs
methods should return all pairs of points whose distance is withintolerance
of the minimum. Important: Think carefully about this: Only include pairs whose distance is withingtolerance
of the minimum. Don't apply it transitively to all points in the input. - Notice that the
closestPairs
methods arestatic
. That means (1) they can't access instance variables, and (2) you don't need to instantiate aClosestPairs
object to use them. Any data that you want to share with helper methods should be passed as a parameter.
Grading
There are several tiers to this project. Your grade will be based on how many you complete. (Unlike previous homework, you can still receive a decent grade if certain parts of this assignment don't work.)
Points | Details | |
---|---|---|
Works with no ties and no rounding | 25 | closestPairs (1) implements a divide and conquer algorithm, (2) passes all of the tests tagged
noTie and noRound . This means that (1) All answers contain just one
PointPair , and (2) you can ignore tolerance .
|
Works with ties. | 15 | In addition to the criteria above, all of the tests tagged tie pass. (5 points if
tie tests pass for brute force only.)
|
Works with tolerance . |
10 | In addition to the criteria above, all of the tests tagged round pass. (4 points if
round tests pass for brute force only.)
|
Has a running time of O(n log n) |
10 | You must prepare and attach a graph showing the running time for input sizes ranging from 500 to 50,000
compared to a graph of a function of the form cn log n . (You can only receive these points
if closestPairs works correctly.) You need only meet the n log n bound for inputs that
contain no ties. (4 points for preparing a graph, even if it isn't n log n .) Include the graph
in your git repo. Important: You must also include the code that generated the numbers used in the
graph. (In other words, I need to be albe to reproduce your results.)
|
Rules
- You may work in teams of two. But your teammate must have completed the same set of homework as you. (For example, if you have completed Homework 6, you may only pair with someone who has also completed Homework 6.)
- Teammates must work together at all times. You may not "divide and conquer". You may not have one person write a bunch of code and then just explain it when it works.
Suggestions
- Look at the rubric above and focus on one set of points at a time. For example, just get the basic algorithm working before worrying about how to handle ties, or even considering the tolerance.
- Do
closestPairsBruteForce
first, then work on the divide and conquer version. This is especially important when working with ties and tolerance. It will be much easier to get the ties working in the divide and conquer algorithm after you first work out the bugs in the brute force version. - Remember,
Points
in aPointPair
must be returned in lexicographic order to pass the tests. However, until you return your final answer, it doesn't really matter what order the points are in. - You will need your recursive divide and conquer calls to return both the closest pairs and the distances
between those pairs. I did this by having my "helper" functions use
set<pair<double, PointPair>>
as a return value. (To avoid a lot of typing, I added this to theClosestPairs
:using PointPairDistSet = set<pair<double, PointPair>>;
. - The divide and conquer code is simipler if you can assume that each recursive call
returns at least one pair of points (i.e., that the return set is not empty). One way to do this is to use a
brute force search when your recursive call is down to the last 5 or so points. As mentioned above, you need
not only the closest points, but the distances as well. I wrote a helper function for brute force that returns
set<pair<double, PointPair>>
. This helper function is used by both the main brute force function and my divide and conquer helper.
Submission and grading
- Please make sure your name appears in all source code files.
- Make sure all relevant code (including unit tests) is checked in to GitHub by the due date.
- Unless you indicate otherwise, I will assume that the code to be graded is on the
master
branch.
Updated Wednesday, 27 November 2019, 1:10 PM