我在比较双打方面遇到了问题。比较负责停止一段时间。代码运行正常,但突然之间,循环永远不会停止。将来自centroidList的dimVal的值与计算的临时变量(粗体位)进行比较。代码总是输入if,如果我使用“!=”或“==”并不重要。打印出来的值,它们完全一样。有什么问题?
package clusters;
import java.util.LinkedList;
public class KMeansV2 {
LinkedList<Record> table;
LinkedList<Centroid> centroidList;
LinkedList<Double> intervalList;
boolean clusterStop;
int meassureType;
int prec=10000000;
KMeansV2()
{
Read read=new Read(true,"BrCa_HD_full.xlsx");
table=new LinkedList<Record>(read.table);
centroidList=new LinkedList<Centroid>();
CreateCentroids(2);
SetMeassureType(1);
while(clusterStop==false)
{
UpdateRecords();
UpdateClusters();
}
Output();
}
public void SetMeassureType(int meassureType)
{
this.meassureType=meassureType;
}
public void CreateCentroids(int centroidCount)
{
if(centroidList.isEmpty())
{
for(int i=0;i<centroidCount;i++)
{
centroidList.add(new Centroid(table.get(0).values.size(),i));
}
}
else
{
centroidList.clear();
for(int i=0;i<centroidCount;i++)
{
centroidList.add(new Centroid(table.get(0).values.size(),i));
}
}
}
public void UpdateRecords()
{
for(int i=0;i<table.size();i++)
{
table.get(i).Update(centroidList, meassureType);
}
}
public void UpdateClusters()
{
clusterStop=true;
for(int i=0;i<centroidList.size();i++) //staiga pa centroidiem
{
for(int j=0;j<table.get(0).values.size();j++) //staiga pa kolonnam
{
double sum=0;
double count=0;
for(int k=0;k<table.size();k++) //staiga pa rindam
{
if(centroidList.get(i).type==table.get(k).type)
{
sum+=table.get(k).values.get(j);
count++;
}
}
System.out.println(clusterStop);
double temp=(1/count)*sum;
**if(centroidList.get(i).dimVal.get(j)==temp);
{
System.out.println(centroidList.get(i).dimVal.get(j)+" != "+(1/count)*sum);
clusterStop=false;
}**
centroidList.get(i).dimVal.set(j,temp);
}
System.out.println(clusterStop);
}
}
public void Output()
{
LinkedList<String> types=new LinkedList<String>();
for(int i=0;i<table.size();i++)
{
if(!types.contains(table.get(i).realType))
{
types.add(table.get(i).realType);
}
}
for(int i=0;i<centroidList.size();i++) //staiga pa centroidiem
{
for(int j=0;j<types.size();j++) //staiga pa klasem
{
int count=0;
for(int k=0;k<table.size();k++) // staiga pa rindam
{
if(table.get(k).type==i && table.get(k).realType.equals(types.get(j)))
{
count++;
}
}
System.out.println("Centroid "+(i+1)+" has "+count+" of type "+types.get(j));
//kMeansUI.UpdateLog("Centroid "+(i+1)+" has "+count+" of type "+types.get(j));
}
}
for(int i=0;i<centroidList.size();i++)
{
int count=0;
for(int j=0;j<table.size();j++)
{
if(table.get(j).type==i)
{
count++;
}
}
System.out.println("Cluster "+i+" has "+count+" records.");
//kMeansUI.UpdateLog("Cluster "+(i+1)+" has "+count+" records.");
}
//kMeansUI.UpdateLog("/-------------------------------------------------------------------------/");
}
public static void main(String[] args)
{
KMeansV2 test=new KMeansV2();
}
}
答案 0 :(得分:6)
由于计算机内存(浮点数,双数)中十进制数的表示,你不应该直接比较它们 - 你应该使用增量:
double x = 123.123;
double y = 123.1234;
double delta = 0.01;
boolean areEqual = Math.abs(x - y) <= delta
但我强烈建议您使用其他适用的类型。也许在你的情况下integer
/ long
是合适的?如果不是,并且您需要精确的精度,请使用BigDecimal
类实例。还请记住用字符串构造它们。
关于控制台输出,java正在欺骗你(; - 它正在使用某种近似值(在内存中0.1几乎为'0.1,它更接近于0.(9))。
答案 1 :(得分:1)
由于浮点数(double
是双精度浮点数)由绝大多数现代处理器处理,因此对它们执行操作很少能获得精确值。
所以你基本上有选择权。要么在比较之前对你的值进行舍入,要么自己做一些比较方法,这允许一些误差范围。
答案 2 :(得分:1)
if(centroidList.get(i).dimVal.get(j)&lt; ---你确定那是返回一个double吗?在打印变量时要注意检查它们的相等性。它们的字符串表示是并不总是与他们的平等表示相同。