From c40eb8dbac618973d582af5d2a474dbebb2f6c90 Mon Sep 17 00:00:00 2001 From: Hardik Pawar <97388607+Hardvan@users.noreply.github.com> Date: Sat, 26 Oct 2024 11:45:24 +0530 Subject: [PATCH] Add `KCenters` algorithm (#5806) --- DIRECTORY.md | 2 + .../greedyalgorithms/KCenters.java | 62 +++++++++++++++++++ .../greedyalgorithms/KCentersTest.java | 15 +++++ 3 files changed, 79 insertions(+) create mode 100644 src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java create mode 100644 src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index d2badd760..78ff31bf9 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -325,6 +325,7 @@ * [FractionalKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java) * [GaleShapley](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/GaleShapley.java) * [JobSequencing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java) + * [KCenters](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java) * [MergeIntervals](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MergeIntervals.java) * [MinimizingLateness](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java) * [MinimumWaitingTime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTime.java) @@ -954,6 +955,7 @@ * [FractionalKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java) * [GaleShapleyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/GaleShapleyTest.java) * [JobSequencingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java) + * [KCentersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java) * [MergeIntervalsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MergeIntervalsTest.java) * [MinimizingLatenessTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java) * [MinimumWaitingTimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTimeTest.java) diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java b/src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java new file mode 100644 index 000000000..152b36053 --- /dev/null +++ b/src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java @@ -0,0 +1,62 @@ +package com.thealgorithms.greedyalgorithms; + +import java.util.Arrays; + +/** + * Given a set of points and a number k. + * The goal is to minimize the maximum distance between any point and its nearest center. + * Each point is assigned to the nearest center. + * The distance between two points is the Euclidean distance. + * The problem is NP-hard. + * + * @author Hardvan + */ +public final class KCenters { + private KCenters() { + } + + /** + * Finds the maximum distance to the nearest center given k centers. + * Steps: + * 1. Initialize an array {@code selected} of size n and an array {@code maxDist} of size n. + * 2. Set the first node as selected and update the maxDist array. + * 3. For each center, find the farthest node from the selected centers. + * 4. Update the maxDist array. + * 5. Return the maximum distance to the nearest center. + * + * @param distances matrix representing distances between nodes + * @param k the number of centers + * @return the maximum distance to the nearest center + */ + public static int findKCenters(int[][] distances, int k) { + int n = distances.length; + boolean[] selected = new boolean[n]; + int[] maxDist = new int[n]; + + Arrays.fill(maxDist, Integer.MAX_VALUE); + + selected[0] = true; + for (int i = 1; i < n; i++) { + maxDist[i] = Math.min(maxDist[i], distances[0][i]); + } + + for (int centers = 1; centers < k; centers++) { + int farthest = -1; + for (int i = 0; i < n; i++) { + if (!selected[i] && (farthest == -1 || maxDist[i] > maxDist[farthest])) { + farthest = i; + } + } + selected[farthest] = true; + for (int i = 0; i < n; i++) { + maxDist[i] = Math.min(maxDist[i], distances[farthest][i]); + } + } + + int result = 0; + for (int dist : maxDist) { + result = Math.max(result, dist); + } + return result; + } +} diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java new file mode 100644 index 000000000..9202d3467 --- /dev/null +++ b/src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.greedyalgorithms; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class KCentersTest { + + @Test + public void testFindKCenters() { + int[][] distances = {{0, 2, 3, 4}, {2, 0, 5, 1}, {3, 5, 0, 7}, {4, 1, 7, 0}}; + assertEquals(4, KCenters.findKCenters(distances, 2)); + assertEquals(2, KCenters.findKCenters(distances, 4)); + } +}