package de.lmu.ifi.dbs.elki.distance.similarityfunction; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures Copyright (C) 2011 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.Iterator; import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.TreeSetDBIDs; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex; import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborPreprocessor; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; /** * SharedNearestNeighborSimilarityFunction with a pattern defined to accept * Strings that define a non-negative Integer. * * @author Arthur Zimek * * @apiviz.has * de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex * .Factory * @apiviz.uses Instance oneway - - «create» * * @param object type */ // todo arthur comment class public class FractionalSharedNearestNeighborSimilarityFunction extends AbstractIndexBasedSimilarityFunction, TreeSetDBIDs, DoubleDistance> implements NormalizedSimilarityFunction { /** * Constructor. * * @param indexFactory Index factory. */ public FractionalSharedNearestNeighborSimilarityFunction(SharedNearestNeighborIndex.Factory> indexFactory) { super(indexFactory); } @SuppressWarnings("unchecked") @Override public Instance instantiate(Relation database) { SharedNearestNeighborIndex indexi = indexFactory.instantiate((Relation) database); return (Instance) new Instance((Relation) database, indexi); } /** * Actual instance for a dataset. * * @author Erich Schubert * * @apiviz.uses SharedNearestNeighborIndex * * @param Object type */ public static class Instance extends AbstractIndexBasedSimilarityFunction.Instance, TreeSetDBIDs, DoubleDistance> { /** * Constructor. * * @param database Database * @param preprocessor Preprocessor */ public Instance(Relation database, SharedNearestNeighborIndex preprocessor) { super(database, preprocessor); } static protected int countSharedNeighbors(TreeSetDBIDs neighbors1, TreeSetDBIDs neighbors2) { int intersection = 0; Iterator iter1 = neighbors1.iterator(); Iterator iter2 = neighbors2.iterator(); DBID neighbors1ID = iter1.hasNext() ? iter1.next() : null; DBID neighbors2ID = iter2.hasNext() ? iter2.next() : null; while(neighbors1ID != null && neighbors2ID != null) { if(neighbors1ID.equals(neighbors2ID)) { intersection++; neighbors1ID = iter1.hasNext() ? iter1.next() : null; neighbors2ID = iter2.hasNext() ? iter2.next() : null; } else if(neighbors2ID.compareTo(neighbors1ID) > 0) { neighbors1ID = iter1.hasNext() ? iter1.next() : null; } else // neighbors1ID > neighbors2ID { neighbors2ID = iter2.hasNext() ? iter2.next() : null; } } return intersection; } @Override public DoubleDistance similarity(DBID id1, DBID id2) { TreeSetDBIDs neighbors1 = index.getNearestNeighborSet(id1); TreeSetDBIDs neighbors2 = index.getNearestNeighborSet(id2); int intersection = countSharedNeighbors(neighbors1, neighbors2); return new DoubleDistance((double) intersection / index.getNumberOfNeighbors()); } @Override public DoubleDistance getDistanceFactory() { return DoubleDistance.FACTORY; } } @Override public DoubleDistance getDistanceFactory() { return DoubleDistance.FACTORY; } /** * Parameterization class. * * @author Erich Schubert * * @apiviz.exclude * * @param object type */ public static class Parameterizer extends AbstractIndexBasedSimilarityFunction.Parameterizer>> { @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); configIndexFactory(config, SharedNearestNeighborIndex.Factory.class, SharedNearestNeighborPreprocessor.Factory.class); } @Override protected FractionalSharedNearestNeighborSimilarityFunction makeInstance() { return new FractionalSharedNearestNeighborSimilarityFunction(factory); } } }