时间复杂性理论与线性搜索的实际实验不匹配

时间:2013-08-04 18:43:40

标签: java computer-science

我正在使用线性搜索算法,并且根据该算法的理论,其时间复杂度为O(n)。现在我必须使用实际代码证明这一点,并创建一个图表,证明算法实际上是O(n)。但是一些实际结果并没有表明这一点。

以下是我使用的编码方法:

  1. 我有一个循环,可以根据循环编号动态创建一个数组。
  2. 然后我用数字随机填充这个数组。
  3. 然后我实现了线性搜索算法。在算法运行之前,我记下时间,一旦找到我找到的值,我就停止时钟并保存时间,在循环结束时,我将值写入文本文件。
  4. 然后我将text'file导入excel并创建一个图表。但结果并未证实算法为O(n)
  5. 的事实

    这是我在java中的代码:

     public static void main(String[] args) 
        {
    
            long[] ArrayTimeTaken = new long[10000];
            String Display = "";
    
            //Code that runs the linear search
            for (int i = 2; i < 10000; i++) 
            {
                int[] arrayExperimentTest = new int[i];
                arrayExperimentTest = FillArray(i);
                int ValuetoSearchfor = Math.round(((arrayExperimentTest.length)/2));
                System.out.println(ValuetoSearchfor);
                ArrayTimeTaken[i] = LinearSearch(arrayExperimentTest,ValuetoSearchfor);
                Display = Display+ System.getProperty("line.separator") + ArrayTimeTaken[i]; 
    
            }
            PrintWriter writer;
            try {
                writer = new PrintWriter("C:/Users/Roberto/Desktop/testing.txt", "UTF-8");
                writer.println(Display);
                writer.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //ChartCreate(ArrayTimeTaken);  
            System.out.println("Done");
        }
    

    以下是使用随机数填充数组的代码和线性搜索:

     //This code simply populates our array with numbers in each of the array positions
        static int[] FillArray(int number)
        {
            int[] ArrayofValues = new int[number];
            for (int i = 0; i < number; i++) 
            {
                Random randomGenerator = new Random();
                boolean flag = true;
                while (flag) 
                {                
                    int index = randomGenerator.nextInt(number);
                    if (ArrayofValues[index] == 0)
                    {
                        ArrayofValues[index] = i;
                        flag = false;
                    }
                }
            }
            return ArrayofValues;
        }
    
        //This function does a linear search on an array with integers
        static long LinearSearch(int[] ArraySearch,int ValueFind)
        {
            long TimeTaken = 0;
            long startTime = System.currentTimeMillis();
            System.gc();
    
            for (int i = 0; i < ArraySearch.length; i++) 
            {
                if (ArraySearch[i] == ValueFind) 
                {
                    TimeTaken = System.currentTimeMillis() - startTime;
                    break;
                }
    
            }
            return TimeTaken;
    
        }
    

    以下是结果图表。我不应该得到直线图吗? enter image description here

2 个答案:

答案 0 :(得分:4)

您无法推断单次运行的结果。使用Google Caliper之类的东西来正确地进行微基准测试,这将为您生成各种有用的指标(标准偏差等),以及许多重要的技术内容(使JVM热身,因此可能优化字节码)。

除了assylias的回答 - 做IO可能会对您的结果产生巨大影响。在没有图形用户界面且运行服务数量最少的操作系统上运行也是一种很好的做法。

阅读Caliper wiki获取最佳做法微工程标记并查看source for examples

修改:对于版本1.0-beta-1,请检查此branch for examples,API正在更改且主文件与文档不符)

答案 1 :(得分:1)

您的测试方法存在一些问题,但主要是:

  • System.currentMillis()的分辨率不是很好,所以考虑到你的结果都是12毫秒,我不相信他们
  • 在测量期间运行完整的GC ,这没有任何意义:GC本身可能需要几毫秒

所以:

  • 使您的阵列显着增大 - 您可以运行大小从10,000到10,000,000的测试,例如以10,000为增量
  • long startTime = System.currentTimeMillis();
  • 之前将GC移至