2016-03-29 7 views
1

次のコードは、最も近いペアの検出をシミュレートしますが、250を超えるペアのランダムな量を生成すると、スタックオーバーフローエラーがスローされます。しかし、250ペアと下の任意の額は正常に動作するようです。何か案は?スタックオーバーフローエラーが発生するのはなぜですか?

ifステートメントの下にあるComparePointsの再帰呼び出しでエラーが発生します。

public class Divide { 

    Point2D closest1; 
    Point2D closest2; 
    double Distance = Double.MAX_VALUE; 

    public Divide(Point2D[] RandArray){ 
     SortArray s = new SortArray(); 
     RandArray = s.SortPointsX(RandArray); 
     SplitAndConquer(RandArray); 
    } 

    private double ComparePoints(Point2D a, Point2D b, Point2D[] s, 
       int CurrentPoint, int NextPoint){ 
      if(s[CurrentPoint] != null && s[NextPoint] != null){ 
       if (Distance > a.distance(b) && 
         (a.getX() != b.getX() || a.getY() != b.getY())){ 
        Distance = a.distance(b); 
        closest1 = new Point2D.Double(a.getX(), a.getY()); 
        closest2 = new Point2D.Double(b.getX(), b.getY()); 
       } 
       if (NextPoint == (s.length - 1)){ 
        NextPoint = s.length - ((s.length - 1) - CurrentPoint); 
        CurrentPoint++; 
       } 
       if (CurrentPoint != (s.length - 1)){ 
        if (NextPoint != (s.length - 1)){ 
        NextPoint++; 
        ComparePoints(s[CurrentPoint], s[NextPoint], 
          s, CurrentPoint, NextPoint); 
        } 
       } 
       if (CurrentPoint == (s.length - 1)){ 
        CurrentPoint = 0; 
        NextPoint = 0; 
       } 
      } 
     return Distance; 
    } 

    private void SplitAndConquer(Point2D[] RandArray){ 
     double median = RandArray[RandArray.length/2].getX(); 
     int countS1 = 0; 
     int countS2 = 0; 
     boolean exact = false; 
     int CurrentPoint = 0; 
     int NextPoint = 0; 
     Point2D[] s1 = new Point2D[RandArray.length/2]; 
     Point2D[] s2 = new Point2D[RandArray.length/2]; 

     for (int i = 0; i < RandArray.length; i++){ 

      if (RandArray[i].getX() < median){ 
       s1[countS1] = RandArray[i]; 
       countS1++; 
      } 
      else if (RandArray[i].getX() > median){ 
       s2[countS2] = RandArray[i]; 
       countS2++; 
      } 
      else if (RandArray[i].getX() == median && exact == false){ 
       s2[countS2] = RandArray[i]; 
       exact = true; 
       countS2++; 
      } 
      else if (RandArray[i].getX() == median && exact == true) { 
       s1[countS1] = RandArray[i]; 
       exact = false; 
       countS2++; 
      } 
     } 

     if (s1[0] != null && s1[1] != null){ 
      Distance = ComparePoints(s1[0], s1[1], s1, 
        CurrentPoint, NextPoint); 
      Distance = ComparePoints(s2[0], s2[0], s2, 
        CurrentPoint, NextPoint); 
      }else{ 
       System.out.println 
       ("One of the subsets does not contain enough points!"); 
      } 
     CheckMid(RandArray, Distance, median, CurrentPoint, NextPoint); 
     PrintClosest(); 
     } 

    private void PrintClosest() { 
     System.out.println("The closest pair found using Divide " 
       + "And Conquer is at (" 
       + closest1.getX() + " " + closest1.getY() + "), and (" 
       + closest2.getX() + " " + closest2.getY() + ")"); 
     System.out.println("The distance between the pairs is: " + Distance); 

    } 

    private void CheckMid(Point2D[] randArray, double d, double m, 
      int current, int next) { 
     int MidCount = 0; 
     Point2D[] MidArray = new Point2D[randArray.length]; 
     for(int i = 0; i < randArray.length; i++){ 
      if(randArray[i].getX() > (m - d) && 
        randArray[i].getX() < (m + d)){ 
       MidArray[MidCount] = randArray[i]; 
       MidCount++; 
      } 
     } 
     if (MidArray[0] != null && MidArray[1] != null){ 
     ComparePoints(MidArray[0], MidArray[1], MidArray, 
       current, next); 
     } 
    } 
} 
+0

"しかし、250を超えるペアのランダムな量を生成すると、スタックオーバーフローエラーが発生します。" - スタックはすべて有限のサイズです。サイズを大きくするかアルゴリズムを変更します。 –

+0

私はアルゴリズムを変更しようとしたいと思いますが、どうすればいいのか分かりません。 –

答えて

1

あなたのプログラムに割り当てられているスタックメモリの容量を超えているようですね。 -Xssオプションを使用してスタックサイズを変更できます。たとえば、スタックサイズを8MBに変更してプログラムを実行するには、java -Xss 8Mを使用します。

+0

プログラムを変更してスタックサイズを変更せずに、より多くの再帰呼び出しを処理する方法はありますか? –

0

内部的にJavaには、メソッド呼び出しをスタックフレームとして格納するコールスタックがあります。そして、これらのメソッド呼び出し(フレーム)をLIFO方式で処理します。 新しいスレッドが作成されると(あなたの場合はメインスレッド)、一定量のスタックとヒープメモリがそのスレッドに割り当てられます。 したがって、コールスタックが使い果たされるたびに、スタックオーバーフローエラーが発生します。 再帰呼び出しの数が呼び出しスタックのサイズを超えているため、エラーが発生しています。

関連する問題