Skip to content

Add WelshPowell (Graph Colouring) #5034

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 26 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e230856
Welsh Powell Algorithm + Test
straf10 Jan 31, 2024
080904b
Welsh Powell Algorithm+Test second commit to fit pull request
straf10 Jan 31, 2024
47b77fd
Welsh Powell Algorithm+Test second commit to fit pull request
straf10 Jan 31, 2024
60e2d10
3rd commit
straf10 Jan 31, 2024
5868035
4th commit
straf10 Jan 31, 2024
30c4cdc
5th attempt
straf10 Jan 31, 2024
6200b82
6th attempt
straf10 Jan 31, 2024
037fc3a
7th attempt
straf10 Jan 31, 2024
da6d43a
Update src/main/java/com/thealgorithms/datastructures/graphs/Welsh_Po…
straf10 Jan 31, 2024
7328b1b
8th attempt
straf10 Jan 31, 2024
86f4ecd
Merge remote-tracking branch 'origin/master'
straf10 Jan 31, 2024
c1ae53a
9th commit(removed main and changed the test class)
straf10 Jan 31, 2024
b3e036f
Merge branch 'master' into master
straf10 Feb 1, 2024
a7f3fcd
Update src/main/java/com/thealgorithms/datastructures/graphs/WelshPow…
straf10 Feb 2, 2024
f59fb89
implemented Hashset, changed name to src,dst to nodeA,B added some me…
straf10 Feb 4, 2024
4039a2f
implemented Hashset, changed name to src,dst to nodeA,B added some me…
straf10 Feb 4, 2024
68cefa1
clang format
straf10 Feb 4, 2024
ba19ccb
added 4 new methods to improve the code, test class still unchanged b…
straf10 Feb 4, 2024
207bb9f
implemented the new changes. Test class probably needs more work
straf10 Feb 5, 2024
01db1c3
changed the addEdge method to disallow self loops(nodeA==nodeB), the …
straf10 Feb 6, 2024
a5e876f
added all the tests except one
straf10 Feb 6, 2024
c71082a
preColored test
straf10 Feb 6, 2024
016b561
reverted the findColoring
straf10 Feb 9, 2024
a55e7eb
added more complex test, blank color method
straf10 Feb 12, 2024
90288e7
refactor: use `isBlank`
vil02 Feb 12, 2024
863c4dc
Merge branch 'master' into master
vil02 Feb 12, 2024
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,83 @@
package com.thealgorithms.datastructures.graphs;

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.stream.IntStream;

/*
* The Welsh-Powell algorithm is a graph coloring algorithm
* used for coloring a graph with the minimum number of colors.
* https://en.wikipedia.org/wiki/Graph_coloring
*/

public class WelshPowell {

static class WPGraph {
private int numVer; // Number of vertices in the graph
private HashSet<Integer>[] adjLists; // Adjacency lists for the graph

private WPGraph(int vertices) {
numVer = vertices;
adjLists = new HashSet[vertices];
Arrays.setAll(adjLists, i -> new HashSet<>());
}

private void addEdge(int nodeA, int nodeB) {
adjLists[nodeA].add(nodeB);
adjLists[nodeB].add(nodeA);
}

HashSet<Integer> getAdjList(int vertex) {
return adjLists[vertex];
}

int getNumVertices() {
return numVer;
}
}

public static WPGraph makeGraph(int numberOfVertices, int[][] listOfEdges) {
WPGraph graph = new WPGraph(numberOfVertices);
for (int[] edge : listOfEdges) {
graph.addEdge(edge[0], edge[1]);
}
return graph;
}

public static int[] welshPowellColoring(WPGraph graph) {
int[] colors = initializeColors(graph.getNumVertices());
Integer[] sortedVertices = getSortedNodes(graph);
for (int vertex : sortedVertices) {
if (colors[vertex] == -1) {
boolean[] usedColors = computeUsedColors(graph, vertex, colors);
colors[vertex] = firstUnusedColor(usedColors);
}
}
return colors;
}

private static int[] initializeColors(int numVer) {
int[] colors = new int[numVer];
Arrays.fill(colors, -1);
return colors;
}

private static Integer[] getSortedNodes(WPGraph graph) {
return IntStream.range(0, graph.getNumVertices()).boxed().sorted(Comparator.comparingInt(v -> - graph.getAdjList(v).size())).toArray(Integer[] ::new);
}

private static boolean[] computeUsedColors(WPGraph graph, int vertex, int[] colors) {
boolean[] usedColors = new boolean[graph.getNumVertices()];
graph.getAdjList(vertex).stream().map(neighbor -> colors[neighbor]).filter(color -> color != -1).forEach(color -> usedColors[color] = true);
return usedColors;
}

private static int firstUnusedColor(boolean[] usedColors) {
return IntStream.range(0, usedColors.length).filter(color -> !usedColors[color]).findFirst().getAsInt();
}

public static void addEdge(WPGraph graph, int nodeA, int nodeB) {
graph.addEdge(nodeA, nodeB);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.thealgorithms.datastructures.graphs;

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

import com.thealgorithms.datastructures.graphs.WelshPowell.WPGraph;
import org.junit.jupiter.api.Test;

class WelshPowellAlgorithmTest {

@Test
void testSimpleGraph() {
int[][] edges = {{0, 1}, {1, 2}, {2, 3}};
WPGraph graph = WelshPowell.makeGraph(4, edges);
int[] colors = WelshPowell.welshPowellColoring(graph);
assertTrue(isValidColoring(graph, colors));
}

@Test
void testDisconnectedGraph() {
WPGraph graph = WelshPowell.makeGraph(3, new int[][] {}); // No edges
int[] colors = WelshPowell.welshPowellColoring(graph);
assertTrue(isValidColoring(graph, colors));
}

@Test
void testCompleteGraph() {
int[][] edges = {{0, 1}, {1, 2}, {2, 0}};
WPGraph graph = WelshPowell.makeGraph(3, edges);
int[] colors = WelshPowell.welshPowellColoring(graph);
assertTrue(isValidColoring(graph, colors));
}

private boolean isValidColoring(WPGraph graph, int[] colors) {
int numVertices = graph.getNumVertices();
for (int i = 0; i < numVertices; i++) {
for (int neighbor : graph.getAdjList(i)) {
if (i != neighbor && colors[i] == colors[neighbor]) {
return false; // Adjacent vertices have the same color
}
}
}
return true; // No adjacent vertices share the same color
}
}