@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; }
public NodeCluster getLargestCluster(ArrayList<NodeCluster> clustersAtLevel) { double largest = 0; NodeCluster outCluster = null; for (NodeCluster nc : clustersAtLevel) { if (nc.getInternalFlow() > largest) { largest = nc.getInternalFlow(); outCluster = nc; } } if (outCluster == null) outCluster = clustersAtLevel.get(0); return outCluster; }
HashSet<ClusterCombo> getViableClusterCombos(TreeMap<Integer, NodeCluster> nodeClusters) { HashSet<ClusterCombo> clusterCheck = new HashSet<>(); for (NodeCluster c1 : nodeClusters.values()) { for (NodeCluster c2 : c1.getOutBoundClusters()) { outBoundClusterSize++; // skip if this combination is already i the hashset clusterCheck.add(new ClusterCombo(c1.getId(), c2.getId())); } } // System.out.println("Clustercombos: " + clusterCheck.size()); return clusterCheck; }
private boolean hasSharedLinks(NodeCluster nc1, NodeCluster nc2) { for (ClusterLink l : nc1.getInLinks().values()) { if (nc2.getOutLinks().get(l.getId()) != null) { return true; } } for (ClusterLink l : nc1.getOutLinks().values()) { if (nc2.getInLinks().get(l.getId()) != null) { return true; } } return false; }
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())); }
/** * 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; }
private boolean initializePointers() { if (getRootClusters() == null) { return false; } pointersToClusterLevels = new TreeMap<>(); ArrayList<NodeCluster> outClusters = null; outClusters = new ArrayList<>(); ArrayList<NodeCluster> tempClusters = new ArrayList<>(); tempClusters.addAll(getRootClusters().values()); boolean levelFound = false; int currentLevel = 0; // first, find the highest nodecluster in the set for (NodeCluster nc : tempClusters) { if (nc.getClusterStepFormed() > currentLevel) currentLevel = nc.getClusterStepFormed(); } while (!levelFound) { if (currentLevel == 0) { levelFound = true; outClusters.addAll(tempClusters); } else { ArrayList<NodeCluster> tempClusters2 = new ArrayList<>(); tempClusters2.addAll(tempClusters); tempClusters = new ArrayList<>(); for (NodeCluster nc : tempClusters2) { // if (nc.getClusterStepParented()==maxLevel-1) // outClusters.add(nc); // else if (nc.getClusterStepFormed() < currentLevel || nc.isLeaf()) tempClusters.add(nc); else tempClusters.addAll(nc.getChildren().values()); } currentLevel--; } } return true; }
@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; }
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"); }
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; }
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); }
@Override public void draw() { // stroke(0); if (change) { println(currentStep + ":" + colorsForDisplay.length); background(255); pushMatrix(); if (followMouse) { translate(mouseX - width / 2, mouseY - height / 2); } if (width / height < (maxX - minX) / (maxY - minY)) scale(width / (maxX - minX), -width / (maxX - minX)); else scale(height / (maxY - minY), -height / (maxY - minY)); ArrayList<NodeCluster> clustersAtLevel = nca.getClustersAtLevel(currentStep); NodeCluster largestCluster = nca.getLargestCluster(clustersAtLevel); println("largest: " + largestCluster.getId()); translate(-minX, -maxY); for (NodeCluster nc : clustersAtLevel) { if (nc.isLeaf()) { for (ClusterLink link : nc.getOutLinks().values()) { strokeWeight(strokeWeights.get(link.getId())); stroke(color(240)); // pushMatrix(); line( (float) (link.getFromNode().getCoord().getX()), (float) (link.getFromNode().getCoord().getY()), (float) (link.getToNode().getCoord().getX()), (float) (link.getToNode().getCoord().getY())); } } else { for (ClusterLink link : nc.getInterLinks().values()) { strokeWeight(strokeWeights.get(link.getId())); int colindex = nc.getId(); if (nc.equals(largestCluster)) { stroke(color(255, 0, 0)); } else { stroke(colorsForDisplay[colindex]); } // pushMatrix(); line( (float) (link.getFromNode().getCoord().getX()), (float) (link.getFromNode().getCoord().getY()), (float) (link.getToNode().getCoord().getX()), (float) (link.getToNode().getCoord().getY())); } for (ClusterLink link : nc.getOutLinks().values()) { strokeWeight(strokeWeights.get(link.getId())); stroke(color(200)); // pushMatrix(); line( (float) (link.getFromNode().getCoord().getX()), (float) (link.getFromNode().getCoord().getY()), (float) (link.getToNode().getCoord().getX()), (float) (link.getToNode().getCoord().getY())); } } } // println(currentStep+":"+clustersAtLevel); // for (Link link : network.getLinks().values()) { // // popMatrix(); // } // for (Node n:network.getNodes().values()){ // // } popMatrix(); change = false; // currentStep++; fill(0); text(currentStep + ":" + (colorsForDisplay.length - 1), 20, 20); } if (this.mousePressed) { change = true; followMouse = true; } // do some frame counting // fcount += 1; // int m = millis(); // if (m - lastm > 1000 * fint) { // frate = (float) fcount / fint; // fcount = 0; // lastm = m; // // println("fps: " + frate); // } // text(frate, 0, 20); }