I’m trying to create a calendar and scheduling application. We have a dataset that consists of short delivery appointments. Start time, duration, due date/time, etc. Our intention is to create an application that will generate a task list given start and end times for a block of work.
Jobs are prioritized in the following order:
- Due today at a specific time
- Due today at no specific time
- Due at a future date, sorted in ascending order
- No due date
- Future start date (excluded from reporting)
When the application runs, a start and end time for the work shift is entered. That block of time is automatically populated with jobs, in priority order.
CONSIDER:
Job01; Duration 10; Start 01/01; Due 01/02 1500;
Job02; Duration 60; Start 01/01; Due 01/02;
Job03; Duration 45; Start 01/08; Due 01/08 1500;
Job04; Duration 30; Start 01/09; Due 01/09 1500;
Job05; Duration 30; Start 12/31; ;
Job06; Duration 60; Start 12/28; ;
Job07; Duration 60; Start 01/04; ;
Job08; Duration 60; Start 01/04; ;
Job09; Duration 30; Start 01/01; Due 01/03 1200;
Job10; Duration 10; Start 01/01; Due 01/05 1700;
On 01/02, these ten jobs would be prioritized in this order: 01-02-09-10-05-06. Jobs 03-04-07-08 would be excluded because of future start dates.
Consider: on 01/02, I come into the office for a four hour shift, 1200-1600, and enter this data into the scheduler.
From there, I need the following magic to happen:
- Starting at my start time, add the top priority job.
- If the job is a specifically scheduled job, hold that time so no other job overwrites it.
- Once all jobs with specific times are in the calendar, keep filling in appointments beginning with the first emply slot until the calendar is filled, then stop.
Following that logic, here’s how the data fills out the schedule.
Job01 - 1500-1510
Job02 - cannot fit in the 1510-1500 slot, so it populates 1200-1300
Job05 - 1300-1330
Job06 - 1330-1430
Job09 - 1430-1500
Job10 - 1510-1520
So far, I have the prioritization logic working just fine. I can properly capture the first record to the schedule. But then, I’m lost on the alendaring piece, especially how to HOLD a certain time slot so nothing overwrites it, and not to exceed begin and end times. I’m struggling with an effective way to structure the method(s) that populate the calendar. Do I create an array of 15-miunte buckets and fill those with appointments as I iterate through my list of tasks? Do I somehow pass a newStartTime and newEndTime back to the top each time I schedule an event and pass another one through the scheduler? Are events held in memory? or written to a database as they populate particular slot? Is there a pre-defined class in Java that already does this and I missed it? Gosh…that would be embarrasing…
I’m too close to this right now, and am having trouble visualizing a good strategy. Any suggestions, observations and generalized pseudocode would be helpful.
Observation / Suggestion 1:
It’s not clear to me why you would ever want one job to over-write another. If you have the priority code done and you are adding the highest priority jobs first, why do you need to overwrite time slots? I would create a structure that allows a job to claim a time slot and then once claimed other jobs cannot claim that same spot.
Write a job schedule class that handles the jobs for a single day. It could just store a list of jobs in todays schedule. Available time slots and occupied time slots can then just be computed on the fly. If you are worried about data persisting after a power outage, then you can regularly write some serialization of your objects to disk. I don’t really see the value of storing this data in a database unless you want this app to be multi-threaded and then you can delegate the thread safe issues to the DB.
I recommend adding a field to Job: assignedStartTime.
Create a TimeInterval class that just stores a start time and an endtime.
Then within Schedule we can write the following:
Observation 2:
When you implement assignJob you should be able to just look for the first available time slot that meets the requirements. Proceeding this way will get you a schedule, but maybe not the most optimal schedule. If there will be situations where not all jobs can be scheduled, you need to carefully define what an optimal solution looks like. One that misses the fewest number of jobs? One that captures the most number of jobs due today?
Suggestion:
I would have Interval implement Comparable. Sort intervals first by length, then by start time. Store the Intervals in a TreeSet so they will always be ordered. This will make it easier and more efficient to find the best fitting interval when trying to schedule a new job.