Improve comments in Mcoloring.java (#5484)

This commit is contained in:
Hardik Pawar
2024-10-02 19:16:34 +05:30
committed by GitHub
parent 0bd86b3d7e
commit dab8ff3d1d
2 changed files with 49 additions and 29 deletions

View File

@ -7,64 +7,82 @@ import java.util.Queue;
import java.util.Set; import java.util.Set;
/** /**
* Node class represents a graph node. Each node is associated with a color
* (initially 1) and contains a set of edges representing its adjacent nodes.
*
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
*/ */
class Node { class Node {
int color = 1; int color = 1; // Initial color for each node
Set<Integer> edges = new HashSet<Integer>(); Set<Integer> edges = new HashSet<Integer>(); // Set of edges representing adjacent nodes
} }
/**
* MColoring class solves the M-Coloring problem where the goal is to determine
* if it's possible to color a graph using at most M colors such that no two
* adjacent nodes have the same color.
*/
public final class MColoring { public final class MColoring {
private MColoring() {
}
static int possiblePaint(ArrayList<Node> nodes, int n, int m) {
// Create a visited array of n nodes private MColoring() {
} // Prevent instantiation of utility class
/**
* Determines whether it is possible to color the graph using at most M colors.
*
* @param nodes List of nodes representing the graph.
* @param n The total number of nodes in the graph.
* @param m The maximum number of allowed colors.
* @return true if the graph can be colored using M colors, false otherwise.
*/
static boolean isColoringPossible(ArrayList<Node> nodes, int n, int m) {
// Visited array keeps track of whether each node has been processed.
ArrayList<Integer> visited = new ArrayList<Integer>(); ArrayList<Integer> visited = new ArrayList<Integer>();
for (int i = 0; i < n + 1; i++) { for (int i = 0; i < n + 1; i++) {
visited.add(0); visited.add(0); // Initialize all nodes as unvisited (0)
} }
// maxColors used till now are 1 as // The number of colors used so far (initially set to 1, since all nodes
// all nodes are painted color 1 // start with color 1).
int maxColors = 1; int maxColors = 1;
// Loop through all the nodes to ensure every node is visited, in case the
// graph is disconnected.
for (int sv = 1; sv <= n; sv++) { for (int sv = 1; sv <= n; sv++) {
if (visited.get(sv) > 0) { if (visited.get(sv) > 0) {
continue; continue; // Skip nodes that are already visited
} }
// If the starting point is unvisited, // If the node is unvisited, mark it as visited and add it to the queue for BFS.
// mark it visited and push it in queue
visited.set(sv, 1); visited.set(sv, 1);
Queue<Integer> q = new LinkedList<>(); Queue<Integer> q = new LinkedList<>();
q.add(sv); q.add(sv);
// BFS // Perform BFS to process all nodes and their adjacent nodes
while (q.size() != 0) { while (q.size() != 0) {
int top = q.peek(); int top = q.peek(); // Get the current node from the queue
q.remove(); q.remove();
// Checking all adjacent nodes // Check all adjacent nodes of the current node
// to "top" edge in our queue
for (int it : nodes.get(top).edges) { for (int it : nodes.get(top).edges) {
// If the color of the // If the adjacent node has the same color as the current node, increment its
// adjacent node is same, increase it by // color to avoid conflict.
// 1
if (nodes.get(top).color == nodes.get(it).color) { if (nodes.get(top).color == nodes.get(it).color) {
nodes.get(it).color += 1; nodes.get(it).color += 1;
} }
// If number of colors used exceeds m, // Keep track of the maximum number of colors used so far
// return 0
maxColors = Math.max(maxColors, Math.max(nodes.get(top).color, nodes.get(it).color)); maxColors = Math.max(maxColors, Math.max(nodes.get(top).color, nodes.get(it).color));
// If the number of colors used exceeds the allowed limit M, return false.
if (maxColors > m) { if (maxColors > m) {
return 0; return false;
} }
// If the adjacent node is not visited, // If the adjacent node hasn't been visited yet, mark it as visited and add it
// mark it visited and push it in queue // to the queue for further processing.
if (visited.get(it) == 0) { if (visited.get(it) == 0) {
visited.set(it, 1); visited.set(it, 1);
q.add(it); q.add(it);
@ -72,6 +90,7 @@ public final class MColoring {
} }
} }
} }
return 1;
return true; // Possible to color the entire graph with M or fewer colors.
} }
} }

View File

@ -1,6 +1,7 @@
package com.thealgorithms.backtracking; package com.thealgorithms.backtracking;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList; import java.util.ArrayList;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -16,7 +17,7 @@ class MColoringTest {
int[][] graph = {{0, 1, 1, 1}, {1, 0, 1, 0}, {1, 1, 0, 1}, {1, 0, 1, 0}}; int[][] graph = {{0, 1, 1, 1}, {1, 0, 1, 0}, {1, 1, 0, 1}, {1, 0, 1, 0}};
int m = 3; // Number of colors int m = 3; // Number of colors
assertEquals(1, MColoring.possiblePaint(createGraph(graph), n, m)); assertTrue(MColoring.isColoringPossible(createGraph(graph), n, m));
} }
@Test @Test
@ -25,7 +26,7 @@ class MColoringTest {
int[][] graph = {{0, 1, 1, 1, 0}, {1, 0, 0, 1, 0}, {1, 0, 0, 1, 1}, {1, 1, 1, 0, 1}, {0, 0, 1, 1, 0}}; int[][] graph = {{0, 1, 1, 1, 0}, {1, 0, 0, 1, 0}, {1, 0, 0, 1, 1}, {1, 1, 1, 0, 1}, {0, 0, 1, 1, 0}};
int m = 2; // Number of colors int m = 2; // Number of colors
assertEquals(0, MColoring.possiblePaint(createGraph(graph), n, m)); assertFalse(MColoring.isColoringPossible(createGraph(graph), n, m));
} }
@Test @Test
@ -34,7 +35,7 @@ class MColoringTest {
int[][] graph = {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}}; int[][] graph = {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}};
int m = 2; // Number of colors int m = 2; // Number of colors
assertEquals(0, MColoring.possiblePaint(createGraph(graph), n, m)); assertFalse(MColoring.isColoringPossible(createGraph(graph), n, m));
} }
private ArrayList<Node> createGraph(int[][] graph) { private ArrayList<Node> createGraph(int[][] graph) {