package splar.core.fm.clustering;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import splar.core.constraints.CNFClause;
import splar.core.constraints.CNFFormula;
import splar.core.fm.FeatureModel;
import splar.core.fm.FeatureTreeNode;
import splar.core.heuristics.FORCEVariableOrderingHeuristic;
public class NodeCluster {
private FeatureTreeNode root;
private FeatureModel featureModel;
private List<FeatureTreeNode> nodes;
private int size = -1;
private List<CNFClause> ecClauses;
private List<CNFClause> clusterClauses;
public NodeCluster(FeatureModel featureModel, FeatureTreeNode root) {
this.root = root;
this.featureModel = featureModel;
this.nodes = new ArrayList<FeatureTreeNode>();
this.ecClauses = null;
this.clusterClauses = null;
}
public List<FeatureTreeNode> getNodes() {
return nodes;
}
public FeatureTreeNode getRoot() {
return root;
}
public void addNode(FeatureTreeNode node) {
nodes.add(node);
}
public void addECClauses(List<CNFClause> ecClauses) {
this.ecClauses = ecClauses;
}
public void addClusterClauses(List<CNFClause> clusterClauses) {
this.clusterClauses = clusterClauses;
}
public List<CNFClause> getECClauses() {
return ecClauses;
}
public List<CNFClause> getClusterClauses() {
return clusterClauses;
}
// count number of nodes for each cluster-node subtree
public int countNodes() {
return nodes.size();
}
public int size() {
if ( size == -1 ) {
for( FeatureTreeNode node : nodes ) {
size += featureModel.countNodes(node);
}
}
return size;
}
// cluster nodes are sorted in ASCENDING order of the size of their subtrees
public FeatureTreeNode[] sortedNodes() {
FeatureTreeNode[] sortedNodes = new FeatureTreeNode[nodes.size()];
int index = 0;
for( FeatureTreeNode node : nodes ) {
sortedNodes[index++] = node;
}
if ( sortedNodes.length > 1 ) {
Comparator<FeatureTreeNode> c = new Comparator<FeatureTreeNode>() {
public int compare(FeatureTreeNode node1, FeatureTreeNode node2) {
int size1 = featureModel.countNodes(node1);
int size2 = featureModel.countNodes(node2);
return ( size1 > size2 ? 1 : ((size1 < size2) ? -1 : 0) );
}
};
java.util.Arrays.sort(sortedNodes, c);
}
return sortedNodes;
}
// sort nodes based on FORCE heuristic
public FeatureTreeNode[] sortedNodesbyFORCE() {
FORCEVariableOrderingHeuristic force = new FORCEVariableOrderingHeuristic("",1);
CNFFormula cnf = new CNFFormula();
cnf.addClauses(clusterClauses);
String vo[] = force.run(cnf);
FeatureTreeNode voNodes[] = new FeatureTreeNode[vo.length];
int index = 0;
for( String nodeID : vo ) {
voNodes[index++] = featureModel.getNodeByID(nodeID);
}
return voNodes;
}
public void dump() {
System.out.println("\nCluster: " + root.getID());
System.out.print(" Nodes: ");
for( FeatureTreeNode node : nodes ) {
System.out.print( node.getID() + ", ");
}
if ( clusterClauses != null ) {
System.out.print("\n Cluster clauses: ");
for( CNFClause clause: clusterClauses) {
System.out.print( clause + ", ");
}
}
if ( ecClauses != null ) {
System.out.print("\n EC clauses: ");
for( CNFClause clause: ecClauses) {
System.out.print( clause + ", ");
}
}
}
}