public void createArbitraryClusterTree(int clusterStep, int child1Id, int child2Id, int newId) { if (getRootClusters() == null) { setRootClusters(leafNodeClusters); pointersToClusterLevels = new TreeMap<>(); pointersToClusterLevels.put(0, new ArrayList<>(leafNodeClusters.values())); } NodeCluster nc1 = rootClusters.get(child1Id); NodeCluster nc2 = rootClusters.get(child2Id); NodeCluster newCluster = new NodeCluster( nc1, nc2, this.getInternalFlowMethod(), this.getInternalFlowMethodParameters(), clusterStep, newId); newCluster.freezeCluster(); flowValues.add(newCluster.getDeltaFlow()); rootClusters = updateClusterTree(rootClusters, newCluster); updateLinksAndNodes(newCluster); clusterSteps = clusterStep; logger.info( String.format( "Step %05d of %05d: c1: %05d + c2: %05d = %05d, flow = %08.2f, deltaFlow = %08.2f", clusterSteps, this.leafNodeClusters.size(), newCluster.getChild1().getId(), newCluster.getChild2().getId(), newCluster.getId(), newCluster.getInternalFlow(), newCluster.getDeltaFlow())); pointersToClusterLevels.put(clusterSteps, new ArrayList<>(rootClusters.values())); }
private TreeMap<Integer, NodeCluster> updateClusterTree( TreeMap<Integer, NodeCluster> currentNCs, NodeCluster newCluster) { TreeMap<Integer, NodeCluster> updatedNCs = new TreeMap<>(); int myId = newCluster.getChild1().getId(); if (newCluster.getChild2().getInternalFlow() > newCluster.getChild1().getInternalFlow()) { myId = newCluster.getChild2().getId(); } // updatedNCs.putAll(currentNCs); currentNCs.remove(newCluster.getChild1().getId()); currentNCs.remove(newCluster.getChild2().getId()); newCluster.setId(myId); currentNCs.put(myId, newCluster); // System.out.println(currentNCs.size()); return currentNCs; }
/** * Procedure that is run after intialization to find nodeclusters with one inlink or one outlink; * clusters these together with their upstream cluster (one inlink) or downstream cluster (one * outlink) */ private TreeMap<Integer, NodeCluster> findLoopsAndLongLinks( TreeMap<Integer, NodeCluster> clusters) { logger.info("Finding loops and long links: START"); boolean doneClustering = false; while (!doneClustering) { // TreeMap<Integer, NodeCluster> currentNCs = nodeClusterHistory // .pollLastEntry().getValue(); // get a single new NodeCluster for this step NodeCluster newCluster = findSingleInLinkClusters(clusters); if (newCluster == null) break; newCluster.freezeCluster(); clusters = updateClusterTree(clusters, newCluster); updateLinksAndNodes(newCluster); pointersToClusterLevels.put(clusterSteps, new ArrayList<>(clusters.values())); logger.info( String.format( "Step %05d of %05d: c1: %05d + c2: %05d = %05d, flow = %08.2f, deltaFlow = %08.2f", clusterSteps, this.leafNodeClusters.size(), newCluster.getChild1().getId(), newCluster.getChild2().getId(), newCluster.getId(), newCluster.getInternalFlow(), newCluster.getDeltaFlow())); clusterSteps++; } logger.info("Finding loops and long links: DONE"); return clusters; }
@Override protected NodeCluster findNextCluster( TreeMap<Integer, NodeCluster> currentNodeClusters, int clusterStep) { NodeCluster bestCluster = null; double minValue = Double.POSITIVE_INFINITY; HashSet<ClusterCombo> viableClusterCombos = getViableClusterCombos(currentNodeClusters); for (ClusterCombo cc : viableClusterCombos) { String[] ccs = cc.getComboId().split("z"); int i = Integer.parseInt(ccs[0]); int j = Integer.parseInt(ccs[1]); NodeCluster nc = new NodeCluster( currentNodeClusters.get(i), currentNodeClusters.get(j), this.internalFlowMethod, internalFlowMethodParameters, clusterStep, 0); double flowChange = nc.getInternalFlow() - nc.getChild1().getInternalFlow() - nc.getChild2().getInternalFlow(); if (flowChange < minValue) { minValue = flowChange; bestCluster = nc; } } return bestCluster; }
private void updateLinksAndNodes(NodeCluster newCluster) { for (ClusterLink l : newCluster.getInLinks().values()) { l.setNewRoot(newCluster, false); l.setToCluster(newCluster); } for (ClusterLink l : newCluster.getOutLinks().values()) { l.setNewRoot(newCluster, false); l.setFromCluster(newCluster); } for (ClusterLink l : newCluster.getInterLinks().values()) { l.setNewRoot(newCluster, true); } for (ClusterNode n : newCluster.getNodes().values()) { n.setNewRoot(newCluster); } newCluster.getChild1().setParent(newCluster); newCluster.getChild2().setParent(newCluster); }
public void run() { logger.info("Starting clustering algo, using the link method " + internalFlowMethod.toString()); clusterSteps = 1; TreeMap<Integer, NodeCluster> currentNodeClusters = new TreeMap<>(); currentNodeClusters = findLoopsAndLongLinks(leafNodeClusters); boolean doneClustering = false; NodeCluster newCluster = null; while (!doneClustering) { // get a single new NodeCluster for this step newCluster = findNextCluster(currentNodeClusters, clusterSteps); if (newCluster == null) { logger.error("Procedure ended with more than one cluster."); break; } newCluster.freezeCluster(); currentNodeClusters = updateClusterTree(currentNodeClusters, newCluster); updateLinksAndNodes(newCluster); flowValues.add(newCluster.getInternalFlow()); logger.info( String.format( "Step %05d of %05d: %05d + %05d = %05d, f: %08.2f, dF: %08.2f, invoc: %12d, obc: %12d", clusterSteps, this.leafNodeClusters.size(), newCluster.getChild1().getId(), newCluster.getChild2().getId(), newCluster.getId(), newCluster.getInternalFlow(), newCluster.getDeltaFlow(), NodeCluster.getInvocations(), outBoundClusterSize)); pointersToClusterLevels.put(clusterSteps, new ArrayList<>(currentNodeClusters.values())); if (currentNodeClusters.size() == 1) doneClustering = true; else clusterSteps++; } if (currentNodeClusters.size() > 1) { currentNodeClusters = findLoopsAndLongLinks(currentNodeClusters); } logger.info(String.format("number of clusters: %d", currentNodeClusters.size())); setRootClusters(currentNodeClusters); logger.info("DONE"); }