protected ClusterNode mergeClusters(ClusterNode first, ClusterNode second) { for (Node node : second.getPrimitives()) { first.add(node); graph.setNodeAliasMapping(node.getIndex(), first); } graph.removeClusterNode(second); return first; }
/* * (non-Javadoc) * * @see * org.processmining.mining.fuzzymining.graph.transform.FuzzyGraphTransformer * #transform(org.processmining.mining.fuzzymining.graph.FuzzyGraph) */ public void transform(MutableFuzzyGraph graph) { this.graph = graph; // clean up edges cleanUpEdges(threshold * 0.1, 1.0); // threshold * 0.3); // determine simplification victims ArrayList<Node> simplificationVictims = new ArrayList<Node>(); Node n; for (int i = 0; i < graph.getNumberOfInitialNodes(); i++) { n = graph.getPrimitiveNode(i); if (n.getSignificance() < threshold) { simplificationVictims.add(n); } } // create clusters int clusterIndex = graph.getNumberOfInitialNodes() + 1; while (simplificationVictims.size() > 0) { ClusterNode cluster = new ClusterNode(graph, clusterIndex); graph.addClusterNode(cluster); clusterIndex++; boolean nodeAdded = true; while (nodeAdded == true) { nodeAdded = false; ArrayList<Node> clustered = new ArrayList<Node>(); for (Node node : simplificationVictims) { if (shouldMergeWith(node, cluster) == true) { cluster.add(node); graph.setNodeAliasMapping(node.getIndex(), cluster); clustered.add(node); nodeAdded = true; } } simplificationVictims.removeAll(clustered); } } // merge clusters mergeAllClusters(); // remove unary clusters for (int i = graph.getClusterNodes().size() - 1; i >= 0; i--) { ClusterNode cluster = graph.getClusterNodes().get(i); if (cluster.getPrimitives().size() == 1) { // unary cluster; remove for (int k = 0; k < graph.getNumberOfInitialNodes(); k++) { Node mapping = graph.getNodeMappedTo(k); if (mapping != null && mapping.equals(cluster)) { graph.setNodeAliasMapping(k, null); } } graph.removeClusterNode(cluster); } } // clean up edges cleanUpEdges(threshold, threshold); }
protected boolean shouldMerge(ClusterNode first, ClusterNode second) { if (first.equals(second)) { return false; } else if (first.directlyFollows(second) && second.directlyFollows(first)) { return true; // connected in both directions: merge } else { Set<Node> preFirst = first.getPredecessors(); Set<Node> preSecond = second.getPredecessors(); if (doSignificantlyOverlap(preFirst, preSecond)) { return true; } /* * HashSet<Node> preBoth = new HashSet<Node>(); * preBoth.addAll(preFirst); preBoth.retainAll(preSecond); * if((preBoth.size() * 2) > (preFirst.size() + preSecond.size())) { * return true; } */ Set<Node> postFirst = first.getSuccessors(); Set<Node> postSecond = second.getSuccessors(); return doSignificantlyOverlap(postFirst, postSecond); /* * HashSet<Node> postBoth = new HashSet<Node>(); * postBoth.addAll(postFirst); postBoth.retainAll(postSecond); * if((postBoth.size() * 2) > (postFirst.size() + * postSecond.size())) { return true; } else { return false; } */ } }
protected boolean shouldMergeWith(Node node, ClusterNode cluster) { if (cluster.getPrimitives().size() == 0) { return true; // always add first node } if (cluster.isDirectlyConnectedTo(node) == true && cluster.contains(node) == false) { double ownSignificance = 0.0; double otherSignificance = 0.0; double ownCorrelation = 0.0; double otherCorrelation = 0.0; // aggregate correlation and significance of edges between the node // in // question and connected nodes, separately for edges to/from // cluster and // to/from other nodes. for (int i = 0; i < graph.getNumberOfInitialNodes(); i++) { if (i == node.getIndex()) { continue; // ignore self-references } if (cluster.contains(graph.getPrimitiveNode(i))) { ownSignificance += graph.getBinarySignificance(node.getIndex(), i); ownSignificance += graph.getBinarySignificance(i, node.getIndex()); ownCorrelation += graph.getBinaryCorrelation(node.getIndex(), i); ownCorrelation += graph.getBinaryCorrelation(i, node.getIndex()); } else { otherSignificance += graph.getBinarySignificance(node.getIndex(), i); otherSignificance += graph.getBinarySignificance(i, node.getIndex()); otherCorrelation += graph.getBinaryCorrelation(node.getIndex(), i); otherCorrelation += graph.getBinaryCorrelation(i, node.getIndex()); } } // make a decision return (ownCorrelation > otherCorrelation || ownSignificance > otherSignificance); } else { // no connection - no merge. return false; } }