From 104857642cc7b29c95523452177640d23483c156 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 09:27:12 +0530 Subject: [PATCH 1/7] feat: Add `AssignmentUsingBitmask` new algorithm with Junit tests --- .../AssignmentUsingBitmask.java | 88 +++++++++++++++++++ .../AssignmentUsingBitmaskTest.java | 54 ++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java new file mode 100644 index 000000000000..f94f9acb0aa9 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java @@ -0,0 +1,88 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.*; + +/** + * The AssignmentUsingBitmask class is used to calculate the total number of ways + * tasks can be distributed among people, given specific constraints on who can perform which tasks. + * The approach uses bitmasking and dynamic programming to efficiently solve the problem. + * + * @author Hardvan + */ +public class AssignmentUsingBitmask { + private final int totalTasks; + private final int[][] dp; + private final List> task; + private final int finalMask; + + /** + * Constructor for the AssignmentUsingBitmask class. + * + * @param taskPerformed a list of lists, where each inner list contains the tasks that a person can perform. + * @param total the total number of tasks. + */ + public AssignmentUsingBitmask(List> taskPerformed, int total) { + this.totalTasks = total; + this.dp = new int[1 << taskPerformed.size()][total + 1]; + for (int[] row : dp) { + Arrays.fill(row, -1); + } + + this.task = new ArrayList<>(totalTasks + 1); + for (int i = 0; i <= totalTasks; i++) { + this.task.add(new ArrayList<>()); + } + + // Final mask to check if all persons are included + this.finalMask = (1 << taskPerformed.size()) - 1; + + // Fill the task list + for (int i = 0; i < taskPerformed.size(); i++) { + for (int j : taskPerformed.get(i)) { + this.task.get(j).add(i); + } + } + } + + /** + * Counts the ways to assign tasks until the given task number with the specified mask. + * + * @param mask the bitmask representing the current state of assignments. + * @param taskNo the current task number being processed. + * @return the number of ways to assign tasks. + */ + private int countWaysUntil(int mask, int taskNo) { + if (mask == finalMask) { + return 1; + } + if (taskNo > totalTasks) { + return 0; + } + if (dp[mask][taskNo] != -1) { + return dp[mask][taskNo]; + } + + int totalWays = countWaysUntil(mask, taskNo + 1); + + // Assign tasks to all possible persons + for (int p : task.get(taskNo)) { + // If the person is already assigned a task + if ((mask & (1 << p)) != 0) { + continue; + } + totalWays += countWaysUntil(mask | (1 << p), taskNo + 1); + } + + dp[mask][taskNo] = totalWays; + return dp[mask][taskNo]; + } + + /** + * Counts the total number of ways to distribute tasks among persons. + * + * @return the total number of ways to distribute tasks. + */ + public int countNoOfWays() { + return countWaysUntil(0, 1); + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java new file mode 100644 index 000000000000..ada496622f75 --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java @@ -0,0 +1,54 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class AssignmentUsingBitmaskTest { + + @Test + public void testCountNoOfWays() { + int totalTasks = 5; + + List> taskPerformed = Arrays.asList(Arrays.asList(1, 3, 4), Arrays.asList(1, 2, 5), Arrays.asList(3, 4)); + + AssignmentUsingBitmask assignment = new AssignmentUsingBitmask(taskPerformed, totalTasks); + int ways = assignment.countNoOfWays(); + assertEquals(10, ways); + } + + @Test + public void testNoPossibleAssignments() { + int totalTasks = 3; + + List> taskPerformed = Arrays.asList(Arrays.asList(2), Arrays.asList(3)); + + AssignmentUsingBitmask assignment = new AssignmentUsingBitmask(taskPerformed, totalTasks); + int ways = assignment.countNoOfWays(); + assertEquals(1, ways); + } + + @Test + public void testSinglePersonMultipleTasks() { + int totalTasks = 3; + + List> taskPerformed = Arrays.asList(Arrays.asList(1, 2, 3)); + + AssignmentUsingBitmask assignment = new AssignmentUsingBitmask(taskPerformed, totalTasks); + int ways = assignment.countNoOfWays(); + assertEquals(3, ways); + } + + @Test + public void testMultiplePeopleSingleTask() { + int totalTasks = 1; + + List> taskPerformed = Arrays.asList(Arrays.asList(1), Arrays.asList(1)); + + AssignmentUsingBitmask assignment = new AssignmentUsingBitmask(taskPerformed, totalTasks); + int ways = assignment.countNoOfWays(); + assertEquals(0, ways); + } +} From 28b568a4792257afc697ef2389581ed01df7ca88 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Mon, 14 Oct 2024 03:57:26 +0000 Subject: [PATCH 2/7] Update directory --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index f1a531486de7..b175077eef2c 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -255,6 +255,7 @@ * [SkylineAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java) * [StrassenMatrixMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java) * dynamicprogramming + * [AssignmentUsingBitmask](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java) * [BoardPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java) * [BoundaryFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java) * [BruteForceKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java) @@ -836,6 +837,7 @@ * [SkylineAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/SkylineAlgorithmTest.java) * [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java) * dynamicprogramming + * [AssignmentUsingBitmaskTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java) * [BoardPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java) * [BoundaryFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java) * [BruteForceKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java) From ca4639ea5eae8c79e8d525fd62e52238a94365c1 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 09:28:58 +0530 Subject: [PATCH 3/7] Fix --- .../dynamicprogramming/AssignmentUsingBitmaskTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java index ada496622f75..0b22294cf837 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java @@ -6,7 +6,9 @@ import java.util.List; import org.junit.jupiter.api.Test; -public class AssignmentUsingBitmaskTest { +public final class AssignmentUsingBitmaskTest { + private AssignmentUsingBitmaskTest() { + } @Test public void testCountNoOfWays() { From 8d040fc81913454565dd9be0676c6e712dc69840 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 09:29:24 +0530 Subject: [PATCH 4/7] Fix --- .../dynamicprogramming/AssignmentUsingBitmask.java | 5 ++++- .../dynamicprogramming/AssignmentUsingBitmaskTest.java | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java index f94f9acb0aa9..07fd9c004abd 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java @@ -9,7 +9,10 @@ * * @author Hardvan */ -public class AssignmentUsingBitmask { +public final class AssignmentUsingBitmask { + private AssignmentUsingBitmask() { + } + private final int totalTasks; private final int[][] dp; private final List> task; diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java index 0b22294cf837..0258f3950510 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java @@ -7,8 +7,6 @@ import org.junit.jupiter.api.Test; public final class AssignmentUsingBitmaskTest { - private AssignmentUsingBitmaskTest() { - } @Test public void testCountNoOfWays() { From 375db65f743aafabcc369aca0997c665289b4d07 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 09:29:36 +0530 Subject: [PATCH 5/7] Fix --- .../dynamicprogramming/AssignmentUsingBitmask.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java index 07fd9c004abd..fa49b1ab5694 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java @@ -10,8 +10,6 @@ * @author Hardvan */ public final class AssignmentUsingBitmask { - private AssignmentUsingBitmask() { - } private final int totalTasks; private final int[][] dp; From 130020f1fc766abcd77b23fff2e8dc35de7c978a Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 09:33:21 +0530 Subject: [PATCH 6/7] Fix --- .../dynamicprogramming/AssignmentUsingBitmask.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java index fa49b1ab5694..5a894ca004b7 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java @@ -1,6 +1,8 @@ package com.thealgorithms.dynamicprogramming; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * The AssignmentUsingBitmask class is used to calculate the total number of ways From 9ff0d718179cc274217d105ebd6dc451578bb27e Mon Sep 17 00:00:00 2001 From: siriak Date: Wed, 16 Oct 2024 11:26:34 +0000 Subject: [PATCH 7/7] Update directory --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 8c75d9524888..e511ab40b329 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -261,6 +261,8 @@ * [StrassenMatrixMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java) * [TilingProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/TilingProblem.java) * dynamicprogramming + * [Abbreviation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Abbreviation.java) + * [AssignmentUsingBitmask](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java) * [BoardPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java) * [BoundaryFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java) * [BruteForceKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java) @@ -864,6 +866,8 @@ * [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java) * [TilingProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/TilingProblemTest.java) * dynamicprogramming + * [AbbreviationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AbbreviationTest.java) + * [AssignmentUsingBitmaskTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java) * [BoardPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java) * [BoundaryFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java) * [BruteForceKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java)