{"id":20409664,"url":"https://github.com/sleekpanther/weighted-interval-scheduling","last_synced_at":"2026-05-29T06:31:31.332Z","repository":{"id":115108666,"uuid":"92223655","full_name":"SleekPanther/weighted-interval-scheduling","owner":"SleekPanther","description":"Weighted Interval Scheduling, the classic Dynamic Programming problem implemented in Java","archived":false,"fork":false,"pushed_at":"2017-05-28T19:20:16.000Z","size":1033,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-05T02:42:59.477Z","etag":null,"topics":["binary-search-tree","compatible","dynamic","dynamic-programming","find-solution","finish-time","interval","interval-scheduling","iterative","noah","noah-patullo","optimal","optimal-substructure","pattullo","patullo","patulo","recursive","scheduling","weighted","weighted-interval-scheduling"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SleekPanther.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-23T21:51:44.000Z","updated_at":"2023-04-10T23:37:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"a1842cc8-8ca9-46d9-8e9d-c743c8345464","html_url":"https://github.com/SleekPanther/weighted-interval-scheduling","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SleekPanther/weighted-interval-scheduling","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fweighted-interval-scheduling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fweighted-interval-scheduling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fweighted-interval-scheduling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fweighted-interval-scheduling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SleekPanther","download_url":"https://codeload.github.com/SleekPanther/weighted-interval-scheduling/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2Fweighted-interval-scheduling/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33640627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary-search-tree","compatible","dynamic","dynamic-programming","find-solution","finish-time","interval","interval-scheduling","iterative","noah","noah-patullo","optimal","optimal-substructure","pattullo","patullo","patulo","recursive","scheduling","weighted","weighted-interval-scheduling"],"created_at":"2024-11-15T05:42:52.911Z","updated_at":"2026-05-29T06:31:31.313Z","avatar_url":"https://github.com/SleekPanther.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Weighted Interval Scheduling\nThe classic introduction to Dynamic Programming\n\n## Problem Statement\nJobs have an ID, start time, a finish time \u0026 a value (or weight)  \n**Find the maximum weight subset of mutually compatible jobs.**  \n2 jobs are **Compatible** if they don't overlap (1 job cannot start before the other job finishes)  \n\n## Optimal Substructure\n![](images/optimal-substructure.png)\n\n## Input Jobs\n![](images/input-jobs.png)  \nFor example: job `6` is compatible with job `3` \u0026 `2`. Jobs `1`, `4` \u0026 `5` are incompatible because they finish after job `6` starts and jobs `7` \u0026 `8` are incompatible because they start before job `6` ends (the algorithm presorts jobs by finish time so `7` \u0026 `8` are never considered when looking for compatible jobs)  \nJob `2` has **no compatible jobs** since none finish before job `2` starts. **The algorithm returns `0` when no compatible job index is found**  \n**Finding the next job compatible with job `i` involves looking earlier in the jobs array for a job that finishes before or at the same time as job `i`**\n\n## Pseudocode\n![](images/optimal-pseudocode.png)  \n![](images/find-solution-pseudocode.png)\n\n\n## Runtime\n**O(n log(n) )** from sorting jobs by finish time and binary search in `latestCompatible()`  \nBinary Search is O(log n) and there are **n** jobs, so **O(n log(n) )**\n\n## Solution (Jobs Selected in Optimal Subset)\n![](images/optimal-solution.png)  \n#### Optimal Subset is **Job `2` \u0026 Job `6`**    \u003cbr\u003e **Maximum Value = 5 + 7 = 12**\n\n\n## Usage\n- A 2D array of `inputJobs[][]` created in `main()`\n- Each `inputJobs[i]` is an array of 4 numbers  \n**[ID, startTime, finishTime, value]**\n- `inputJobs[0]` must be a placeholder array of four 0's: `{0,0,0,0}`\n\n## Code Details\n- 2D `jobs[]` array is sorted by finish time so the ID's of jobs are no longer the array indexes  \n`findSolutionIterative()` uses `jobs[jobIndex][0]` to get the original **ID** of the job\n- This allows the rest of the code to just use array indexes in `jobs[][]` when finding the optimal value\n- `findSolutionRecursive()` works, but is not used. The recursion has been converted to a loop-based method `findSolutionIterative()`  \n(Both versions are left in to show the similarities)\n- Comparisons in `latestCompatible()` are made with `\u003c=` since a job `x` can be **compatible** with job `i` if `x` finishes at exactly the same time as `i` starts\n  - `latestCompatible()` uses **binary search** to find the index of the job with the latest finish time that is compatible with job `i`\n  - `latestCompatible()` Returns `0` if no compatible job was found. This allows the dynamic programming loop to add the value of `jobs[0][0]` (which is `0`) to the `memo[]` array, so this placeholder job does not affect the rest of the schedule, only when no compatible jobs are found\n  - `jobs[0][0]` is also used in `findSolutionIterative()` for the **base case**\n- `getJobInfo()` converts an `int` job index in `jobs[][]` (sorted by finish time) to a `String` with the job ID, Start Time, Finish Time \u0026 Value human-readable\n\n## References\n- [Design and Analysis of Algorithms I - Larry Ruzzo, University of Washington](https://courses.cs.washington.edu/courses/cse521/13wi/slides/06dp-sched.pdf)\n- [GeeksForGeeks Weighted Job Scheduling](http://www.geeksforgeeks.org/weighted-job-scheduling/)\n- [GeeksForGeeks Weighted Job Scheduling in O(n Log n)](http://www.geeksforgeeks.org/weighted-job-scheduling-log-n-time/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleekpanther%2Fweighted-interval-scheduling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleekpanther%2Fweighted-interval-scheduling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleekpanther%2Fweighted-interval-scheduling/lists"}