package de.lmu.ifi.dbs.elki.data; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures Copyright (C) 2015 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.Comparator; import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable; import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream; /** * Generic cluster class, that may or not have hierarchical information. Note * that every cluster MUST have a DBIDs, since it implements the interface, too. * Calls to the interface are proxied to the inner group object. * * A hierarchy object of class SimpleHierarchy will be created automatically * when a list of parents and children is provided. Alternatively, a * pre-existing hierarchy object can be provided, e.g. when there is a single * hierarchy object used for keeping all the hierarchy information in one * object. * * @param Model object type * * @author Erich Schubert * @since 0.2 * * @apiviz.landmark * * @apiviz.composedOf DBIDs * @apiviz.composedOf Model */ public class Cluster implements TextWriteable { /** * Cluster name. */ protected String name = null; /** * Cluster data. */ private DBIDs ids = null; /** * Cluster model. */ private M model = null; /** * Noise? */ private boolean noise = false; /** * Full constructor * * @param name Cluster name. May be null. * @param ids Object Group * @param noise Noise flag * @param model Model. May be null. */ public Cluster(String name, DBIDs ids, boolean noise, M model) { super(); this.name = name; this.ids = ids; this.noise = noise; this.model = model; } /** * Constructor without hierarchy information. * * @param name Cluster name. May be null. * @param ids Object group * @param model Model */ public Cluster(String name, DBIDs ids, M model) { this(name, ids, false, model); } /** * Constructor without hierarchy information and name * * @param ids Object group * @param noise Noise flag * @param model Model */ public Cluster(DBIDs ids, boolean noise, M model) { this(null, ids, noise, model); } /** * Constructor without hierarchy information and name * * @param ids Object group * @param model Model */ public Cluster(DBIDs ids, M model) { this(null, ids, false, model); } /** * Constructor without hierarchy information and model * * @param name Cluster name. May be null. * @param ids Object group * @param noise Noise flag */ public Cluster(String name, DBIDs ids, boolean noise) { this(name, ids, noise, null); } /** * Constructor without hierarchy information and model * * @param name Cluster name. May be null. * @param ids Object group */ public Cluster(String name, DBIDs ids) { this(name, ids, false, null); } /** * Constructor without hierarchy information and name and model * * @param ids Cluster name. May be null. * @param noise Noise flag */ public Cluster(DBIDs ids, boolean noise) { this(null, ids, noise, null); } /** * Constructor without hierarchy information and name and model * * @param ids Object group */ public Cluster(DBIDs ids) { this(null, ids, false, null); } /** * Delegate to database object group. * * @return Cluster size retrieved from object group. */ public int size() { return ids.size(); } /** * Return either the assigned name or the suggested label * * @return a name for the cluster */ public String getNameAutomatic() { if(name != null) { return name; } if(isNoise()) { return "Noise"; } else { return "Cluster"; } } /** * Get Cluster name. May be null. * * @return cluster name, or null */ public String getName() { return name; } /** * Set Cluster name * * @param name new cluster name */ public void setName(String name) { this.name = name; } /** * Access group object * * @return database object group */ public DBIDs getIDs() { return ids; } /** * Access group object * * @param g set database object group */ public void setIDs(DBIDs g) { ids = g; } /** * Access model object * * @return Cluster model */ public M getModel() { return model; } /** * Access model object * * @param model New cluster model */ public void setModel(M model) { this.model = model; } /** * Write to a textual representation. Writing the actual group data will be * handled by the caller, this is only meant to write the meta information. * * @param out output writer stream * @param label Label to prefix */ @Override public void writeToText(TextWriterStream out, String label) { String name = getNameAutomatic(); if(name != null) { out.commentPrintLn("Cluster name: " + name); } out.commentPrintLn("Cluster noise flag: " + isNoise()); out.commentPrintLn("Cluster size: " + ids.size()); // also print model, if any and printable if(getModel() != null && (getModel() instanceof TextWriteable)) { ((TextWriteable) getModel()).writeToText(out, label); } } /** * Getter for noise flag. * * @return noise flag */ public boolean isNoise() { return noise; } /** * Setter for noise flag. * * @param noise new noise flag value */ public void setNoise(boolean noise) { this.noise = noise; } /** * A partial comparator for Clusters, based on their name. Useful for sorting * clusters. Do NOT use in e.g. a TreeSet since it is * inconsistent with equals. */ public static Comparator> BY_NAME_SORTER = new Comparator>() { @Override public int compare(Cluster o1, Cluster o2) { if(o1 == o2) { return 0; } // sort by label if possible if(o1 != null && o1.name != null && o2 != null && o2.name != null) { int lblresult = o1.name.compareTo(o2.getName()); if(lblresult != 0) { return lblresult; } } int hashresult = o1.hashCode() - o2.hashCode(); if(hashresult != 0) { return hashresult; } return 0; } }; /** {@inheritDoc} */ @Override public String toString() { String mstr = (model == null) ? "null" : model.toString(); String nstr = noise ? ",noise" : ""; return "Cluster(size=" + size() + ",model=" + mstr + nstr + ")"; } }