/*******************************************************************************
* Copyright (c) 2013 Michael Kutschke.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Michael Kutschke - initial API and implementation
******************************************************************************/
package bayesnet.jayes.util.triangulation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import bayesnet.jayes.util.Graph;
/**
* Graph elimination based on greedy minimum fill-in heuristic. Tie-breaking is done by using weights on the nodes. On
* tie, the node is chosen that will result in the cluster with a minimal sum of node weights
*/
public class GraphElimination implements Iterable> {
private final Graph graph;
private final double[] nodeWeights;
private final IEliminationHeuristic heuristic;
public GraphElimination(Graph graph, double[] nodeWeights, IEliminationHeuristic heuristic) {
this.nodeWeights = nodeWeights;
this.graph = graph;
this.heuristic = heuristic;
}
private List getNodeList() {
final List moralNodes = new LinkedList();
for (int i = 0; i < graph.numberOfVertices(); i++) {
moralNodes.add(i);
}
return moralNodes;
}
@Override
public Iterator> iterator() {
return new Iterator>() {
private List nodes = getNodeList();
private QuotientGraph graph = new QuotientGraph(GraphElimination.this.graph);
@Override
public boolean hasNext() {
return !nodes.isEmpty();
}
@Override
public List next() {
int next = nextTriangulationNode();
nodes.remove(Integer.valueOf(next));
List result = createClique(next);
graph.eliminate(next);
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private int nextTriangulationNode() {
int minCost = Integer.MAX_VALUE;
Double nextClusterWeight = Double.MAX_VALUE;
int returnNode = 0;
for (final int node : nodes) {
final int predictedCost = heuristic.getHeuristicValue(graph, node);
if (predictedCost <= minCost) {
final double clusterWeight = computeClusterWeight(node);
if (predictedCost < minCost || clusterWeight < nextClusterWeight) {
returnNode = node;
minCost = predictedCost;
nextClusterWeight = clusterWeight;
}
}
}
return returnNode;
}
private double computeClusterWeight(final int node) {
double clSize = nodeWeights[node];
for (final int neighbor : graph.getNeighbors(node)) {
clSize += nodeWeights[neighbor];
}
return clSize;
}
private List createClique(final int centerNode) {
final List clique = new ArrayList();
clique.add(centerNode);
for (final int neighbor : graph.getNeighbors(centerNode)) {
clique.add(neighbor);
}
return clique;
}
};
}
}
Ads help maintain this website.