/* * CCVisu is a tool for visual graph clustering * and general force-directed graph layout. * This file is part of CCVisu. * * Copyright (C) 2005-2012 Dirk Beyer * * CCVisu is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * CCVisu is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CCVisu; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Please find the GNU Lesser General Public License in file * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt * * Dirk Beyer (firstname.lastname@uni-passau.de) * University of Passau, Bavaria, Germany */ package org.sosy_lab.ccvisu.clustering; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; import org.junit.Test; import org.sosy_lab.ccvisu.graph.GraphData; import org.sosy_lab.ccvisu.graph.GraphVertex; import org.sosy_lab.ccvisu.graph.Group; import com.google.common.collect.Lists; public class ClustererMinDistPercTest { /** * Create one vertex/node for the test graph. * @param uniqueName * @param posX Position on the x axis. * @param posY Position on the y axis. * @param posZ POsition on the z axis. * @return */ private GraphVertex createTestVertex (String uniqueName, int posX, int posY, int posZ) { GraphVertex vertex = new GraphVertex(uniqueName); vertex.getPosition().x = posX; vertex.getPosition().y = posY; vertex.getPosition().z = posZ; return vertex; } /** * Create a test graph layout (without edges). * @return Graph */ public GraphData createTestGraph1() { GraphData graph = new GraphData(); GraphVertex[] vertices = { // Cluster 1 createTestVertex("V1", 1, 0, 0), createTestVertex("V2", 3, 0, 0), createTestVertex("V3", 4, 0, 0), // Cluster 2 createTestVertex("V4", 10, 0, 0), createTestVertex("V5", 11, 0, 0), createTestVertex("V6", 13, 0, 0), // Cluster 3 createTestVertex("V7", 21, 0, 0), createTestVertex("V8", 23, 0, 0), createTestVertex("V9", 25, 0, 0), // Cluster 4 createTestVertex("V10", 41, 0, 0), createTestVertex("V11", 42, 0, 0) }; // Represents the following graph: // o . o o | . . . . O o . o . | . . . . | o . o . O . . . . | . . . . | . . . . | o o . . | graph.setVertices(Lists.newArrayList(vertices)); return graph; } /** * Create a test graph layout (without edges). * @return Graph */ public GraphData createTestGraph2() { GraphData graph = new GraphData(); GraphVertex[] vertices = { // Cluster 1 createTestVertex("V1", 1, 0, 0), createTestVertex("V2", 2, 0, 0), createTestVertex("V3", 3, 0, 0), // Cluster 2 createTestVertex("V4", 10, 0, 0), createTestVertex("V5", 11, 0, 0), createTestVertex("V6", 12, 0, 0), // Cluster 3 createTestVertex("V7", 21, 0, 0), createTestVertex("V8", 22, 0, 0), createTestVertex("V9", 23, 0, 0), // Cluster 4 createTestVertex("V10", 41, 0, 0), createTestVertex("V11", 42, 0, 0) }; // Represents the following graph: // o o o . | . . . . O o o . . | . . . . | o o o . | . . . . | . . . . | . . . . | o o . . | graph.setVertices(Lists.newArrayList(vertices)); return graph; } /** * Create a test graph layout (without edges). * @return Graph */ public GraphData createTestGraph3() { GraphData graph = new GraphData(); GraphVertex[] vertices = { // Cluster 1 createTestVertex("V1", 1, 0, 0), createTestVertex("V2", 2, 0, 0), createTestVertex("V3", 3, 0, 0), // Cluster 2 createTestVertex("V4", 11, 0, 0), createTestVertex("V5", 12, 0, 0), createTestVertex("V6", 13, 0, 0) }; // Represents the following graph: // o o o . | . . . . | o o o . | graph.setVertices(Lists.newArrayList(vertices)); return graph; } /** * Check if there is a partition containing all the given nodes. * @param partitions List of partitions that are checked for the nodes. * @param nodeNames Names of the nodes that should be contained in one partition. * @return */ public boolean existNodesWithinOnePartition(List<Group> partitions, String[] nodeNames) { // TODO: Time complexity of this method could be optimized. for (Group g : partitions) { int contained = 0; for (GraphVertex n : g.getNodes()) { for (String s : nodeNames) { if (n.getName().equals(s)) { contained++; } } } if (contained == nodeNames.length) { return true; } } return false; } @Test public void createClustersOfLayout_NoHeuristic() { // Create the graph containing the test data. GraphData graph = createTestGraph1(); // Create and parameterize the clustering algorithm. ClustererMinDistPerc clusterer = new ClustererMinDistPerc(graph, 4, 0, 1); // Run the clustering algorithm. List<Group> partitions = null; try { partitions = clusterer.createClustersOfLayout(graph); } catch (InterruptedException e) { assertTrue(false); } // Check the results. assertNotNull(partitions); assertEquals(4, partitions.size()); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V10", "V11" })); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V7", "V8", "V9" })); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V4", "V5", "V6" })); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V1", "V2", "V3" })); } @Test public void createClustersOfLayout_UsingHeuristic() { // Create the graph containing the test data. GraphData graph = createTestGraph1(); // Create and parameterize the clustering algorithm. ClustererMinDistPerc clusterer = new ClustererMinDistPerc(graph, 4 /* Number of clusters. In general the stop parameter may case more than this. */, 0.10 /* Max distance percent to auto merge. * 0.05 = 5% = All clusters within a distance of 5% of * the diagonal of the graph are merged without recalculating * there distances after each merge. */, 1 /* Only merge clusters having a distance less than. * 1 = 100% = All clusters are within this distance. */ ); // Run the clustering algorithm. List<Group> partitions = null; try { partitions = clusterer.createClustersOfLayout(graph); } catch (InterruptedException e) { assertTrue(false); } for (Group group : partitions) { System.out.print(group.getName() + ": "); for (GraphVertex vertex : group.getNodes()) { System.out.print(vertex.getName() + ", "); } System.out.println(); } // Check the results. assertNotNull(partitions); assertEquals(4, partitions.size()); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V10", "V11" })); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V7", "V8", "V9" })); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V4", "V5", "V6" })); assertTrue(existNodesWithinOnePartition(partitions, new String[] { "V1", "V2", "V3" })); } }