A Java program that determines if there is a 3-clique in a graph:
The problem defined:
https://en.wikipedia.org/wiki/Clique_problem
Input format:
The input to the method called three_clique
is a String encoding representing an undirected graph that is represented like this:
(1,2,3)((1,2);(2,3);(3,1))
This encoding denotes an undirected graph with three nodes: 1,2,3. There are edges between 1 and 2, 2 and 3 and 3 and 1. It looks like a triangle. Clearly this undirected graph contains a 3 clique.
This encoding of an undirected graph does not contain a 3-clique:
(1,2,3)((1,2);(3,4))
The code:
import java.util.AbstractMap.SimpleEntry;
import java.util.Map;
import java.util.AbstractMap;
import java.util.ArrayList;
public class Main{
public static boolean three_clique(String encoding){
if (encoding.length() == 0){
return false;
}
String[] elements = encoding.substring(1, encoding.indexOf(")")).split(",");
encoding = encoding.substring(encoding.indexOf(")")+2);
encoding = encoding.substring(0, encoding.length()-1);
ArrayList<Map.Entry<Integer, Integer>> arr = new ArrayList<Map.Entry<Integer, Integer>>();
String[] pairs = encoding.split(";");
if (pairs.length == 1){
return false;
}
for(int x = 0; x < pairs.length; x++){
String str = pairs[x].substring(1, pairs[x].length()-1);
String[] items = str.split(",");
int left = Integer.parseInt(items[0]);
int right = Integer.parseInt(items[1]);
arr.add(new AbstractMap.SimpleEntry(left, right));
}
for(int x = 0; x < elements.length; x++){
for(int y = 0; y < elements.length; y++){
for(int z = 0; z < elements.length; z++){
if (x != y && y != z && z != x){
int one = Integer.parseInt(elements[x]);
int two = Integer.parseInt(elements[y]);
int three = Integer.parseInt(elements[z]);
if (is_connected(arr, one, two) &&
is_connected(arr, two, three) &&
is_connected(arr, three, one)){
return true;
}
}
}
}
}
return false;
}
public static boolean is_connected(ArrayList<Map.Entry<Integer, Integer>> arr, int left, int right){
for(int x = 0; x < arr.size(); x++){
if (left == arr.get(x).getKey() && arr.get(x).getValue() == right){
return true;
}
if (right == arr.get(x).getKey() && arr.get(x).getValue() == left){
return true;
}
}
return false;
}
public static void main(String[] args){
tests();
}
public static void tests(){
String encoding = "";
boolean expected;
String msg = "";
encoding = "";
expected = false;
msg = "expected '" + encoding + "' encoding to be false";
doTest(encoding, expected, msg);
encoding = "(1)()";
expected = false;
msg = "expected '" + encoding + "' encoding to be " + expected;
doTest(encoding, expected, msg);
encoding = "(1,2)((1,2))";
expected = false;
msg = "expected '" + encoding + "' encoding to be " + expected;
doTest(encoding, expected, msg);
encoding = "(1,2,3)((1,2);(2,3);(3,1))";
expected = true;
msg = "expected '" + encoding + "' encoding to be " + expected;
doTest(encoding, expected, msg);
encoding = "(1,2,3)((1,2);(3,4))";
expected = false;
msg = "expected '" + encoding + "' encoding to be " + expected;
doTest(encoding, expected, msg);
encoding = "(1,2,3,4)((1,2);(2,3);(3,1);(1,4))";
expected = true;
msg = "expected '" + encoding + "' encoding to be " + expected;
doTest(encoding, expected, msg);
encoding = "(1,2,3)((1,2);(2,3);(1,3))";
expected = true;
msg = "expected '" + encoding + "' encoding to be " + expected;
doTest(encoding, expected, msg);
}
public static void doTest(String encoding, boolean expected, String msg){
boolean result = three_clique(encoding);
if (result == expected){
System.out.print(".");
}
else{
System.out.println("\n" + msg);
}
}
}
Output
The program outputs a series of seven dots on the screen which means all the unit tests pass. To prove it works, add some more unit test cases for large undirected graphs like this one: (1,2,3,4,5)((1,5);(1,4);(1,3);(1,2);(1,1);)
And see if it returns false.
Runtime complexity:
Computational complexity is Polynomial, specifically O(n^3)
. So it's very inefficient and is certainly not the optimal algorithm for this problem. But it demonstrates the starting point how to approach and solve the clique problem in Java.