/**
 * Copyright (c) 2011 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.inference.jtree;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;

import bayesnet.jayes.BayesNet;
import bayesnet.jayes.BayesNode;
import bayesnet.jayes.util.Graph;
import bayesnet.jayes.util.OrderIgnoringPair;
import bayesnet.jayes.util.Pair;
import bayesnet.jayes.util.triangulation.GraphElimination;
import bayesnet.jayes.util.triangulation.IEliminationHeuristic;

public class JunctionTreeBuilder {

    private final IEliminationHeuristic heuristic;

    public static JunctionTreeBuilder forHeuristic(IEliminationHeuristic heuristic) {
        return new JunctionTreeBuilder(heuristic);
    }

    protected JunctionTreeBuilder(IEliminationHeuristic heuristic) {
        this.heuristic = heuristic;
    }

    public JunctionTree buildJunctionTree(BayesNet net) {
        JunctionTree junctionTree = new JunctionTree();
        junctionTree.setClusters(triangulateGraphAndFindCliques(buildMoralGraph(net), weightNodesByOutcomes(net),
                heuristic));
        junctionTree.setSepSets(computeSepsets(junctionTree, net));
        return junctionTree;
    }

    private Graph buildMoralGraph(BayesNet net) {
        Graph moral = new Graph(net.getNodes().size());
        for (final BayesNode node : net.getNodes()) {
            addMoralEdges(moral, node);
        }
        return moral;
    }

    private void addMoralEdges(Graph moral, final BayesNode node) {
        final ListIterator it = node.getParents().listIterator();
        while (it.hasNext()) {
            final BayesNode parent = it.next();
            final ListIterator remainingParentsIt = node.getParents().listIterator(it.nextIndex());
            while (remainingParentsIt.hasNext()) { // connect parents
                final BayesNode otherParent = remainingParentsIt.next();
                moral.addEdge(parent.getId(), otherParent.getId());
            }
            moral.addEdge(node.getId(), parent.getId());
        }
    }

    private List> triangulateGraphAndFindCliques(Graph graph, double[] weights,
            IEliminationHeuristic eliminationHeuristic) {
        GraphElimination triangulate = new GraphElimination(graph, weights, eliminationHeuristic);

        final List> cliques = new ArrayList>();
        for (List nextClique : triangulate) {
            if (!containsSuperset(cliques, nextClique)) {
                cliques.add(nextClique);
            }
        }
        return cliques;
    }

    private double[] weightNodesByOutcomes(BayesNet net) {
        double[] weights = new double[net.getNodes().size()];
        for (BayesNode node : net.getNodes()) {
            weights[node.getId()] = Math.log(node.getOutcomeCount());
            // using these weights is the same as minimizing the resulting cluster factor size
            // which is given by the product of the variable outcome counts.
        }
        return weights;
    }

    private boolean containsSuperset(final Collection> sets, final Collection set) {
        boolean isSubsetOfOther = false;
        for (final Collection superset : sets) {
            if (superset.containsAll(set)) {
                isSubsetOfOther = true;
                break;
            }
        }
        return isSubsetOfOther;
    }

    private List, List>> computeSepsets(JunctionTree junctionTree, BayesNet net) {
        return new SepsetComputer().computeSepsets(junctionTree, net);

    }

}

 

Ads help maintain this website.