package bgu.bio.algorithms.graphs;
import gnu.trove.list.array.TIntArrayList;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import org.junit.Assert;
import org.junit.Test;
import bgu.bio.adt.graphs.FlexibleUndirectedGraph;
import bgu.bio.adt.tuples.IntDoublePair;
import bgu.bio.io.file.json.JSONException;
import bgu.bio.io.file.json.JSONObject;
public class TestMaximalWeightedClique {
private boolean useTimeout = true;
@Test
public void testUnDirectedClique1() {
FlexibleUndirectedGraph graph = new FlexibleUndirectedGraph();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addEdge(0, 1);
graph.addEdge(0, 4);
graph.addEdge(0, 3);
graph.addEdge(3, 2);
graph.addEdge(5, 3);
graph.addEdge(4, 3);
MaximalWeightedClique maximalWeightedClique = new MaximalWeightedClique();
maximalWeightedClique.setGraph(graph);
TIntArrayList ans = maximalWeightedClique
.findMaximumWeightedClique(new double[] { 1, 1, 1, 1, 1, 1, 1 });
ans.sort();
int[] arr = ans.toArray();
Assert.assertArrayEquals("Found the wrong clique",
new int[] { 0, 3, 4 }, arr);
}
@Test
public void testUnDirectedCliqueOnSingles() {
FlexibleUndirectedGraph graph = new FlexibleUndirectedGraph();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
MaximalWeightedClique maximalWeightedClique = new MaximalWeightedClique();
maximalWeightedClique.setGraph(graph);
TIntArrayList ans = maximalWeightedClique
.findMaximumWeightedClique(new double[] { 1, 1, 5, 1, 1, 1, 1 });
ans.sort();
int[] arr = ans.toArray();
Assert.assertArrayEquals("Found the wrong clique",
new int[] { 2 }, arr);
}
@Test
public void testUnDirectedClique2() {
FlexibleUndirectedGraph graph = new FlexibleUndirectedGraph();
int nodes = 10;
for (int i = 0; i < nodes; i++) {
graph.addNode();
}
for (int i = 0; i < nodes; i++) {
for (int j = i + 1; j < nodes; j++) {
graph.addEdge(i, j);
}
}
double[] weights = new double[nodes];
for (int i = 0; i < nodes; i++) {
weights[i] = 1;
}
MaximalWeightedClique maximalWeightedClique = new MaximalWeightedClique();
maximalWeightedClique.setGraph(graph);
TIntArrayList ans = maximalWeightedClique
.findMaximumWeightedClique(weights);
ans.sort();
int[] arr = ans.toArray();
int[] expected = new int[nodes];
for (int i = 0; i < expected.length; i++) {
expected[i] = i;
}
Assert.assertArrayEquals("Found the wrong clique", expected, arr);
}
@Test
public void testUnDirectedClique3() {
FlexibleUndirectedGraph graph = new FlexibleUndirectedGraph();
int nodes = 6;
for (int i = 0; i < nodes; i++) {
graph.addNode();
}
graph.addEdge(0, 5);
graph.addEdge(2, 5);
double[] weights = new double[] { 23.7600228881836, 10.149999618530273,
10.559999465942383, 12.0100228881836, 18.53999900817871,
29.6900534057617 };
MaximalWeightedClique maximalWeightedClique = new MaximalWeightedClique();
maximalWeightedClique.setGraph(graph);
TIntArrayList ans = maximalWeightedClique
.findMaximumWeightedClique(weights);
ans.sort();
int[] arr = ans.toArray();
int[] expected = new int[] { 0, 5 };
Assert.assertArrayEquals("Found the wrong clique", expected, arr);
}
@Test
public void testUnDirectedCliqueMandatory1() {
FlexibleUndirectedGraph graph = new FlexibleUndirectedGraph();
int nodes = 9;
for (int i = 0; i < nodes; i++) {
graph.addNode();
}
graph.addEdge(1, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 3);
graph.addEdge(3, 4);
graph.addEdge(3, 5);
graph.addEdge(3, 6);
graph.addEdge(4, 5);
graph.addEdge(4, 6);
graph.addEdge(5, 6);
double[] weights = new double[] { 20, 10, 10, 10, 2, 11, 2, 1, 1 };
MaximalWeightedClique maximalWeightedClique = new MaximalWeightedClique();
maximalWeightedClique.setGraph(graph);
TIntArrayList ans = maximalWeightedClique
.findMaximumWeightedClique(weights);
ans.sort();
int[] arr = ans.toArray();
int[] expected = new int[] { 1, 2, 3 };
Assert.assertArrayEquals("Found the wrong clique", expected, arr);
TIntArrayList ans2 = maximalWeightedClique.findMaximumWeightedClique(
weights, new TIntArrayList(new int[] { 6 }));
ans2.sort();
int[] arr2 = ans2.toArray();
int[] expected2 = new int[] { 3, 4, 5, 6 };
Assert.assertArrayEquals("Found the wrong clique", expected2, arr2);
TIntArrayList ans3 = maximalWeightedClique.findMaximumWeightedClique(
weights, new TIntArrayList(new int[] { 6, 3 }));
ans3.sort();
int[] arr3 = ans3.toArray();
int[] expected3 = new int[] { 1, 2, 3 };
Assert.assertArrayEquals(
"Found the wrong clique " + Arrays.toString(arr3), expected3,
arr3);
TIntArrayList ans4 = maximalWeightedClique.findMaximumWeightedClique(
weights, new TIntArrayList(new int[] { 7 }));
ans4.sort();
int[] arr4 = ans4.toArray();
int[] expected4 = new int[] { 7 };
Assert.assertArrayEquals("Found the wrong clique", expected4, arr4);
}
@Test
public void testBig1() {
testFile("test-files/cliques/big1", 10000);
}
@Test
public void testBig2() {
testFile("test-files/cliques/big2", 5000);
}
@Test
public void testBig3() {
testFile("test-files/cliques/big3", 10000);
}
@Test
public void testBig4() {
testFile("test-files/cliques/timeout488", 10000);
}
@Test
public void testBig5() {
testFile("test-files/cliques/timeout100", 7000);
}
@Test
public void testBig6() {
testFile("test-files/cliques/timeout81", 6000);
}
@Test
public void testDensity() {
File[] files = new File("test-files/cliques/problematics")
.listFiles(new FilenameFilter() {
@Override
public boolean accept(File arg0, String arg1) {
return arg1.toLowerCase().contains("json");
}
});
for (int i = 0; i < files.length; i++) {
try {
String json = content(files[i].getAbsolutePath());
FlexibleUndirectedGraph graph = FlexibleUndirectedGraph
.fromJSON(new JSONObject(json));
System.out.println(files[i].getName() + " " + graph.stats());
/*
FileWriter writer = new FileWriter(files[i].getName() + ".dot");
writer.write(graph.toDOTFormat());
writer.close();
*/
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private String content(String filename) throws IOException {
StringBuilder sb = new StringBuilder();
FileReader file = new FileReader(new File(filename));
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
while (line != null) {
sb.append(line);
line = reader.readLine();
}
reader.close();
return sb.toString();
}
private void testFile(String fileNamePrefix, long time) {
System.out.println(fileNamePrefix);
try {
String json = content(fileNamePrefix + "-json.txt");
String mandatory = content(fileNamePrefix + "-mandatory.txt");
String weight = content(fileNamePrefix + "-weights.txt");
String answer = content(fileNamePrefix + "-answer.txt");
String[] sp = mandatory.split(",");
TIntArrayList mandatoryList = new TIntArrayList();
for (String string : sp) {
mandatoryList.add(Integer.parseInt(string.trim()));
}
sp = weight.split(",");
double[] weightsArr = new double[sp.length];
int i = 0;
for (String string : sp) {
weightsArr[i] = Double.parseDouble(string.trim());
i++;
}
sp = answer.split(",");
int[] expected = new int[sp.length];
i = 0;
for (String string : sp) {
expected[i] = Integer.parseInt(string.trim());
i++;
}
JSONObject jsonData = new JSONObject(json.trim());
FlexibleUndirectedGraph graph = FlexibleUndirectedGraph
.fromJSON(jsonData);
MaximalWeightedClique maximalWeightedClique = new MaximalWeightedClique();
maximalWeightedClique.setGraph(graph);
if (useTimeout) {
maximalWeightedClique.setTimeout(time);
}
TIntArrayList ans = null;
double ansWeight = 0;
ArrayList<Comparator<ArrayList<IntDoublePair>>> comps = maximalWeightedClique
.getClassesComparators();
for (Comparator<ArrayList<IntDoublePair>> comparator : comps) {
maximalWeightedClique.setClassesComparator(comparator);
TIntArrayList ansTemp = maximalWeightedClique
.findMaximumWeightedClique(weightsArr, mandatoryList);
ansTemp.sort();
final int[] ansArray = ansTemp.toArray();
double curWeight = evaluate(ansArray, weightsArr);
if (curWeight > ansWeight) {
ansWeight = curWeight;
ans = ansTemp;
}
System.out.println(Arrays.toString(maximalWeightedClique
.typesOfPrunings()));
if (!maximalWeightedClique.timedout()) {
break;
}
}
final int[] ansArray = ans.toArray();
System.out.println(maximalWeightedClique.statistics());
System.out.println(Arrays.toString(maximalWeightedClique
.typesOfPrunings()));
double expWeight = evaluate(expected, weightsArr);
System.out.println(ans);
System.out.println(expWeight);
System.out.println(ansWeight);
Assert.assertArrayEquals(expected, ansArray);
} catch (IOException e) {
e.printStackTrace();
Assert.fail("IO exception:" + e.getMessage());
} catch (JSONException e) {
Assert.fail("JSON exception:" + e.getMessage());
e.printStackTrace();
}
}
private double evaluate(int[] ans, double[] weights) {
double total = 0;
for (int i = 0; i < ans.length; i++) {
total += weights[ans[i]];
}
return total;
}
public static void main(String[] args) {
TestMaximalWeightedClique t = new TestMaximalWeightedClique();
t.useTimeout = true;
t.testBig1();
t.testBig2();
t.testBig3();
}
}