/***********************************************************************
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.MCA;
import keel.Algorithms.Instance_Generation.Basic.PrototypeSet;
import keel.Algorithms.Instance_Generation.Basic.Prototype;
import keel.Algorithms.Instance_Generation.*;
import keel.Algorithms.Instance_Generation.PNN.*;
import keel.Algorithms.Instance_Generation.utilities.KNN.*;
import keel.Algorithms.Instance_Generation.utilities.*;
import java.util.*;
//import keel.Dataset.Instance;
/**
Prototype that implements comparator. It is used for sorting.
*/
class PairOfPrototypes implements Comparable<PairOfPrototypes>
{
Pair<Prototype,Prototype> pair;
double distance;
double label;
public double getDistance() { return distance; }
public double getLabel() { return label; }
public Pair<Prototype, Prototype> getPair() { return pair; }
public PairOfPrototypes(Prototype one, Prototype two)
{
pair = new Pair<Prototype,Prototype>(one,two);
distance = Distance.d(one, two);
label = one.label();
}
@Override
public int compareTo(PairOfPrototypes other)
{
if(distance < other.distance)
return -1;
else if(distance == other.distance)
return 0;
return 1;
}
}
class SymmetricDistanceMatrix
{
ArrayList<ArrayList<Double>> matrix;
PrototypeSet original;
//! Position of each prototype in the superset (not in the partition)
//HashMap<Prototype,Integer> positionInSuperset;
public SymmetricDistanceMatrix()
{
matrix = new ArrayList<ArrayList<Double>>();
}
protected void updateDistances()
{
int _size = original.size();
matrix = new ArrayList<ArrayList<Double>>(_size);
for(int i=0; i<_size; ++i)
{
matrix.add(new ArrayList<Double>(_size-i));
for(int j=i+1; j<_size; ++j)
matrix.get(i).add(Distance.dSquared(original.get(i), original.get(j)));
}
}
public SymmetricDistanceMatrix(PrototypeSet V)
{
original = V;
updateDistances();
}
public double get(int i, int j)
{
double value = 0.0;
if(j > i)
value = matrix.get(i).get(j);
else if(j == i)
value = 0.0;
else if(j < i+1)
{
int tmp = j;
j = i;
i = tmp;
value = matrix.get(i).get(j);
}
return value;
}
// No debes hacer todos con todos, piensa algo
ArrayList<PairOfPrototypes> sortByNearness()
{
ArrayList<PairOfPrototypes> pairs = new ArrayList<PairOfPrototypes>();
int _size = original.size();
for(int i=0; i<_size; ++i)
for(int j=0; j<_size; ++j)
if(i!=j)
pairs.add(new PairOfPrototypes(original.get(i),original.get(j)));
Collections.sort(pairs);
//ArrayList<Pair<Prototype,Prototype>> sortedPairs = new ArrayList<Pair<Prototype,Prototype>>();
//for(PairOfPrototypes p : pairs)
// sortedPairs.add(p.getPair());
return pairs;
}
boolean remove(Prototype p)
{
boolean removed = false;
int index = original.indexOf(p);
int _size = original.size();
if(index > -1 && index < _size)
{
original.remove(index);
removed = true;
}
return removed;
}
boolean remove(Prototype p, boolean makeUpdate)
{
boolean removed = false;
int index = original.indexOf(p);
int _size = original.size();
if(index > -1 && index < _size)
{
original.remove(index);
if(makeUpdate)
updateDistances();
removed = true;
}
/* for (int i = 0; i < _size; ++i)
for (int j = i + 1; j < _size; ++j)
{
if(i == index)
{
matrix.remove(i);
removed = true;
//++counter;
}
else if(j == index)
{
matrix.get(i).remove(j);
removed = true;
//++counter;
}
}*/
return removed;
}
}
/**
*
* @author diegoj
*/
public class DistanceMatrixByClass
{
//Para cada clase hay una matriz de distancias
HashMap<Double,SymmetricDistanceMatrix> matrix = new HashMap<Double,SymmetricDistanceMatrix>();
public DistanceMatrixByClass(PrototypeSet V)
{
ArrayList<Double> labels = Prototype.possibleValuesOfOutput();
for(double label : labels)
{
PrototypeSet pLabelSet = V.getFromClass(label);
if(!pLabelSet.isEmpty())
matrix.put(label, new SymmetricDistanceMatrix(pLabelSet));
}
}
boolean containsLabel(double label)
{
return matrix.containsKey(label);
}
public ArrayList<Double> labels()
{
ArrayList<Double> presLabels = new ArrayList<Double>();
ArrayList<Double> labels = new ArrayList<Double>(matrix.keySet());
for(double label : labels)
if(containsLabel(label))
presLabels.add(label);
return presLabels;
}
private ArrayList<PairOfPrototypes> sortByNearness(double label)
{
SymmetricDistanceMatrix pSet = matrix.get(label);
ArrayList<PairOfPrototypes> sorted = pSet.sortByNearness();
return sorted;
}
/**
* Returns the nearest prototype for each class in the set.
* @return Hash with associations class, list with pairs of prototypes of each class sorted by distance between them.
*/
//Hashmap de clases -> lista de pares para esa clase, ordenados de más cercanía a menor cercanía
public HashMap<Double,ArrayList<Pair<Prototype,Prototype>>> nearnestPrototypesForEachClass()
{
ArrayList<Double> labels = labels();
HashMap<Double,ArrayList<Pair<Prototype,Prototype>>> n = new HashMap<Double,ArrayList<Pair<Prototype,Prototype>>>();
for(double label : labels)
{
ArrayList<PairOfPrototypes> pLabel = sortByNearness(label);
ArrayList<Pair<Prototype,Prototype>> goodPLabel = new ArrayList<Pair<Prototype,Prototype>>(pLabel.size());
n.put(label, goodPLabel);
for(PairOfPrototypes p : pLabel)
goodPLabel.add(p.getPair());
}
return n;
}
public boolean remove(Prototype p, boolean makeUpdate)
{
double pLabel = p.label();
SymmetricDistanceMatrix m = matrix.get(pLabel);
return m.remove(p, makeUpdate);
}
public boolean remove(Prototype p)
{
double pLabel = p.label();
SymmetricDistanceMatrix m = matrix.get(pLabel);
return m.remove(p);
}
}