package de.lmu.ifi.dbs.elki.data;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.result.BasicResult;
/**
* Result class for clusterings. Can be used for both hierarchical and
* non-hierarchical clusterings.
*
* The class does not enforce or rely on clusterings to be a tree or DAG,
* instead they can be an arbitrary forest of directed graphs that COULD contain
* cycles.
*
* This class is NOT iterable for a simple reason: there is more than one method to do so.
* You need to specify whether you want to use getToplevelClusters() or getAllClusters().
*
* @author Erich Schubert
*
* @apiviz.composedOf Cluster oneway - n
*
* @param Model type
*/
public class Clustering extends BasicResult {
/**
* Keep a list of top level clusters.
*/
private List> toplevelclusters;
/**
* Constructor with a list of top level clusters
*
* @param name The long name (for pretty printing)
* @param shortname the short name (for filenames etc.)
* @param toplevelclusters Top level clusters
*/
public Clustering(String name, String shortname, List> toplevelclusters) {
super(name, shortname);
this.toplevelclusters = toplevelclusters;
}
/**
* Constructor for an empty clustering
*
* @param name The long name (for pretty printing)
* @param shortname the short name (for filenames etc.)
*/
public Clustering(String name, String shortname) {
this(name, shortname, new ArrayList>());
}
/**
* Add a cluster to the clustering.
*
* @param n new cluster
*/
public void addCluster(Cluster n) {
toplevelclusters.add(n);
}
/**
* Return top level clusters
*
* @return top level clusters
*/
public List> getToplevelClusters() {
return toplevelclusters;
}
/**
* Collect all clusters (recursively) into a List.
*
* @return List of all clusters.
*/
public List> getAllClusters() {
Set> clu = new HashSet>();
for(Cluster rc : toplevelclusters) {
if(!clu.contains(rc)) {
clu.add(rc);
for (Iterator> iter = rc.iterDescendants(); iter.hasNext(); ) {
clu.add(iter.next());
}
}
}
// Note: we canNOT use TreeSet above, because this comparator is only
// partial!
ArrayList> res = new ArrayList>(clu);
Collections.sort(res, new Cluster.PartialComparator());
return res;
}
}