package i5.las2peer.services.ocd.graphs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import i5.las2peer.services.ocd.adapters.AdapterException;
import i5.las2peer.services.ocd.algorithms.OcdAlgorithm;
import i5.las2peer.services.ocd.algorithms.SskAlgorithm;
import i5.las2peer.services.ocd.algorithms.utils.OcdAlgorithmException;
import i5.las2peer.services.ocd.graphs.Cover;
import i5.las2peer.services.ocd.graphs.CustomGraph;
import i5.las2peer.services.ocd.graphs.GraphProcessor;
import i5.las2peer.services.ocd.graphs.GraphType;
import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory;
import i5.las2peer.services.ocd.utils.Pair;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import y.base.Edge;
import y.base.Node;
import y.base.NodeCursor;
public class GraphProcessorTest {
/*
* Tests making a graph undirected, i.e. the reverse edge creation
* and edge weight setting, on sawmill.
*/
@Test
public void testMakeUndirected() throws AdapterException, FileNotFoundException {
/*
* Note that getSawmillGraph makes use of makeUndirected.
*/
CustomGraph undirectedGraph = OcdTestGraphFactory.getSawmillGraph();
CustomGraph directedGraph = OcdTestGraphFactory.getDirectedSawmillGraph();
assertEquals(undirectedGraph.nodeCount(), directedGraph.nodeCount());
/*
* Assures that the undirected graph has precisely twice as many edges
*/
assertEquals(undirectedGraph.edgeCount(), 2 * directedGraph.edgeCount());
System.out.println("Edge Count Directed Graph: " + directedGraph.edgeCount());
System.out.println("Edge Count Undirected Graph: " + undirectedGraph.edgeCount());
/*
* Assures that the undirected graph includes all the original and the reverse edges
* and possesses correct edge weights.
*/
NodeCursor directedNodes = directedGraph.nodes();
Node[] undirectedNodes = undirectedGraph.getNodeArray();
while(directedNodes.ok()) {
Node directedNode = directedNodes.node();
Node undirectedNode = undirectedNodes[directedNode.index()];
NodeCursor directedSuccessors = directedNode.successors();
while(directedSuccessors.ok()) {
Node directedSuccessor = directedSuccessors.node();
Node undirectedSuccessor = undirectedNodes[directedSuccessor.index()];
Edge edge = directedNode.getEdge(directedSuccessor);
double weight = directedGraph.getEdgeWeight(edge);
Edge toEdge = undirectedNode.getEdgeTo(undirectedSuccessor);
Edge fromEdge = undirectedNode.getEdgeFrom(undirectedSuccessor);
assertNotNull(toEdge);
assertNotNull(fromEdge);
assertEquals(weight, undirectedGraph.getEdgeWeight(toEdge), 0);
assertEquals(weight, undirectedGraph.getEdgeWeight(fromEdge), 0);
directedSuccessors.next();
}
directedNodes.next();
}
}
/*
* Tests removing multi edges from a graph.
*/
@Test
public void testRemoveMultiEdges() {
CustomGraph graph = new CustomGraph();
Node node1 = graph.createNode();
Node node2 = graph.createNode();
Edge edge1 = graph.createEdge(node1, node2);
graph.setEdgeWeight(edge1, 2d);
graph.createEdge(node1, node2);
System.out.println("Multi Edge Graph");
System.out.println("Edge Count: " + graph.edgeCount() + "\nEdge Weights:");
for(Edge edge : graph.getEdgeArray()) {
System.out.println(graph.getEdgeWeight(edge));
}
GraphProcessor processor = new GraphProcessor();
processor.removeMultiEdges(graph);
System.out.println("Single Edge Graph");
System.out.println("Edge Count: " + graph.edgeCount() + "\nEdge Weights:");
for(Edge edge : graph.getEdgeArray()) {
System.out.println(graph.getEdgeWeight(edge));
}
assertEquals(1, graph.edgeCount());
assertEquals(3d, graph.getEdgeWeight(graph.getEdgeArray()[0]), 0.00001);
}
/*
* Tests the component division and cover remerge on simple two components.
*/
@Test
public void testDivideAndMergeConnectedComponents() throws OcdAlgorithmException, InterruptedException {
CustomGraph graph = OcdTestGraphFactory.getSimpleTwoComponentsGraph();
GraphProcessor processor = new GraphProcessor();
List<Pair<CustomGraph, Map<Node, Node>>> components = processor.divideIntoConnectedComponents(graph);
List<Pair<Cover, Map<Node, Node>>> componentCovers = new ArrayList<Pair<Cover, Map<Node, Node>>>();
Cover currentCover;
OcdAlgorithm algo = new SskAlgorithm();
for(Pair<CustomGraph, Map<Node, Node>> component : components) {
currentCover = algo.detectOverlappingCommunities(component.getFirst());
componentCovers.add(new Pair<Cover, Map<Node, Node>>(currentCover, component.getSecond()));
}
Cover cover = processor.mergeComponentCovers(graph, componentCovers);
System.out.println("Divide and merge of simple two components");
System.out.println(cover.toString());
}
@Test
public void testDetermineGraphTypes() {
System.out.println("Test Determine Graph Types");
/*
* Empty graph.
*/
CustomGraph graph = new CustomGraph();
GraphProcessor processor = new GraphProcessor();
processor.determineGraphTypes(graph);
assertEquals(0, graph.getTypes().size());
System.out.println("Empty graph.");
System.out.println(graph.getTypes());
/*
* One directed edge.
*/
Node node0 = graph.createNode();
Node node1 = graph.createNode();
graph.createEdge(node0, node1);
processor.determineGraphTypes(graph);
System.out.println("One directed edge.");
System.out.println(graph.getTypes());
assertEquals(1, graph.getTypes().size());
assertTrue(graph.isOfType(GraphType.DIRECTED));
/*
* One undirected edge.
*/
graph.createEdge(node1, node0);
processor.determineGraphTypes(graph);
System.out.println("One undirected edge.");
System.out.println(graph.getTypes());
assertEquals(0, graph.getTypes().size());
/*
* Undirected edge and self loop.
*/
Edge edge2 = graph.createEdge(node0, node0);
processor.determineGraphTypes(graph);
System.out.println("Undirected edge and self loop.");
System.out.println(graph.getTypes());
assertEquals(1, graph.getTypes().size());
assertTrue(graph.isOfType(GraphType.SELF_LOOPS));
/*
* Undirected edge and weighted self loop.
*/
graph.setEdgeWeight(edge2, 2.5);
processor.determineGraphTypes(graph);
System.out.println("Undirected edge and weighted self loop.");
System.out.println(graph.getTypes());
assertEquals(2, graph.getTypes().size());
assertTrue(graph.isOfType(GraphType.SELF_LOOPS));
assertTrue(graph.isOfType(GraphType.WEIGHTED));
/*
* Undirected edge and 0 weight self loop.
*/
graph.setEdgeWeight(edge2, 0);
processor.determineGraphTypes(graph);
System.out.println("Undirected edge and 0 weight self loop.");
System.out.println(graph.getTypes());
assertEquals(3, graph.getTypes().size());
assertTrue(graph.isOfType(GraphType.SELF_LOOPS));
assertTrue(graph.isOfType(GraphType.WEIGHTED));
assertTrue(graph.isOfType(GraphType.ZERO_WEIGHTS));
/*
* Undirected edge, 0 weight self loop and directed negative edge.
*/
Node node2 = graph.createNode();
Edge edge3 = graph.createEdge(node0, node2);
graph.setEdgeWeight(edge3, -1);
processor.determineGraphTypes(graph);
System.out.println("Undirected edge, 0 weight self loop and directed negative edge.");
System.out.println(graph.getTypes());
assertEquals(5, graph.getTypes().size());
assertTrue(graph.isOfType(GraphType.SELF_LOOPS));
assertTrue(graph.isOfType(GraphType.WEIGHTED));
assertTrue(graph.isOfType(GraphType.ZERO_WEIGHTS));
assertTrue(graph.isOfType(GraphType.DIRECTED));
assertTrue(graph.isOfType(GraphType.NEGATIVE_WEIGHTS));
}
@Test
public void testMakeCompatible() {
/*
* Empty Graph
*/
System.out.println("Test Get Compatible Graph");
Set<GraphType> compatibleTypes = new HashSet<GraphType>();
CustomGraph graph = new CustomGraph();
GraphProcessor processor = new GraphProcessor();
processor.determineGraphTypes(graph);
System.out.println("Empty Graph. No compatible type.");
CustomGraph copy = new CustomGraph(graph);
processor.makeCompatible(copy, compatibleTypes);
processor.determineGraphTypes(copy);
System.out.println("Types: " + copy.getTypes());
assertEquals(compatibleTypes, copy.getTypes());
/*
* Further init.
*/
compatibleTypes.add(GraphType.NEGATIVE_WEIGHTS);
compatibleTypes.add(GraphType.WEIGHTED);
compatibleTypes.add(GraphType.DIRECTED);
compatibleTypes.add(GraphType.SELF_LOOPS);
Node node0 = graph.createNode();
Node node1 = graph.createNode();
Node node2 = graph.createNode();
Node node3 = graph.createNode();
graph.createEdge(node0, node1);
graph.createEdge(node1, node0);
graph.createEdge(node0, node0);
Edge edge3 = graph.createEdge(node0, node2);
Edge edge4 = graph.createEdge(node1, node2);
Edge edge5 = graph.createEdge(node2, node1);
Edge edge6 = graph.createEdge(node2, node3);
graph.setEdgeWeight(edge3, 3);
graph.setEdgeWeight(edge4, -1);
graph.setEdgeWeight(edge5, 0);
graph.setEdgeWeight(edge6, 0);
processor.determineGraphTypes(graph);
/*
* No zero weights.
*/
System.out.println("No zero weights.");
copy = new CustomGraph(graph);
processor.makeCompatible(copy, compatibleTypes);
processor.determineGraphTypes(copy);
System.out.println("Types: " + copy.getTypes());
assertEquals(compatibleTypes, copy.getTypes());
/*
* No negative weights.
*/
compatibleTypes.remove(GraphType.NEGATIVE_WEIGHTS);
compatibleTypes.add(GraphType.ZERO_WEIGHTS);
copy = new CustomGraph(graph);
processor.makeCompatible(copy, compatibleTypes);
processor.determineGraphTypes(copy);
System.out.println("No negative weights.");
System.out.println("Types: " + copy.getTypes());
assertEquals(compatibleTypes, copy.getTypes());
/*
* Undirected.
*/
compatibleTypes.add(GraphType.NEGATIVE_WEIGHTS);
compatibleTypes.remove(GraphType.DIRECTED);
copy = new CustomGraph(graph);
processor.makeCompatible(copy, compatibleTypes);
processor.determineGraphTypes(copy);
System.out.println("Undirected.");
System.out.println("Types: " + copy.getTypes());
assertEquals(compatibleTypes, copy.getTypes());
/*
* Self loops.
*/
compatibleTypes.add(GraphType.DIRECTED);
compatibleTypes.remove(GraphType.SELF_LOOPS);
copy = new CustomGraph(graph);
processor.makeCompatible(copy, compatibleTypes);
processor.determineGraphTypes(copy);
System.out.println("Self loops.");
System.out.println("Types: " + copy.getTypes());
assertEquals(compatibleTypes, copy.getTypes());
/*
* Unweighted.
*/
compatibleTypes.add(GraphType.SELF_LOOPS);
compatibleTypes.remove(GraphType.WEIGHTED);
copy = new CustomGraph(graph);
processor.makeCompatible(copy, compatibleTypes);
processor.determineGraphTypes(copy);
compatibleTypes.remove(GraphType.NEGATIVE_WEIGHTS);
compatibleTypes.remove(GraphType.ZERO_WEIGHTS);
System.out.println("Unweighted.");
System.out.println("Types: " + copy.getTypes());
assertEquals(compatibleTypes, copy.getTypes());
/*
* Unweighted, no negative weights, no zero weights.
*/
copy = new CustomGraph(graph);
processor.makeCompatible(copy, compatibleTypes);
processor.determineGraphTypes(copy);
System.out.println("Unweighted, no negative weights, no zero weights.");
System.out.println("Types: " + copy.getTypes());
assertEquals(compatibleTypes, copy.getTypes());
}
}