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())); }
@Override protected NodeCluster findSingleInLinkClusters(TreeMap<Integer, NodeCluster> clusters) { double minFlow = Double.POSITIVE_INFINITY; NodeCluster outCluster = null; for (int i : clusters.keySet()) { NodeCluster nc = clusters.get(i); if (nc.getInLinks().size() == 1) { for (ClusterLink cl : nc.getInLinks().values()) { NodeCluster newCluster; newCluster = new NodeCluster( cl.getFromCluster(), nc, internalFlowMethod, internalFlowMethodParameters, clusterSteps, cl.getFromCluster().getId()); if (newCluster.getDeltaFlow() < minFlow) { minFlow = newCluster.getDeltaFlow(); outCluster = newCluster; } } } } return outCluster; }
/** * 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; }
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"); }