/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.es) J. Alcal�-Fdez (jalcala@decsai.ugr.es) S. Garc�a (sglopez@ujaen.es) A. Fern�ndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ **********************************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package keel.Algorithms.Instance_Generation.PNN; import keel.Algorithms.Instance_Generation.Basic.PrototypeSet; import keel.Algorithms.Instance_Generation.Basic.Prototype; import keel.Algorithms.Instance_Generation.*; import keel.Algorithms.Instance_Generation.utilities.KNN.*; import org.core.*; import java.util.*; import keel.Algorithms.Instance_Generation.utilities.*; /** * Matrix of distances between two sets of prototypes. */ public class MatrixOfDistances { /** One prototype set */ protected PrototypeSet A; /** Other prototype set */ protected PrototypeSet B; /** Prototypes added to the set, to be compared both A and B (it is not so much used) */ protected PrototypeSet orphans; /** Warehouse of distance between prototypes in A and prototypes in B */ protected HashMap<Prototype, HashMap<Prototype, Double> > matrix; //Para cada prototipo de B, un hashset de todos los prototipos que lo apuntan /** For each B-prototype, there is a hashset of all the others prototypes which point to it. */ protected HashMap<Prototype,HashSet<Prototype>> invertedBList; /** * Use d-squared, its faster than euclidean one. * @param a One prototype. * @param b Other prototype. * @return Distance between a and b. */ double d(Prototype a, Prototype b) { return Distance.dSquared(a,b); } /** * Construct a matrix of the distances between elements of the set A and B. * @param A One prototype set. * @param B Other prototype set. */ public MatrixOfDistances(PrototypeSet A, PrototypeSet B) { this.A = A; this.B = B; this.orphans = new PrototypeSet(); matrix = new HashMap<Prototype,HashMap<Prototype, Double>>(); invertedBList = new HashMap<Prototype,HashSet<Prototype>>(); for(Prototype b : B) invertedBList.put(b, new HashSet<Prototype>()); for(Prototype a : A) { matrix.put(a, new HashMap<Prototype, Double>()); for(Prototype b : B) if(a!=b) { invertedBList.get(b).add(a);//lista invertida de b a->b //matrix.get(a).put(b, Distance.d(a, b)); matrix.get(a).put(b, d(a, b)); } } } /** * Get the distance between two prototypes. * @param a A prototype. * @param b Other prototype. * @return Distance between a and b. */ public double get(Prototype a, Prototype b) { double dist = 0.0; //if(!a.equals(b)) //if(a!=b) //{ if(matrix.containsKey(a)) dist = matrix.get(a).get(b); else if(matrix.containsKey(b)) dist = matrix.get(b).get(a); else dist = -1.0;//used only for ours //} return dist; } /** * Remove a prototype to the matrix of distances. * @param a prototype to be erased. */ public boolean removeFromA(Prototype a) { boolean present = matrix.containsKey(a); if(present) matrix.remove(a); return present; } /** * Remove a prototype to the matrix of distances. * @param x prototype to be erased. * @return TRUE if it was removed, FALSE if not. */ public boolean removeFromB(Prototype x) { int _size = B.size(); boolean found = false; Prototype Bi = null; for (int i = 0; i < _size && !found; ++i) { Bi = B.get(i); found = (x == Bi); } if (found) { ArrayList<Prototype> list = new ArrayList<Prototype>(invertedBList.get(Bi)); for (Prototype p : list) matrix.get(p).remove(x); } return found; } /** * Remove a prototype to the matrix of distances. * @param x prototype to be erased. * @return TRUE if it was removed, FALSE if not. */ public boolean remove(Prototype x) { if(matrix.containsKey(x)) return removeFromA(x); else return removeFromB(x); //return false; } /** * Add a new prototype to the matrix of distances. * @param x New prototype to be added. */ public void add(Prototype x) { orphans.add(x); HashMap<Prototype, Double> xRow = new HashMap<Prototype, Double>(); matrix.put(x, xRow); for(Prototype a : A) if(x!=a) xRow.put(a, Distance.d(x, a)); for(Prototype b : B) if(x!=b && !xRow.containsKey(b)) //xRow.put(b, Distance.d(x, b)); xRow.put(b, d(x, b)); } /** * Add a new prototype to the matrix of distances (subset A). * @param x New prototype to be added to A set. */ public void addToA(Prototype x) { HashMap<Prototype, Double> xRow = new HashMap<Prototype, Double>(); matrix.put(x, xRow); for(Prototype b : B) if(x!=b && !xRow.containsKey(b)) //xRow.put(b, Distance.d(x, b)); xRow.put(b, d(x, b)); } /** * Add a new prototype to the matrix of distances (subset B). * @param x New prototype to be added to B set. */ public void addToB(Prototype x) { invertedBList.put(x,new HashSet<Prototype>()); HashMap<Prototype, Double> xRow = new HashMap<Prototype, Double>(); matrix.put(x, xRow); for(Prototype a : A) if(x!=a && !xRow.containsKey(a)) { //xRow.put(a, Distance.d(x, a)); xRow.put(a, d(x, a)); invertedBList.get(x).add(a); } } }//end-of-class