Skip to content

Greedy Algorithm Implementations and Explanations #4493 #4504

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

Merged
merged 25 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
57a4701
Greedy Algorithm Implementations and Explanations #4493
Vineetttt Oct 1, 2023
3405139
Greedy Algorithm Implementations and Explanations #4493
Vineetttt Oct 1, 2023
0380598
Merge branch 'master' into master
Vineetttt Oct 1, 2023
6d08ab2
modify dijkstras and adding JUnit Tests
Vineetttt Oct 1, 2023
5c342ce
Merge branch 'master' of https://github.com/Vineetttt/TheAlgorithms-JAVA
Vineetttt Oct 1, 2023
5205a48
modify activity selection and add JUnit Tests
Vineetttt Oct 1, 2023
e7c2fca
modify coinChange and add JUnit Tests
Vineetttt Oct 1, 2023
4b99c75
modify fractionalKnapsack and add JUnit Tests
Vineetttt Oct 1, 2023
249be4b
modify jobSequencing and add JUnit Tests
Vineetttt Oct 1, 2023
4d53fc6
Merge branch 'master' into master
Vineetttt Oct 1, 2023
f41a78a
minor changes
Vineetttt Oct 1, 2023
4963bf8
Merge branch 'master' of https://github.com/Vineetttt/TheAlgorithms-JAVA
Vineetttt Oct 1, 2023
24d231c
minor change in JobSequecingTest
Vineetttt Oct 1, 2023
d57722a
minor change in JobSequencingTest
Vineetttt Oct 1, 2023
ebc6f47
clang format linter changes
Vineetttt Oct 2, 2023
ce0369b
clang format linter changes
Vineetttt Oct 2, 2023
9844a39
removing dijkstra's algorithm
Vineetttt Oct 2, 2023
7b2160b
adding partial coins test case
Vineetttt Oct 2, 2023
38f20e9
removing print functions
Vineetttt Oct 2, 2023
7ff6f01
linter job fixes
Vineetttt Oct 3, 2023
8d89bf1
linter job fixes
Vineetttt Oct 3, 2023
3cd77c6
minor changes for the clang linter job
Vineetttt Oct 3, 2023
935aea1
Adding more JUnit Tests to the coin change problem
Vineetttt Oct 3, 2023
d68d840
Merge branch 'master' into master
Vineetttt Oct 3, 2023
ae8d56f
Merge branch 'master' into master
siriak Oct 3, 2023
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.thealgorithms.greedyalgorithms;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

// Problem Link: https://en.wikipedia.org/wiki/Activity_selection_problem

public class ActivitySelection {
// Function to perform activity selection
public static ArrayList<Integer> activitySelection(int startTimes[], int endTimes[]) {
int n = startTimes.length;
int activities[][] = new int[n][3];

// Create a 2D array to store activities and their start/end times.
// Each row: [activity index, start time, end time]

for (int i = 0; i < n; i++) {
activities[i][0] = i; // Assign activity index
activities[i][1] = startTimes[i]; // Assign start time
activities[i][2] = endTimes[i]; // Assign end time
}

// Sort activities by their end times in ascending order.
Arrays.sort(activities, Comparator.comparingDouble(activity -> activity[2]));
int lastEndTime;
ArrayList<Integer> selectedActivities = new ArrayList<>();
selectedActivities.add(activities[0][0]);
lastEndTime = activities[0][2];

// Iterate through sorted activities to select compatible ones.
for (int i = 1; i < n; i++) {
if (activities[i][1] >= lastEndTime) {
selectedActivities.add(activities[i][0]);
lastEndTime = activities[i][2];
}
}
return selectedActivities;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.thealgorithms.greedyalgorithms;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

// Problem Link : https://en.wikipedia.org/wiki/Change-making_problem

public class CoinChange {
// Function to solve the coin change problem
public static ArrayList<Integer> coinChangeProblem(int amount) {
// Define an array of coin denominations in descending order
Integer coins[] = {1, 2, 5, 10, 20, 50, 100, 500, 2000};

// Sort the coin denominations in descending order
Arrays.sort(coins, Comparator.reverseOrder());

int count = 0; // Variable to keep track of the total number of coins used
ArrayList<Integer> ans = new ArrayList<>(); // List to store selected coins

// Iterate through the coin denominations
for (int i = 0; i < coins.length; i++) {
// Check if the current coin denomination can be used to reduce the remaining amount
if (coins[i] <= amount) {
// Repeatedly subtract the coin denomination from the remaining amount
while (coins[i] <= amount) {
count++; // Increment the count of coins used
ans.add(coins[i]); // Add the coin to the list of selected coins
amount -= coins[i]; // Update the remaining amount
}
}
}
return ans;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.thealgorithms.greedyalgorithms;

import java.util.Arrays;
import java.util.Comparator;

// Problem Link: https://en.wikipedia.org/wiki/Continuous_knapsack_problem

public class FractionalKnapsack {
// Function to perform fractional knapsack
public static int fractionalKnapsack(int weight[], int value[], int capacity) {
// Create a 2D array to store item indices and their value-to-weight ratios.
double ratio[][] = new double[weight.length][2];

// Populate the ratio array with item indices and their value-to-weight ratios.
for (int i = 0; i < weight.length; i++) {
ratio[i][0] = i; // Assign item index.
ratio[i][1] = value[i] / (double) weight[i]; // Calculate and assign value-to-weight ratio.
}

// Sort items by their value-to-weight ratios in descending order.
Arrays.sort(ratio, Comparator.comparingDouble(o -> o[1]));

int finalValue = 0; // Variable to store the final knapsack value.
double current = capacity; // Variable to track the remaining capacity of the knapsack.

// Iterate through the sorted items to select items for the knapsack.
for (int i = ratio.length - 1; i >= 0; i--) {
int index = (int) ratio[i][0]; // Get the item index.
if (current >= weight[index]) {
// If the entire item can fit in the knapsack, add its value.
finalValue += value[index];
current -= weight[index];
} else {
// If only a fraction of the item can fit, add a proportionate value.
finalValue += ratio[i][1] * current;
break; // Stop adding items to the knapsack since it's full.
}
}
return finalValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.thealgorithms.greedyalgorithms;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

// Problem Link: https://en.wikipedia.org/wiki/Job-shop_scheduling

public class JobSequencing {

// Define a Job class that implements Comparable for sorting by profit in descending order
static class Job implements Comparable<Job> {
char id;
int deadline;
int profit;

// Compare jobs by profit in descending order
@Override
public int compareTo(Job otherJob) {
return otherJob.profit - this.profit;
}

public Job(char id, int deadline, int profit) {
this.id = id;
this.deadline = deadline;
this.profit = profit;
}
}

// Function to print the job sequence
public static String findJobSequence(ArrayList<Job> jobs, int size) {
Boolean[] slots = new Boolean[size];
Arrays.fill(slots, false);

int result[] = new int[size];

// Iterate through jobs to find the optimal job sequence
for (int i = 0; i < size; i++) {
for (int j = jobs.get(i).deadline - 1; j >= 0; j--) {
if (!slots[j]) {
result[j] = i;
slots[j] = true;
break;
}
}
}

// Create a StringBuilder to build the job sequence string
StringBuilder jobSequenceBuilder = new StringBuilder();
jobSequenceBuilder.append("Job Sequence: ");
for (int i = 0; i < jobs.size(); i++) {
if (slots[i]) {
jobSequenceBuilder.append(jobs.get(result[i]).id).append(" -> ");
}
}

// Remove the trailing " -> " from the job sequence
if (jobSequenceBuilder.length() >= 4) {
jobSequenceBuilder.setLength(jobSequenceBuilder.length() - 4);
}

// Return the job sequence as a string
return jobSequenceBuilder.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.thealgorithms.greedyalgorithms;

import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.Arrays;
import org.junit.jupiter.api.Test;

public class ActivitySelectionTest {
@Test
public void testActivitySelection() {
int start[] = {1, 3, 0, 5, 8, 5};
int end[] = {2, 4, 6, 7, 9, 9};

ArrayList<Integer> result = ActivitySelection.activitySelection(start, end);
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0, 1, 3, 4));

assertEquals(expected, result);
}

@Test
public void testSingleActivity() {
int start[] = {1};
int end[] = {2};

ArrayList<Integer> result = ActivitySelection.activitySelection(start, end);
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0));

assertEquals(expected, result);
}

@Test
public void testNoOverlap() {
int start[] = {1, 2, 3};
int end[] = {2, 3, 4};

ArrayList<Integer> result = ActivitySelection.activitySelection(start, end);
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0, 1, 2));

assertEquals(expected, result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.thealgorithms.greedyalgorithms;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;
import java.util.Arrays;
import org.junit.jupiter.api.Test;

public class CoinChangeTest {
@Test
public void testCoinChangeProblemWithValidAmount() {
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(500, 50, 20, 20, 1));
ArrayList<Integer> coins = CoinChange.coinChangeProblem(591);
assertEquals(expected, coins);
}

@Test
public void testCoinChangeProblemWithLargeAmount() {
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2000));
ArrayList<Integer> coins = CoinChange.coinChangeProblem(2000);
assertEquals(expected, coins);
}

@Test
public void testCoinChangeProblemWithPartialCoins2() {
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(500, 50, 20));
ArrayList<Integer> coins = CoinChange.coinChangeProblem(570);
assertEquals(expected, coins);
}

@Test
public void testCoinChangeProblemWithSmallAmount() {
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2, 1));
ArrayList<Integer> coins = CoinChange.coinChangeProblem(3);
assertEquals(expected, coins);
}

@Test
public void testCoinChangeProblemWithLargeAmountAndMultipleDenominations() {
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2000, 2000, 2000, 2000, 500, 500, 500, 100, 100, 100, 100, 50, 20, 20, 5, 2, 2));
ArrayList<Integer> coins = CoinChange.coinChangeProblem(9999);
assertEquals(expected, coins);
}

@Test
public void testCoinChangeProblemWithAllDenominations() {
ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2000, 500, 100, 100, 100, 50, 20, 10, 5, 2, 1));
ArrayList<Integer> coins = CoinChange.coinChangeProblem(2888);
assertEquals(expected, coins);
}

@Test
public void testCoinChangeProblemWithZeroAmount() {
ArrayList<Integer> expected = new ArrayList<>();
ArrayList<Integer> coins = CoinChange.coinChangeProblem(0);
assertEquals(expected, coins);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.thealgorithms.greedyalgorithms;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

public class FractionalKnapsackTest {

@Test
public void testFractionalKnapsackWithExampleCase() {
int weight[] = {10, 20, 30};
int value[] = {60, 100, 120};
int capacity = 50;
assertEquals(240, FractionalKnapsack.fractionalKnapsack(weight, value, capacity));
}

@Test
public void testFractionalKnapsackWithZeroCapacity() {
int weight[] = {10, 20, 30};
int value[] = {60, 100, 120};
int capacity = 0;
assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity));
}

@Test
public void testFractionalKnapsackWithEmptyItems() {
int weight[] = {};
int value[] = {};
int capacity = 50;
assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.thealgorithms.greedyalgorithms;

import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.Collections;
import org.junit.jupiter.api.Test;

public class JobSequencingTest {
@Test
public void testJobSequencingWithExampleCase() {
ArrayList<JobSequencing.Job> jobs = new ArrayList<>();
jobs.add(new JobSequencing.Job('a', 2, 100));
jobs.add(new JobSequencing.Job('b', 1, 19));
jobs.add(new JobSequencing.Job('c', 2, 27));
jobs.add(new JobSequencing.Job('d', 1, 25));
jobs.add(new JobSequencing.Job('e', 3, 15));
Collections.sort(jobs);
String jobSequence = JobSequencing.findJobSequence(jobs, jobs.size());

assertEquals("Job Sequence: c -> a -> e", jobSequence);
}
}