public void newmanCluster(ItemRegistry registry) { DoubleMatrix2D distance_matrix = DoubleFactory2D.sparse.make( registry.getGraph().getNodeCount(), registry.getGraph().getNodeCount()); DoubleMatrix1D a_matrix = DoubleFactory1D.dense.make(registry.getGraph().getNodeCount(), 0.); Map<String, Cluster> cluster_map = new HashMap<String, Cluster>(); // construct the leaf node distance matrix Iterator edge_iter = registry.getGraph().getEdges(); m_total_distances = 0.; while (edge_iter.hasNext()) { Edge edge = (Edge) edge_iter.next(); Cluster clust1 = (Cluster) edge.getFirstNode(); Cluster clust2 = (Cluster) edge.getSecondNode(); if (cluster_map.get(clust1.getAttribute("id")) == null) { cluster_map.put(clust1.getAttribute("id"), clust1); } if (cluster_map.get(clust2.getAttribute("id")) == null) { cluster_map.put(clust2.getAttribute("id"), clust2); } int n = Integer.parseInt(clust1.getAttribute("id")); int m = Integer.parseInt(clust2.getAttribute("id")); // make reciprocal (big values = good in newman, but not in our case) double dist = 1 / clust1.getCenter().distance(clust2.getCenter()); distance_matrix.set(Math.max(n, m), Math.min(n, m), dist); // m_total_distances += dist; // a_matrix.setQuick( n, a_matrix.getQuick( n ) + dist ); // a_matrix.setQuick( m, a_matrix.getQuick( m ) + dist ); m_total_distances += 1; a_matrix.setQuick(n, a_matrix.getQuick(n) + 1); a_matrix.setQuick(m, a_matrix.getQuick(m) + 1); } // System.out.println(distance_matrix); // System.out.println(count_matrix); // agglomerate nodes until we reach a root node (or nodes) boolean done = false; int trash = 0; QFinder qfinder = new QFinder(); qfinder.a_matrix = a_matrix; QMerger qmerger = new QMerger(); while (!done) { // find the minimum cluster distance qfinder.reset(); distance_matrix.forEachNonZero(qfinder); // done = true; // System.out.println(distance_matrix); // System.out.println(count_matrix); if (qfinder.getVal() == -Double.MAX_VALUE) { break; } // add a parent cluster to the graph Cluster clust1 = cluster_map.get("" + qfinder.getM()); Cluster clust2 = cluster_map.get("" + qfinder.getN()); while (clust1.getParent() != null) { clust1 = clust1.getParent(); } while (clust2.getParent() != null) { clust2 = clust2.getParent(); } trash++; double dist = Math.max(clust1.getHeight(), clust2.getHeight()); Cluster new_cluster = new DefaultCluster( (float) (clust1.getCenter().getX() + clust2.getCenter().getX()) / 2.f, (float) (clust1.getCenter().getY() + clust2.getCenter().getY()) / 2.f, (float) Math.sqrt( clust1.getRadius() * clust1.getRadius() + clust2.getRadius() * clust2.getRadius()), clust1, clust2, dist); registry.getGraph().addNode(new_cluster); // merge the clusters distances / counts int M = Math.max(qfinder.getM(), qfinder.getN()); int N = Math.min(qfinder.getM(), qfinder.getN()); a_matrix.set(N, a_matrix.getQuick(M) + a_matrix.getQuick(N)); a_matrix.set(M, 0); // System.out.println("M = "+M+" N = "+N + " VAL=" + minfinder.getVal() ); qmerger.setM(M); qmerger.setN(N); qmerger.setParent(distance_matrix); qmerger.setMode(true); // System.out.println(distance_matrix.viewPart( 0, M, distance_matrix.rows(), 1)); distance_matrix.viewPart(0, M, distance_matrix.rows(), 1).forEachNonZero(qmerger); qmerger.setMode(false); // System.out.println(distance_matrix.viewPart( M, 0, 1, M )); distance_matrix.viewPart(M, 0, 1, M).forEachNonZero(qmerger); // System.out.println(distance_matrix); // System.out.println(count_matrix); // free any superfluous memory randomly ~ (1/20) times if (Math.random() > 0.95) { distance_matrix.trimToSize(); } } }
public void shortestDistance(ItemRegistry registry) { // System.out.println(""+registry.getGraph().getNodeCount()); DoubleMatrix2D distance_matrix = DoubleFactory2D.sparse.make( registry.getGraph().getNodeCount(), registry.getGraph().getNodeCount()); DoubleMatrix2D count_matrix = DoubleFactory2D.sparse.make( registry.getGraph().getNodeCount(), registry.getGraph().getNodeCount()); Map<String, Cluster> cluster_map = new HashMap<String, Cluster>(); // construct the leaf node distance matrix Iterator edge_iter = registry.getGraph().getEdges(); while (edge_iter.hasNext()) { Edge edge = (Edge) edge_iter.next(); Cluster clust1 = (Cluster) edge.getFirstNode(); Cluster clust2 = (Cluster) edge.getSecondNode(); if (cluster_map.get(clust1.getAttribute("id")) == null) { cluster_map.put(clust1.getAttribute("id"), clust1); } if (cluster_map.get(clust2.getAttribute("id")) == null) { cluster_map.put(clust2.getAttribute("id"), clust2); } int n = Integer.parseInt(clust1.getAttribute("id")); int m = Integer.parseInt(clust2.getAttribute("id")); double dist = clust1.getCenter().distance(clust2.getCenter()); distance_matrix.set(Math.max(n, m), Math.min(n, m), dist); count_matrix.set(Math.max(n, m), Math.min(n, m), 1); } // System.out.println(distance_matrix); // System.out.println(count_matrix); // agglomerate nodes until we reach a root node (or nodes) boolean done = false; MinFinder minfinder = new MinFinder(); minfinder.count_matrix = count_matrix; Merger merger = new Merger(); while (!done) { // find the minimum cluster distance minfinder.reset(); distance_matrix.forEachNonZero(minfinder); // done = true; // System.out.println(distance_matrix); // System.out.println(count_matrix); if (minfinder.getVal() == Double.MAX_VALUE) { break; } // add a parent cluster to the graph Cluster clust1 = cluster_map.get("" + minfinder.getM()); Cluster clust2 = cluster_map.get("" + minfinder.getN()); while (clust1.getParent() != null) { clust1 = clust1.getParent(); } while (clust2.getParent() != null) { clust2 = clust2.getParent(); } // System.out.println("HERE!"); Cluster new_cluster = new DefaultCluster( (float) (clust1.getCenter().getX() + clust2.getCenter().getX()) / 2.f, (float) (clust1.getCenter().getY() + clust2.getCenter().getY()) / 2.f, (float) Math.sqrt( clust1.getRadius() * clust1.getRadius() + clust2.getRadius() * clust2.getRadius()), clust1, clust2, minfinder.getVal()); registry.getGraph().addNode(new_cluster); // merge the clusters distances / counts int M = Math.max(minfinder.getM(), minfinder.getN()); int N = Math.min(minfinder.getM(), minfinder.getN()); // System.out.println("M = "+M+" N = "+N + " VAL=" + minfinder.getVal() ); merger.setM(M); merger.setN(N); merger.setParent(distance_matrix); merger.setMode(true); // System.out.println(distance_matrix.viewPart( 0, M, distance_matrix.rows(), 1)); distance_matrix.viewPart(0, M, distance_matrix.rows(), 1).forEachNonZero(merger); merger.setMode(false); // System.out.println(distance_matrix.viewPart( M, 0, 1, M )); distance_matrix.viewPart(M, 0, 1, M).forEachNonZero(merger); merger.setParent(count_matrix); merger.setMode(true); count_matrix.viewPart(0, M, count_matrix.rows(), 1).forEachNonZero(merger); merger.setMode(false); count_matrix.viewPart(M, 0, 1, M).forEachNonZero(merger); // System.out.println(distance_matrix); // System.out.println(count_matrix); // free any superfluous memory randomly ~ (1/20) times if (Math.random() > 0.95) { distance_matrix.trimToSize(); } } }