/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package at.ac.tuwien.dsg.rSybl.learningEngine.advise.kMeans; import at.ac.tuwien.dsg.rSybl.learningEngine.utils.LearningLogger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import java.util.PriorityQueue; /** * * @author Georgiana */ public class Clustering { private ArrayList<NDimensionalPoint> points = new ArrayList<>(); private ArrayList<Cluster> clusters = new ArrayList<Cluster>(); public Clustering(){ } public void refresh(ArrayList<NDimensionalPoint> newPoints, int k, double cutoff){ points.addAll(newPoints); if (k>clusters.size()){ int oldSize = clusters.size(); for (int i=0;i<k-oldSize;i++){ Cluster newCluster = new Cluster(); newCluster.addPoint(newPoints.get(i)); newCluster.setCentroid(newPoints.get(i)); clusters.add(newCluster); } } double biggestShift= NDimensionalPoint.MAX_DIST; while (biggestShift>cutoff){ ArrayList<ArrayList<NDimensionalPoint>> lists = new ArrayList<ArrayList<NDimensionalPoint>>(); for (int i=0;i<clusters.size();i++){ lists.add(new ArrayList<NDimensionalPoint>()); } for (NDimensionalPoint nDimensionalPoint:points){ double smallestDistance = nDimensionalPoint.computeDistance(clusters.get(0).getCentroid()); int index=0; for (int i=1;i<clusters.size();i++){ double distance = nDimensionalPoint.computeDistance(clusters.get(i).getCentroid()); if (distance<smallestDistance){ smallestDistance=distance; index=i; } } lists.get(index).add(nDimensionalPoint); } biggestShift=0.0; for (int i=0;i<clusters.size();i++){ double shift = clusters.get(i).update(lists.get(i)); if (shift>biggestShift){ biggestShift=shift; } } } } public void initialize(ArrayList<NDimensionalPoint> points, int k, double cutoff){ this.points=points; for (int i=0;i<k;i++){ Cluster newCluster = new Cluster(); newCluster.addPoint(points.get(i)); newCluster.setCentroid(points.get(i)); clusters.add(newCluster); } double biggestShift= NDimensionalPoint.MAX_DIST; while (biggestShift>cutoff){ ArrayList<ArrayList<NDimensionalPoint>> lists = new ArrayList<ArrayList<NDimensionalPoint>>(); for (int i=0;i<clusters.size();i++){ lists.add(new ArrayList<NDimensionalPoint>()); } for (NDimensionalPoint nDimensionalPoint:points){ double smallestDistance = nDimensionalPoint.computeDistance(clusters.get(0).getCentroid()); int index=0; for (int i=1;i<clusters.size();i++){ double distance = nDimensionalPoint.computeDistance(clusters.get(i).getCentroid()); if (distance<smallestDistance){ smallestDistance=distance; index=i; } } lists.get(index).add(nDimensionalPoint); } biggestShift=-200000; for (int i=0;i<clusters.size();i++){ double shift = clusters.get(i).update(lists.get(i)); if (shift>biggestShift){ biggestShift=shift; } } } } public ArrayList<MyEntry<Double,NDimensionalPoint>> getClustersByDistance(NDimensionalPoint point){ ArrayList<MyEntry<Double,NDimensionalPoint>> orderedCluster = new ArrayList<> (); for (Cluster c:clusters){ // c.computeCentroidAsAverage(); double dist = NDimensionalPoint.MAX_DIST; NDimensionalPoint res = null; if (c.getCentroid()!=null && c.getClosestPoint(point).computeDistance(point,point.getValues().size())<dist){ // dist = c.computeDistance(point, point.getValues().size()); res=c.getClosestPoint(point); dist = res.computeDistance(point,point.getValues().size()); } if (orderedCluster.size()==0){ orderedCluster.add(new MyEntry<>(dist,res)); }else{ int x = -1; for (int i =0;i<orderedCluster.size();i++){ if (orderedCluster.get(i).getKey()<dist){ x=i; } } if (x==-1){ orderedCluster.add(0,new MyEntry<>(dist,res)); }else{ if (x+1<orderedCluster.size()) orderedCluster.add(x+1, new MyEntry<>(dist,res)); else orderedCluster.add(new MyEntry<>(dist,res)); } } } return orderedCluster; } public void addNewPointsAndRefreshClusters(ArrayList<NDimensionalPoint> newPoints, int k, double cutoff){ this.points.addAll(newPoints); for (int i=0;i<k;i++){ Cluster newCluster = new Cluster(); newCluster.addPoint(points.get(i)); } double biggestShift= NDimensionalPoint.MAX_DIST; while (biggestShift>cutoff){ ArrayList<ArrayList<NDimensionalPoint>> lists = new ArrayList<ArrayList<NDimensionalPoint>>(); for (int i=0;i<clusters.size();i++){ lists.add(new ArrayList<NDimensionalPoint>()); } for (NDimensionalPoint nDimensionalPoint:points){ double smallestDistance = nDimensionalPoint.computeDistance(clusters.get(0).getCentroid()); int index=0; for (int i=1;i<clusters.size();i++){ double distance = nDimensionalPoint.computeDistance(clusters.get(i).getCentroid()); if (distance<smallestDistance){ smallestDistance=distance; index=i; } } lists.get(index).add(nDimensionalPoint); } biggestShift=0.0; for (int i=0;i<clusters.size();i++){ double shift = clusters.get(i).update(lists.get(i)); if (shift>biggestShift){ biggestShift=shift; } } } } /** * @return the points */ public ArrayList<NDimensionalPoint> getPoints() { return points; } /** * @param points the points to set */ public void setPoints(ArrayList<NDimensionalPoint> points) { this.points = points; } /** * @return the clusters */ public ArrayList<Cluster> getClusters() { return clusters; } /** * @param clusters the clusters to set */ public void setClusters(ArrayList<Cluster> clusters) { this.clusters = clusters; } }