package CSVFileCon;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class CSVController {
ArrayList<String[]> saver=new ArrayList<String[]>();
ArrayList<double[]> datasaver=new ArrayList<double[]>();
protected int k=4;
public CSVController()
{
try {
BufferedReader reader = new BufferedReader(new FileReader("newCS455ASSIGN.csv")); //input file and save at saver
String line = null;
while((line=reader.readLine())!=null){
String item[] = line.split(",");
saver.add(item);
}
reader.close();
}
catch (Exception e)
{
e.printStackTrace();
}
dataFliter();
}
/**
* to find the max of data
*/
public double findmaxdata(){
ArrayList<Double> data=new ArrayList<Double>();
for(int i=0;i<datasaver.size();i++)
data.add(datasaver.get(i)[1]);
for(int i=0;i<data.size();i++)
for(int j=i;j<data.size();j++){
double temp=0;
if(data.get(i)<data.get(j)){
temp=data.get(j);
data.set(j, data.get(i));
data.set(i,temp);
}
}
return data.get(0);
}
/**
* to find the max of message charge
*/
public double findmaxmess(){
ArrayList<Double> data=new ArrayList<Double>();
for(int i=0;i<datasaver.size();i++)
data.add(datasaver.get(i)[0]);
for(int i=0;i<data.size();i++)
for(int j=i;j<data.size();j++){
double temp=0;
if(data.get(i)<data.get(j)){
temp=data.get(j);
data.set(j, data.get(i));
data.set(i,temp);
}
}
return data.get(0);
}
/**
* datafliter is used to flit out data what we want
* x=message,y=data
*/
public void dataFliter(){
int flag1=0;
int flag2=0;
String data1="Total message sent and received";
String data2="Total data used(MB)";
ArrayList<double[]> dataflit=new ArrayList<double[]>();
while(flag1<saver.get(0).length&&!saver.get(0)[flag1].equalsIgnoreCase(data1))
flag1++;
while(flag2<saver.get(0).length&&!saver.get(0)[flag2].equalsIgnoreCase(data2))
flag2++;
for(int i=1;i<saver.size();i++){
double[] n={Double.parseDouble(saver.get(i)[flag1]),Double.parseDouble(saver.get(i)[flag2])};
dataflit.add(n);
}
datasaver=dataflit;
}
/**
* ChoosePointsandFirstLoop return the first time loop ArrayList<ArrayList<double[]>>
* if flag=true, the method will auto choose 4 random center points
* @return
*/
public ArrayList<ArrayList<double[]>> ChoosePointsandFirstLoop(String flag){
ArrayList<double[]> looper=new ArrayList<double[]>(); // to save the clusters
ArrayList<ArrayList<double[]>> listForLoop=new ArrayList<ArrayList<double[]>>();//to save the lists of Clusters
Scanner input=new Scanner(System.in);
if(flag.equalsIgnoreCase("yes"))
{
for(int i=0;i<k;i++){ //choose 4 random points as starting point
Random ran=new Random();
int point=ran.nextInt(datasaver.size());
looper.add(datasaver.get(point));
}
}
else{
for(int i=0;i<k;i++){
System.out.println("Please enter the number of message you want:(message<=689) ");
double a=Double.parseDouble(input.nextLine());
System.out.println("Please enter the number of data you want:(data<781) ");
double b=Double.parseDouble(input.nextLine());
double[] point={a,b};
looper.add(point);
}
input.close();
System.out.println("----------the data you input has been accepted, please wait---------");
}
ArrayList<double[]> list0=new ArrayList<double[]>(); //The first list of cluster
list0.add(looper.get(0));
ArrayList<double[]> list1=new ArrayList<double[]>(); // the second list of cluster
list1.add(looper.get(1));
ArrayList<double[]> list2=new ArrayList<double[]>(); // the third list of cluster
list2.add(looper.get(2));
ArrayList<double[]> list3=new ArrayList<double[]>(); // the fourth list of cluster
list3.add(looper.get(3));
for(int j=0;j<datasaver.size();j++){
double dis0=distance(looper.get(0),datasaver.get(j));
double dis1=distance(looper.get(1),datasaver.get(j));
double dis2=distance(looper.get(2),datasaver.get(j));
double dis3=distance(looper.get(3),datasaver.get(j));
if(dis0<dis1&&dis0<dis2&&dis0<dis3)
list0.add(datasaver.get(j));
else if(dis1<dis0&&dis1<dis2&&dis1<dis3)
list1.add(datasaver.get(j));
else if(dis2<dis0&&dis2<dis1&&dis2<dis3)
list2.add(datasaver.get(j));
else if(dis3<dis0&&dis3<dis1&&dis3<dis2)
list3.add(datasaver.get(j));
else
list0.add(datasaver.get(j));
}
listForLoop.add(list0);
listForLoop.add(list1);
listForLoop.add(list2);
listForLoop.add(list3);
return listForLoop;
}
/**
* to calculate distance between 2 points
*
* ((x2-x1)/max)+((y2-y1)max)=dis
* it is unnecessary to use Math.sqr because dis can also compare the difference of distance
* @param list1
* @param list2
* @return
*/
public double distance(double[] point1, double[] point2){
double dis=Math.abs((point1[0]-point2[0]))/findmaxmess()+Math.abs((point1[1]-point2[1]))/findmaxdata();
return dis;
}
/**
* to calculate the sse of one cluster
* @param list
* @return
*/
public double SSECalForOneCluster(ArrayList<double[]> sublist){
double x=0;
double y=0;
double sse=0;
for(int j=0;j<sublist.size();j++){
x+=sublist.get(j)[0];
y+=sublist.get(j)[1];
}
double x_ave=x/sublist.size();
double y_ave=y/sublist.size();
double[] center={x_ave,y_ave};
for(int j=0;j<sublist.size();j++)
sse+=distance(center,sublist.get(j));
return sse;
}
/**
* To calculate the sum of SSE
* @param list
* @return
*/
public double SSECalculator(ArrayList<ArrayList<double[]>> list){
double sse=0.0;
for(int i=0;i<list.size();i++){
ArrayList<double[]> sublist=list.get(i);
double x=0;
double y=0;
for(int j=0;j<sublist.size();j++){
x+=sublist.get(j)[0];
y+=sublist.get(j)[1];
}
double x_ave=x/sublist.size();
double y_ave=y/sublist.size();
double[] center={x_ave,y_ave};
for(int j=0;j<sublist.size();j++){
sse+=distance(center,sublist.get(j));
}
}
return sse;
}
/**
* to calculate the similarity of objects
*/
public double calsimilar(double[] point1, double[] point2){
return Math.abs(1-distance(point1,point2));
}
/**
* this method is keeping loop classification
* @param looperlist
* @return
*/
public ArrayList<ArrayList<double[]>> AdjustLooper(ArrayList<ArrayList<double[]>> looperlist){
boolean change=true; //record if it is changed
ArrayList<ArrayList<double[]>> list=looperlist;
ArrayList<ArrayList<double[]>> finalresult=new ArrayList<ArrayList<double[]>>();
while(change==true)
{
ArrayList<ArrayList<double[]>> templist= new ArrayList<ArrayList<double[]>> ();
ArrayList<double[]> NewCenter=new ArrayList<double[]>();
ArrayList<double[]> list0=new ArrayList<double[]>();
ArrayList<double[]> list1=new ArrayList<double[]>();
ArrayList<double[]> list2=new ArrayList<double[]>();
ArrayList<double[]> list3=new ArrayList<double[]>();
for(int i=0;i<list.size();i++)
{
ArrayList<double[]> sublist=list.get(i);
double x=0;
double y=0;
for(int j=0;j<sublist.size();j++){
x+=sublist.get(j)[0];
y+=sublist.get(j)[1];
}
double x_ave=x/sublist.size();
double y_ave=y/sublist.size();
double[] center={x_ave,y_ave};
NewCenter.add(center);
}
for(int i=0;i<datasaver.size();i++){
double[] point0=NewCenter.get(0);
double[] point1=NewCenter.get(1);
double[] point2=NewCenter.get(2);
double[] point3=NewCenter.get(3);
double dis0=distance(point0,datasaver.get(i));
double dis1=distance(poin