/* * Copyright (C) Justo Montiel, David Torres, Sergio Gomez, Alberto Fernandez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * <http://www.gnu.org/licenses/> */ package methods; import utils.PrecDouble; import definicions.Cluster; import definicions.MatriuDistancies; /** * <p> * <b>MultiDendrograms</b> * </p> * * Abstract class for the different clustering methods available * * @author Justo Montiel, David Torres, Sergio Gómez, Alberto Fernández * * @since JDK 6.0 */ public abstract class Method { Cluster cI, cJ; MatriuDistancies mdAct; public Method(final Cluster ci, final Cluster cj, final MatriuDistancies md) { cI = ci; cJ = cj; mdAct = md; } public double Distancia() throws Exception { return this.calculaDistanciaIJ(); } private double calculaDistanciaIJ() throws Exception { PrecDouble dist, dl, alfa, beta, tmp; tmp = new PrecDouble("0.0"); if (mdAct.existDistance(cI, cJ)) { dist = new PrecDouble(mdAct.getDistancia(cI, cJ)); } else { if (cI.isNado() && cJ.isNado()) { for (int i = 0; i < cI.getFamily(); i++) { for (int j = 0; j < cJ.getFamily(); j++) { dl = new PrecDouble(mdAct.getDistancia(cI.getFill(i), cJ.getFill(j))); alfa = new PrecDouble(this.getAlfa_ij(cI.getFill(i), cJ.getFill(j))); alfa.Producto(dl); tmp.Suma(alfa); } } } else { if (cI.isNado()) { for (int i = 0; i < cI.getFamily(); i++) { dl = new PrecDouble(mdAct.getDistancia(cI.getFill(i), cJ)); alfa = new PrecDouble( this.getAlfa_ij(cI.getFill(i), cJ)); alfa.Producto(dl); tmp.Suma(alfa); } } else { for (int j = 0; j < cJ.getFamily(); j++) { dl = new PrecDouble(mdAct.getDistancia(cJ.getFill(j), cI)); alfa = new PrecDouble( this.getAlfa_ij(cJ.getFill(j), cI)); alfa.Producto(dl); tmp.Suma(alfa); } } } dist = tmp.clone(); if (cI.isNado()) { tmp = new PrecDouble("0.0"); for (int i = 0; i < cI.getFamily() - 1; i++) { for (int ii = i + 1; ii < cI.getFamily(); ii++) { beta = new PrecDouble(this.getBeta_ii(cI.getFill(i), cI.getFill(ii))); beta.Producto(mdAct.getDistancia(cI.getFill(i), cI.getFill(ii))); tmp.Suma(beta); } } dist.Suma(tmp); } if (cJ.isNado()) { tmp = new PrecDouble("0.0"); for (int j = 0; j < cJ.getFamily() - 1; j++) { for (int jj = j + 1; jj < cJ.getFamily(); jj++) { beta = new PrecDouble(this.getBeta_jj(cJ.getFill(j), cJ.getFill(jj))); beta.Producto(mdAct.getDistancia(cJ.getFill(j), cJ.getFill(jj))); tmp.Suma(beta); } } dist.Suma(tmp); } dist.Suma(this.CalculLinkage()); } return dist.parserToDouble(); } protected abstract double CalculLinkage() throws Exception; protected abstract double getAlfa_ij(Cluster i, Cluster j); protected abstract double getBeta_ii(Cluster i, Cluster ii); protected abstract double getBeta_jj(Cluster j, Cluster jj); protected abstract double getGamma_ij(Cluster i, Cluster j); public Cluster getcI() { return cI; } public void setcI(final Cluster i) { cI = i; } public Cluster getcJ() { return cJ; } public void setcJ(final Cluster j) { cJ = j; } protected double getDistanciaMax(final Cluster ci, final Cluster cj) throws Exception { double max = Double.MIN_VALUE; double tmp; if (mdAct.existDistance(ci, cj)) { max = mdAct.getDistancia(ci, cj); } else if (ci.isNado() && cj.isNado()) { for (int i = 0; i < ci.getFamily(); i++) { for (int j = 0; j < cj.getFamily(); j++) { tmp = mdAct.getDistancia(ci.getFill(i), cj.getFill(j)); max = max < tmp ? tmp : max; } } } else if (ci.isNado()) { for (int i = 0; i < ci.getFamily(); i++) { tmp = mdAct.getDistancia(ci.getFill(i), cj); max = max < tmp ? tmp : max; } } else { for (int j = 0; j < cj.getFamily(); j++) { tmp = mdAct.getDistancia(cj.getFill(j), ci); max = max < tmp ? tmp : max; } } return max; } protected double getDistanciaMin(final Cluster ci, final Cluster cj) throws Exception { double min = Double.MAX_VALUE; double tmp; if (mdAct.existDistance(ci, cj)) { min = mdAct.getDistancia(ci, cj); } else if (ci.isNado() && cj.isNado()) { for (int i = 0; i < ci.getFamily(); i++) { for (int j = 0; j < cj.getFamily(); j++) { tmp = mdAct.getDistancia(ci.getFill(i), cj.getFill(j)); min = min > tmp ? tmp : min; } } } else if (ci.isNado()) { for (int i = 0; i < ci.getFamily(); i++) { tmp = mdAct.getDistancia(ci.getFill(i), cj); min = min > tmp ? tmp : min; } } else { for (int j = 0; j < cj.getFamily(); j++) { tmp = mdAct.getDistancia(cj.getFill(j), ci); min = min > tmp ? tmp : min; } } return min; } }