Skip to content
Merged
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
67 changes: 43 additions & 24 deletions src/main/java/com/thealgorithms/backtracking/MColoring.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,71 +7,90 @@
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)
*/
class Node {
int color = 1;
Set<Integer> edges = new HashSet<Integer>();
int color = 1; // Initial color for each node
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 {

private MColoring() {
}
static int possiblePaint(ArrayList<Node> nodes, int n, int m) {
} // Prevent instantiation of utility class

// Create a visited array of n nodes
/**
* 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>();
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
// all nodes are painted color 1
// The number of colors used so far (initially set to 1, since all nodes
// start with color 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++) {
if (visited.get(sv) > 0) {
continue;
continue; // Skip nodes that are already visited
}

// If the starting point is unvisited,
// mark it visited and push it in queue
// If the node is unvisited, mark it as visited and add it to the queue for BFS.
visited.set(sv, 1);
Queue<Integer> q = new LinkedList<>();
q.add(sv);

// BFS
// Perform BFS to process all nodes and their adjacent nodes
while (q.size() != 0) {
int top = q.peek();
int top = q.peek(); // Get the current node from the queue
q.remove();

// Checking all adjacent nodes
// to "top" edge in our queue
// Check all adjacent nodes of the current node
for (int it : nodes.get(top).edges) {

// If the color of the
// adjacent node is same, increase it by
// 1
// If the adjacent node has the same color as the current node, increment its
// color to avoid conflict.
if (nodes.get(top).color == nodes.get(it).color) {
nodes.get(it).color += 1;
}

// If number of colors used exceeds m,
// return 0
// Keep track of the maximum number of colors used so far
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) {
return 0;
return false;
}

// If the adjacent node is not visited,
// mark it visited and push it in queue
// If the adjacent node hasn't been visited yet, mark it as visited and add it
// to the queue for further processing.
if (visited.get(it) == 0) {
visited.set(it, 1);
q.add(it);
}
}
}
}
return 1;

return true; // Possible to color the entire graph with M or fewer colors.
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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 org.junit.jupiter.api.Test;
Expand All @@ -16,7 +17,7 @@ void testGraphColoring1() {
int[][] graph = {{0, 1, 1, 1}, {1, 0, 1, 0}, {1, 1, 0, 1}, {1, 0, 1, 0}};
int m = 3; // Number of colors

assertEquals(1, MColoring.possiblePaint(createGraph(graph), n, m));
assertTrue(MColoring.isColoringPossible(createGraph(graph), n, m));
}

@Test
Expand All @@ -25,7 +26,7 @@ void testGraphColoring2() {
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

assertEquals(0, MColoring.possiblePaint(createGraph(graph), n, m));
assertFalse(MColoring.isColoringPossible(createGraph(graph), n, m));
}

@Test
Expand All @@ -34,7 +35,7 @@ void testGraphColoring3() {
int[][] graph = {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}};
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) {
Expand Down