CPSC 327 | Data Structures and Algorithms | Spring 2024 |
Implement the time-o problem from homework 22 as discussed below.
Write a program which, given a list of controls with their point values and available time windows, the overall time limit and overtime penalty (points per minute), and the time it takes to travel between each pair of controls (including the start and finish), determines which controls to visit and in what order so as to maximize your score. Review homework 22 for more specifics on the problem.
The program should be run as follows:
java TimeO mapfile coursefile pace
The main program class should be named TimeO and the names of the map and course files and the competitor's pace should be specified on the commandline — don't prompt the user for the filenames!
The program should output a line with the total time, the total score (minus any penalties), the raw score (excluding penalties), and the total penalty assessed followed by a list of the controls visited (in order), the time of the visit, and the points scored for that control, with one control per line. For each control, list both the control ID and the control code. The output should go to the console (not written to a file). If other output is produced (such as for debugging), either remove it before handin or make sure each line starts with DEBUG (exactly like that) so it can be easily filtered out.
Your implementation should be an efficient implementation of your algorithm and your choices should reflect an understanding of efficiency and not just convenience.
For a passing grade, have a correct implementation of a recursive backtracking algorithm and:
Consider representation and make appropriate choices for both the ADTs used and for the implementation of those ADTs. Note that it is fine to use things from the Java Collections classes if that's appropriate; you might need to implement something of your own if not.
Avoid unnecessary copying. For example, prefer adding the next choice to the partial solution, making the recursive call, and then removing the next choice to restore the partial solution to copying the current partial solution before adding the next choice to the copy and passing that to the recursive call.
Prune obviously non-optimal partial solutions. Once the latest-ending time window has closed, there's no advantage in visiting additional controls (no more points will be gained, and they can only be lost if the route goes overtime) — prune all next choices other than going to the finish.
For an A, take some additional steps to improve efficiency, such as additional pruning, branch-and-bound, and/or dynamic programming. (If you implement dynamic programming, create a second copy of the program TimeODynProg to distinguish it from the required part of the assignment.) What you implement should demonstrate a basic understanding of the techniques. For extra credit, make more extensive improvements and/or implement dynamic programming, and do some comparisons of the effectiveness of various strategies.
Include a short writeup containing a discussion of your program's efficiency and any extra credit you implemented. Explain why your pruning, bound functions, and initial solution estimates are safe.
Data files are provided in /classes/cs327/timeo. Map files have the extension .map and course files have the extension .course. An image (.png) of the original map has been provided if you are interested; you do not need to make use of it.
In the real world, space is continuous and there are an infinite number of slight variations in routes an orienteer could take, even between the same pair of controls. For this problem, a "best" route between each pair of controls has been identified and it is assumed that orienteers will take those routes.
The time-o map file contains information about the distances between pairs of controls and between controls and the start/finish. It has the following format:
controls num code1 code2 code3 ... src dst dist revdist ...
The first line contains the word controls followed by the number of controls and then a list of control codes. (The start/finish is not included in this list.)
The remaining lines give the adjusted distances between each pair of controls and between each control and the start/finish — dist is from src to dst, and revdist is from dst to src. (start denotes the start/finish, otherwise the control is identified by its code.) Each pair is only listed once e.g. if (136,142) is listed, (142,136) will not be listed. "Adjusted distance" means that the actual distance has been adjusted to account for speed differences due to the terrain and elevation gain/loss. (In general, dist and revdist will not be the same.) Distances are in meters, so should be multiplied by a minutes-per-meter pace to get times; the pace is specified as the third parameter on the commandline when the program is run. (Your program should work with any pace, but if you are going for realism, reasonable values to try range from about 3 min/km for a fast run to 20 min/km for a slow walk. Divide by 1000 to get min/m!)
A partial example:
controls 29 136 128 123 124 122 126 121 138 137 135 134 125 140 133 131 139 117 139 116 118 127 143 141 142 120 119 132 130 144 start 136 481.0 481.0 start 128 394.0 394.0 start 123 332.0 332.0 start 124 154.0 154.0 start 122 285.0 285.0 start 126 194.0 194.0 start 121 276.0 276.0 start 138 190.0 190.0 ... 136 143 988.0 988.0 136 141 921.0 921.0 136 142 876.0 876.0 136 120 788.0 788.0 136 119 864.0 864.0 136 132 947.0 947.0 136 130 718.0 718.0 136 144 583.0 583.0 128 123 120.0 120.0 128 124 240.0 240.0 128 122 174.0 174.0 128 126 304.0 304.0 128 121 427.0 427.0 128 138 403.0 403.0 128 137 430.0 430.0 128 135 362.0 362.0 ...
The time-o course file contains information about controls. It has the following format:
timelimit limit penalty controls numcontrols code points open close ...
The first line contains the word timelimit followed by the time limit for completing the course (in minutes) and the penalty (in points) per minute late. The second line contains the word controls followed by the number of controls. The remaining lines contain the control code along with the point value, open time, and close time of each control. The open and close times define the window during which points can be earned for punching the control; they are given in minutes.
The start/finish is not included in the number of controls or the list of control information.
A partial example:
timelimit 30 2 controls 29 136 1 15 20 128 1 0 15 122 1 15 25 126 1 25 30 121 1 0 5 138 1 5 15 137 1 15 25 124 1 15 30 134 1 25 30 ...
Note that while the control code is a number in the example, that shouldn't be assumed — any string should be allowed.
Is the answer your program produces correct? That is always the question, and it is more challenging to address when you don't know the answer in advance.
With recursive backtracking, an important tactic is to reason carefully — make sure you cover all of the legal next choices, and make sure that any pruning or branch-and-bound strategy is safe. Print output to help you trace what the program is doing. (Either prefix debugging output lines with DEBUG or remove it before handin.)
A second tactic is to solve the problem yourself. This is difficult for large inputs, so an option is to create your own small example map and course files and run your program on that.
You are encouraged to use Eclipse, though it is not required. It is recommended that you use Java 17 though probably everything will be fine with an older version. This software is available on the lab computers in Rosenberg 009 and Lansing 310, or you can set up your own computer. Note that you do not need JavaFX for this assignment so you can skip that part for now.
Commandline parameters in Eclipse: Your program should take its input from commandline arguments rather than reading input from the user. Within the program, access commandline arguments using the args array passed to main — don't prompt the user for anything. To specify the commandline arguments for when the program is run in Eclipse:
java TimeO westpoint14-timeo.map westpoint14-timeo.course 10enter westpoint14-timeo.map westpoint14-timeo.course 10 for the program arguments. Note that if you make a subdirectory within your project for the data files, you'll need to include that. For example, if the map and course files are in a folder data within the project, you will need to specify the pathnames as data/westpoint14-timeo.map data/westpoint14-timeo.course — they are relative to the top level of the project.
Hand in your code by copying your Java files into a folder called timeo within your handin directory (/classes/cs327/handin/username).
Hand in a hardcopy of your writeup in class.