001/*
002 * Copyright (c) 2015-2020, Oracle and/or its affiliates. All rights reserved.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.tribuo.clustering;
018
019import org.tribuo.Model;
020import org.tribuo.Output;
021
022import java.util.Objects;
023
024/**
025 * A clustering id.
026 * <p>
027 * The id is an int, referring to a cluster stored in the model.
028 * Optionally contains a score representing the strength of association
029 * with that cluster, if available.
030 * <p>
031 * The id is {@link ClusterID#UNASSIGNED} if the output is not assigned to a
032 * cluster (e.g., before the {@link Model} has been trained).
033 */
034public class ClusterID implements Output<ClusterID> {
035    private static final long serialVersionUID = 1L;
036
037    public static final int UNASSIGNED = -1;
038
039    private final int id;
040
041    private final double score;
042
043    /**
044     * Creates a ClusterID with the sentinel score of {@link Double#NaN}.
045     * @param id The cluster id number.
046     */
047    public ClusterID(int id) {
048        this(id,Double.NaN);
049    }
050
051    /**
052     * Creates a ClusterID with the specified id number and score.
053     * @param id The cluster id number.
054     * @param score The score.
055     */
056    public ClusterID(int id, double score) {
057        this.id = id;
058        this.score = score;
059    }
060
061    /**
062     * Get a real valued score for this ClusterID.
063     * <p>
064     * If the score is not set then it returns Double.NaN.
065     * @return The predicted score for this cluster id.
066     */
067    public double getScore() {
068        return score;
069    }
070
071    /**
072     * Gets the cluster id number.
073     * @return A int.
074     */
075    public int getID() {
076        return id;
077    }
078
079    @Override
080    public boolean equals(Object o) {
081        if (this == o) return true;
082        if (!(o instanceof ClusterID)) return false;
083        ClusterID that = (ClusterID) o;
084        return id == that.id;
085    }
086
087    @Override
088    public int hashCode() {
089        return Objects.hash(id);
090    }
091
092    @Override
093    public boolean fullEquals(ClusterID o) {
094        if (this == o) return true;
095
096        if ((!(Double.isNaN(o.score) && Double.isNaN(score))) && (Double.compare(o.score, score) != 0)) return false;
097        return id == o.id;
098    }
099
100    @Override
101    public String toString() {
102        if (Double.isNaN(score)) {
103            return ""+id;
104        } else {
105            return "("+id+","+score+")";
106        }
107    }
108
109    @Override
110    public ClusterID copy() {
111        return new ClusterID(id, score);
112    }
113
114    /**
115     * Returns "id" or "id,score=idScore".
116     * @param includeConfidence Include whatever confidence score the clusterID contains, if known.
117     * @return A string representing this ClusterID, suitable for csv or json serialization.
118     */
119    @Override
120    public String getSerializableForm(boolean includeConfidence) {
121        if (includeConfidence && !Double.isNaN(score)) {
122            return id + ",score=" + score;
123        } else {
124            return ""+id;
125        }
126    }
127}