0

double の比較に問題があります。比較は、while サイクルを停止する役割を果たします。コードは正常に実行されますが、突然サイクルが停止しません。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

コンピューター メモリ (float、double) での 10 進数の表現のため、それらを直接比較しないでください。デルタを使用する必要があります。

  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 に答える