Skip to content

Weighted job scheduling using Dynamic Programming and Binary Search #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions C++/Algorithms/Graph-Algorithms/bellman.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import java.util.Arrays;

/**
* The bellman-ford algorithm to calculate the shortest paths in a Graph with negative weights
*/
public class BellmanFord {

/**
* Bellman-Ford algorithm to get the shortest distances to every node in {@code graph} from a start node.
* Returns an empty array if the graph contains negative-weight cycles<br>
* Based on: https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm<br>
* Visualization tool used: https://www-m9.ma.tum.de/graph-algorithms/spp-bellman-ford/index_en.html<br>
* Complexity: O(n³)
*
* @param graph the input graph
* @param source the source node
* @return an array containing the shortest distance to every node from {@code source}, plus an array
* containing the predecessor for each node.
*/
private static int[][] impl(final int[][] graph, int source) {
// Contains the shortest distance from source to each node
int[] distance = new int[graph.length];

// Contains the predecessor to each node
int[] predecessor = new int[graph.length];

for (int i = 0; i < graph.length; i++) {
distance[i] = Integer.MAX_VALUE;
predecessor[i] = -1;
}

distance[source] = 0;
for (int i = 1; i < graph.length; i++) {
for (int s = 0; s < graph.length; s++) {
for (int d = 0; d < graph[s].length; d++) {
int weight = graph[s][d];
if (distance[s] != Integer.MAX_VALUE && distance[s] + weight < distance[d]) {
distance[d] = distance[s] + weight;
predecessor[d] = s;
}
}
}
}

// Check for negative-weight circles
for (int u = 1; u < graph.length; u++) {
for (int v = 0; v < graph.length; v++) {
if (distance[u] + graph[u][v] < distance[v]) {
return new int[0][];
}
}
}

return new int[][]{distance, predecessor};
}

/**
* Use the bellman-ford algorithm to calculate the shortest distance from and to every node in {@code inGraph}.<br>
* Complexity: O(n⁴)
*
* @param inGraph the input graph matrix
* @return the 'new' graph matrix, only containing the shortest paths to and from every node or an empty array
* when {@code inGraph} contains negative-weight cycles
*/
public static int[][] bellmanFord(final int[][] inGraph) {
int[][] res = new int[inGraph.length][];
for (int i = 0; i < inGraph.length; i++) {
int[][] b_f_res = impl(inGraph, i);
if (b_f_res.length == 2) {
// Only fill in the distance, you may use b_f_res[1] to get the nodes visited to
// get to a specific node
res[i] = b_f_res[0];
} else {
return new int[0][];
}
}

return res;
}

public static void main(String[] args) {
// Print out the graph matrix with the shortest paths to each node of this graph
System.out.println(Arrays.deepToString(bellmanFord(new int[][]{
{0, 2, 2, 2, -1},
{9, 0, 2, 2, -1},
{9, 3, 0, 2, -1},
{9, 3, 2, 0, -1},
{9, 3, 2, 2, 0}
})));
}
}
91 changes: 91 additions & 0 deletions Java/Algorithms/Greedy-Algorithms/greedy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//C++ program for weighted job scheduling using Dynamic Programming and Binary Search
#include <iostream>
#include <algorithm>
using namespace std;

//A job has start time, finish time and profit.
struct Job
{
int start, finish, profit;
};

//A utility function that is used for sorting events according to finish time
bool myfunction(Job s1, Job s2)
{
return (s1.finish < s2.finish);
}

/*A Binary Search based function to find the latest job (before current job) that doesn't conflict with current job. "index" is index of the current job. This function returns -1 if all jobs before index conflict with it.
The array jobs[] is sorted in increasing order of finish time. */

int binarySearch(Job jobs[], int index)
{
// Initialize 'lo' and 'hi' for Binary Search
int lo = 0, hi = index - 1;

// Perform binary Search iteratively
while (lo <= hi)
{
int mid = (lo + hi) / 2;
if (jobs[mid].finish <= jobs[index].start)
{
if (jobs[mid + 1].finish <= jobs[index].start)
lo = mid + 1;
else
return mid;
}
else
hi = mid - 1;
}

return -1;
}

//The main function that returns the maximum possible profit from given array of jobs

int findMaxProfit(Job arr[], int n)
{
//Sort jobs according to finish time
sort(arr, arr+n, myfunction);

//Create an array to store solutions of subproblems. table[i] stores the profit for jobs till arr[i] (incl. arr[i])
int *table = new int[n];
table[0] = arr[0].profit;

//Fill entries in table[] using recursive property
for (int i=1; i<n; i++)
{
//Find profit including the current job
int inclProf = arr[i].profit;
int l = binarySearch(arr, i);
if (l != -1)
inclProf += table[l];

//Store maximum of including and excluding
table[i] = max(inclProf, table[i-1]);
}

//Store result and free dynamic memory allocated for table[]
int result = table[n-1];
delete[] table;

return result;
}

//Driver program
int main()
{
int n;
cin>>n;

Job arr[n];
for(int i=0; i<n; i++)
{
cin>>arr[i].start;
cin>>arr[i].finish;
cin>>arr[i].profit;
}

cout<< findMaxProfit(arr, n);
return 0;
}