2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
* & Matthias Schubert (schubert@dbs.ifi.lmu.de)
20
* & Zhanna Melnikova-Albrecht (melnikov@cip.ifi.lmu.de)
21
* & Rainer Holzmann (holzmann@cip.ifi.lmu.de)
24
package weka.clusterers.forOPTICSAndDBScan.DataObjects;
26
import weka.clusterers.forOPTICSAndDBScan.Databases.Database;
27
import weka.core.Attribute;
28
import weka.core.Instance;
29
import weka.core.Utils;
31
import java.io.Serializable;
35
* ManhattanDataObject.java <br/>
36
* Authors: Rainer Holzmann, Zhanna Melnikova-Albrecht, Matthias Schubert <br/>
37
* Date: Aug 19, 2004 <br/>
38
* Time: 5:50:22 PM <br/>
39
* $ Revision 1.4 $ <br/>
42
* @author Matthias Schubert (schubert@dbs.ifi.lmu.de)
43
* @author Zhanna Melnikova-Albrecht (melnikov@cip.ifi.lmu.de)
44
* @author Rainer Holzmann (holzmann@cip.ifi.lmu.de)
45
* @version $Revision: 1.3 $
47
public class ManhattanDataObject
48
implements DataObject, Serializable {
50
/** for serialization */
51
private static final long serialVersionUID = -3417720553766544582L;
54
* Holds the original instance
56
private Instance instance;
59
* Holds the (unique) key that is associated with this DataObject
64
* Holds the ID of the cluster, to which this DataObject is assigned
66
private int clusterID;
69
* Holds the status for this DataObject (true, if it has been processed, else false)
71
private boolean processed;
74
* Holds the coreDistance for this DataObject
76
private double c_dist;
79
* Holds the reachabilityDistance for this DataObject
81
private double r_dist;
84
* Holds the database, that is the keeper of this DataObject
86
private Database database;
88
// *****************************************************************************************************************
90
// *****************************************************************************************************************
93
* Constructs a new DataObject. The original instance is kept as instance-variable
94
* @param originalInstance the original instance
96
public ManhattanDataObject(Instance originalInstance, String key, Database database) {
97
this.database = database;
99
instance = originalInstance;
100
clusterID = DataObject.UNCLASSIFIED;
102
c_dist = DataObject.UNDEFINED;
103
r_dist = DataObject.UNDEFINED;
106
// *****************************************************************************************************************
108
// *****************************************************************************************************************
111
* Compares two DataObjects in respect to their attribute-values
112
* @param dataObject The DataObject, that is compared with this.dataObject
113
* @return Returns true, if the DataObjects correspond in each value, else returns false
115
public boolean equals(DataObject dataObject) {
116
if (this == dataObject) return true;
117
if (!(dataObject instanceof ManhattanDataObject)) return false;
119
final ManhattanDataObject manhattanDataObject = (ManhattanDataObject) dataObject;
121
if (getInstance().equalHeaders(manhattanDataObject.getInstance())) {
122
for (int i = 0; i < getInstance().numAttributes(); i++) {
123
double i_value_Instance_1 = getInstance().valueSparse(i);
124
double i_value_Instance_2 = manhattanDataObject.getInstance().valueSparse(i);
126
if (i_value_Instance_1 != i_value_Instance_2) return false;
134
* Calculates the manhattan-distance between dataObject and this.dataObject
135
* @param dataObject The DataObject, that is used for distance-calculation with this.dataObject
136
* @return double-value The manhattan-distance between dataObject and this.dataObject
137
* NaN, if the computation could not be performed
139
public double distance(DataObject dataObject) {
142
if (!(dataObject instanceof ManhattanDataObject)) return Double.NaN;
144
if (getInstance().equalHeaders(dataObject.getInstance())) {
145
for (int i = 0; i < getInstance().numAttributes(); i++) {
146
double cDistance = computeDistance(getInstance().index(i),
147
getInstance().valueSparse(i),
148
dataObject.getInstance().valueSparse(i));
149
dist += Math.abs(cDistance);
157
* Performs manhattan-distance-calculation between two given values
158
* @param index of the attribute within the DataObject's instance
161
* @return double norm-distance between value_1 and value_2
163
private double computeDistance(int index, double v, double v1) {
164
switch (getInstance().attribute(index).type()) {
165
case Attribute.NOMINAL:
166
return (Instance.isMissingValue(v) || Instance.isMissingValue(v1)
167
|| ((int) v != (int) v1)) ? 1 : 0;
169
case Attribute.NUMERIC:
170
if (Instance.isMissingValue(v) || Instance.isMissingValue(v1)) {
171
if (Instance.isMissingValue(v) && Instance.isMissingValue(v1))
174
return (Instance.isMissingValue(v)) ? norm(v1, index)
178
return norm(v, index) - norm(v1, index);
186
* Normalizes a given value of a numeric attribute.
188
* @param x the value to be normalized
189
* @param i the attribute's index
191
private double norm(double x, int i) {
192
if (Double.isNaN(database.getAttributeMinValues()[i])
193
|| Utils.eq(database.getAttributeMaxValues()[i], database.getAttributeMinValues()[i])) {
196
return (x - database.getAttributeMinValues()[i]) /
197
(database.getAttributeMaxValues()[i] - database.getAttributeMinValues()[i]);
202
* Returns the original instance
203
* @return originalInstance
205
public Instance getInstance() {
210
* Returns the key for this DataObject
213
public String getKey() {
218
* Sets the key for this DataObject
219
* @param key The key is represented as string
221
public void setKey(String key) {
226
* Sets the clusterID (cluster), to which this DataObject belongs to
227
* @param clusterID Number of the Cluster
229
public void setClusterLabel(int clusterID) {
230
this.clusterID = clusterID;
234
* Returns the clusterID, to which this DataObject belongs to
237
public int getClusterLabel() {
242
* Marks this dataObject as processed
243
* @param processed True, if the DataObject has been already processed, false else
245
public void setProcessed(boolean processed) {
246
this.processed = processed;
250
* Gives information about the status of a dataObject
251
* @return True, if this dataObject has been processed, else false
253
public boolean isProcessed() {
258
* Sets a new coreDistance for this dataObject
259
* @param c_dist coreDistance
261
public void setCoreDistance(double c_dist) {
262
this.c_dist = c_dist;
266
* Returns the coreDistance for this dataObject
267
* @return coreDistance
269
public double getCoreDistance() {
274
* Sets a new reachability-distance for this dataObject
276
public void setReachabilityDistance(double r_dist) {
277
this.r_dist = r_dist;
281
* Returns the reachabilityDistance for this dataObject
283
public double getReachabilityDistance() {
287
public String toString() {
288
return instance.toString();
291
// *****************************************************************************************************************
293
// *****************************************************************************************************************