package splar.core.heuristics;
import java.util.ArrayList;
import java.util.List;
import splar.core.constraints.CNFFormula;
import splar.core.fm.FeatureModel;
import splar.core.fm.FeatureTreeNode;
import splar.core.fm.clustering.FeatureModelClustersManager;
import splar.core.fm.clustering.NodeCluster;
/*
* Given a node P, its child nodes A, B, C, D, E, F, G, and clauses (A,D), (A,F), (B,G)
*
* Step 1: Creates clusters based on their clause dependencies
* ------
* 1. (A,D,F)
* 2. (B,G)
* 3. (C)
* 4. (E)
* (*) Note that variables not in the clauses form a cluster each
*
* Step 2: Sorts clusters (ascending-order) based on the size of the subtrees rooted by their nodes, say:
* ------
* 1. (B,G) - 78 nodes
* 2. (E) - 83 nodes
* 3. (C) - 187 nodes
* 4. (A,D,F) - 200 nodes
*
* Step 3: Sort cluster nodes based on their size; single-node clusters are not considered for obvious reasons, say:
* ------
* 1. (B,G) - 18 + 60 = 78 nodes
* 2. (E) - 83 nodes
* 3. (C) - 187 nodes
* 4. (D,F,A) - 20 + 80 + 100 = 200 nodes
*
* Step 4: Return the nodes order
* ------
* >> B, G, E, C, D, F, A
*/
public class FTPreOrderClustersTraversalHeuristic extends FTPreOrderTraversalHeuristic {
public static final int SIZE_SORT = 10;
public static final int FORCE_SORT = 20;
private int sortType = SIZE_SORT;
private FeatureModelClustersManager clustersManager;
public FTPreOrderClustersTraversalHeuristic(String name, FeatureModelClustersManager clustersManager, int sortType) {
super(name, clustersManager.getFeatureModel());
this.sortType = sortType;
this.clustersManager = clustersManager;
}
protected FeatureTreeNode[] orderChildNodes(FeatureTreeNode node) {
List<FeatureTreeNode> orderedNodes = new ArrayList<FeatureTreeNode>();
// Step 1: Creates clusters based on their clause dependencies
// Step 2: Sorts clusters (ascending-order) based on the total size of their subtrees
for( NodeCluster cluster : clustersManager.sortClusterAscendingOrder(node) ) {
FeatureTreeNode nodes[] = null;
// Step 3: Sort cluster subtrees based on their size; single-node clusters are not considered for obvious reasons
if ( sortType == SIZE_SORT || cluster.countNodes() <= 2) {
nodes = cluster.sortedNodes();
}
// Step 3: Sort cluster subtrees using FORCE and its dependencies
else if ( sortType == FORCE_SORT ){
nodes = cluster.sortedNodesbyFORCE();
}
for( FeatureTreeNode sortedNode : nodes ) {
orderedNodes.add(sortedNode);
}
}
// Step 4: Return the nodes order
return orderedNodes.toArray(new FeatureTreeNode[0]);
}
protected void runPreProcessing(CNFFormula cnf) {
if ( !clustersManager.clustersReady() ) {
clustersManager.createClusters();
}
}
}