0

我在比较双打时遇到问题。比较负责停止一段时间循环。代码运行良好,但突然之间,循环永远不会停止。来自 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();
}

}

4

3 回答 3

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))。

于 2013-04-03T08:45:42.900 回答
1

由于double绝大多数现代处理器都处理浮点数(是双精度浮点数),因此对它们执行操作很少能得到准确的值。

所以你基本上有选择。在比较之前对您的值进行四舍五入,或者自己制定一些比较方法,以允许一些误差范围。

于 2013-04-03T08:46:29.543 回答
1

if(centroidList.get(i).dimVal.get(j) <--- 你确定那是返回一个双精度值吗?在打印出变量以检查它们的相等性时要注意。它们的字符串表示并不总是相同的作为他们的平等代表。

于 2013-04-03T08:49:01.067 回答