代码之家  ›  专栏  ›  技术社区  ›  Daved

java中的算法比较:测试程序不起作用

  •  0
  • Daved  · 技术社区  · 12 年前

    我试图比较QuickSort的java实现及其混合版本的执行情况(对那些小于整数k的分区使用InsertionSort)。我写了一个测试类来分析一些值ok k(1<=k<=25)的算法行为。对于k的每个值,该类针对不同大小的输入数组比较这两种算法。

    对于数组大小的某些值,例如大于4000的值,我无法运行该程序。执行达到一些不同的值,然后冻结,过一段时间就会结束,但我没有计算的输出。(我正在使用eclipse)。
    可能是什么问题?我希望对10到10000(至少)的数组大小执行两种算法的比较。
    代码如下所示:

    public class Main {
    
    private static final int MAX_K = 25;
    private static final int MAX_SIZE = 4500;
    private static final int ADD_SIZE = 100;
    private static int size = 10;
    
    private static QuickSort qSort;
    private static HybridSort hSort;
    
    private static void initArray(int[] A) {
        Random rand = new Random();
        for (int i = 0; i < A.length; i++) {
            // A[i] = (int)(Math.random()*100000);
            A[i] = rand.nextInt();
    
        }
    }
    
    private static int[] A = new int[10];
    private static int[] B = new int[10];
    
    public static void main(String[] args) {
    
        try {
    
            FileWriter fstream = new FileWriter("out.txt");
            BufferedWriter out = new BufferedWriter(fstream);
            out.write("Init file");
    
            qSort = new QuickSort();
            hSort = new HybridSort();
    
            /************************************************/
            /* Comparison */
            /************************************************/
    
            for (int i = 1; i <= MAX_K; i++) {
                hSort.setK(i);
    
                int p = 0;
                for (int j = size; j <= MAX_SIZE; j = j + ADD_SIZE) {
    
                    A = new int[j];
                    B = new int[j];
                    initArray(A);
                    initArray(B);
    
                    long sTime = System.nanoTime();
                    qSort.quickSort(A, 0, A.length - 1);
                    long qDuration = System.nanoTime() - sTime;
    
                    sTime = System.nanoTime();
                    hSort.hybridSort(B, 0, B.length - 1);
                    long hDuration = System.nanoTime() - sTime;
    
                    out.append(/* "\nA: " +printArray(A)+ */"K: " + i + " A["
                            + j + "]\tQ = " + qDuration + " H = " + hDuration
                            + "\n");
    
                    String h = Long.toString(hDuration);
                    String q = Long.toString(qDuration);
    
                    if (h.length() < q.length()) {
                        p++;
                        out.append("\t#OUTPERM for K: "
                                + i
                                + "\t\t"
                                + hDuration
                                + "\t\t < \t\t "
                                + qDuration
                                + "\t\t\t\t| A[]\t\t"
                                + A.length
                                + ((q.length() - h.length()) == 2 ? "\t Magn. 2"
                                        : "") + "\n");
                    }
                }
                if (p > 0)
                    out.append("#P= " + p + " for K= " + i + "\n\n");
            }
            out.append("Close file");
            out.close();
        } catch (IOException e) {
    
        }
    }
    
    }
    

    算法类别:

    public class QuickSort {
    
    
    public void quickSort(int[] A, int left, int right){
        if (left < right) {
            int m = Partition(A, left, right);
            quickSort(A, left, m-1);
            quickSort(A, m, right);
        }
    }
    
    
    private int Partition(int[] A, int left, int right){
        int pivot = A[right];
        int i = left;
        int j = right;
    
        while (true) {
            while ( (A[j] > pivot)) {
                j--;
            }
            while ((A[i] < pivot)) {
                i++;
            }
            if (i < j){
                int swap = A[j];
                A[j] = A[i];
                A[i] = swap;
            }else{
                return i;
            }
        }
    }
    
    }
    


    public class HybridSort {
    
    int k;
    int m;
    InsertionSort iSort;
    
    public HybridSort() {
        k = 3;
        iSort = new InsertionSort();
    }
    
    public void hybridSort(int[] A, int left, int right) {
        if (left < right) {
            if ((right - left) < k) {
                                        iSort.sort(A,left,right);
            } else {                
                m = Partition(A, left, right);
                hybridSort(A, left, m - 1);
                hybridSort(A, m, right);
            }
        }
    }
    
    private int Partition(int[] A, int left, int right) {
        int pivot = A[right];
        int i = left;
        int j = right;
    
        while (true) {
            while ((A[j] > pivot) && (j >= 0)) {
                j--;
            }
            while ((A[i] < pivot) && (i < A.length)) {
                i++;
            }
            if (i < j) {
                int swap = A[j];
                A[j] = A[i];
                A[i] = swap;
            } else {
                return i;
            }
        }
    }
    
    
    public void setK(int k) {
        this.k = k;
    }
    }
    
    3 回复  |  直到 12 年前
        1
  •  0
  •   Vincent van der Weele    12 年前

    您对 Partition 不正确。考虑下面的小测试(我做了 隔断 static 为了我的方便)。

    二者都 while 循环不会被执行,因为 A[i] == A[j] == pivot 此外 i<j ,因此这两个元素将被交换,从而产生完全相同的数组。因此 虽然 循环变得无限。

    对于第一个元素和最后一个元素相同的任何数组,都会出现同样的问题。

    public class Test {
        public static void main(String[] args) {
            int[] A = {1, 1};
            Partition(A, 0, 1);
        }
    
        private static int Partition(int[] A, int left, int right){
            int pivot = A[right];
            int i = left;
            int j = right;
    
            while (true) {
                while ( (A[j] > pivot)) {
                    j--;
                }
                while ((A[i] < pivot)) {
                    i++;
                }
                if (i < j){
                    int swap = A[j];
                    A[j] = A[i];
                    A[i] = swap;
                }else{
                    return i;
                }
            }
        }
    }
    
        2
  •  0
  •   Community CDub    7 年前

    您是否尝试过增加代码在eclipse中运行的内存设置。 你可能会发现这个 Setting memory of Java programs that runs from Eclipse 有用的

        3
  •  0
  •   Community CDub    4 年前

    一些提示/可能的解决方案?:

    我还没有读过你的QuickSort或HybridSort的实现,但我认为它们是正确的。

    1. 如果你在比较两种算法的性能,你应该将它们的性能与相同的输入进行比较。目前,您正在生成两个随机arry(尽管大小相同)。这不一定是一个准确的测试,因为我可以很容易地找到一个测试案例,如果随机生成器要攻击你,一种算法会优于另一种算法。

    2. 根据我的说法,你比较这两种算法的逻辑有点奇怪和不正确。你为什么要比较时间的字符串长度?根据您的逻辑,1与9相同,1000000000与9999999999相同,这显然是不正确的。一种算法几乎比另一种算法快10倍。

    3. 此外,没有输出的一个原因可能是,只有当hybridsort比quicksort更好时才输出,而不是相反。我相信还有其他原因,但这可能是一个容易引起注意的原因(如果您的实现不正确)。

      我确实注意到你关闭了输出流,这很好,因为这是没有输出的一个常见原因。然而,你应该关闭 finally 尝试接球的部分,因为这样他们就可以保证闭合。您可能会得到一个IOException,在您的情况下,这也不会关闭输出团队,从而导致文件中没有输出。

    这是一个样本结构,我将遵循它进行任何比较测试。它很容易阅读,也很容易调试,有足够的输出供您确定哪种算法性能更好。这只是一个建议。

    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.PrintWriter;
    import java.util.Random;
    
    public class Tester {
    
      private static int[] initArray(int size) {
        Random rand = new Random();
        int[] arr = new int[size];
        for (int i = 0; i < arr.length; i++) {
          arr[i] = rand.nextInt();
        }
        return arr;
      }
    
      public static void main(String[] args) {
        final int MAX_ITERATIONS = 25;
        final int INITIAL_ARRAY_SIZE = 10;
        final int MAX_ARRAY_SIZE = 4500;
        final int ARRAY_SIZE_INCREMENT = 100;
    
        long start;
        int[] score = null;
    
        PrintWriter out = null;
        try {
          out = new PrintWriter(new FileOutputStream("out.txt"));
          for (int arraySize = INITIAL_ARRAY_SIZE; arraySize <= MAX_ARRAY_SIZE; arraySize += ARRAY_SIZE_INCREMENT) {
            // score[0] is for quickSort and score[1] is for hybridSort
            score = new int[2];
            for (int iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
              int[] testArray = initArray(arraySize);
              int[] testArrayCopy = new int[arraySize];
              System.arraycopy(testArray, 0, testArrayCopy, 0, arraySize);
    
              start = System.nanoTime();
              // Do quicksort here using testArray
              long qSortfinish = System.nanoTime() - start;
    
              System.arraycopy(testArray, 0, testArrayCopy, 0, arraySize);
              start = System.nanoTime();
              // Do hybridsort here using testArrayCopy
              long hybridSortfinish = System.nanoTime() - start;
    
              // Keep score
              if (qSortfinish < hybridSortfinish)
                score[0]++;
              else if (qSortfinish > hybridSortfinish) {
                score[1]++;
              } else {
                score[0]++;
                score[1]++;
              }
            }
            out.println("Array Size: " + arraySize + " QuickSort: " + score[0] + " HybridSort: " + score[1]);
          }
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } finally {
          if (out != null)
            out.close();
        }
      }
    }