算法设计的要求
算法设计的要求
正确性
“正确”一词的含义在通常的用法中有很大的差别,大体上可分为以下4个层次:
- 程序不含语法错误。
- 程序对于几组输入数据得出满足规格说明要求的结果。
- 程序对于精心选择的典型、苛刻而带有发难性的几组输入数据能够得出满足规格说明要求的结果。
- 程序对于一切合法的输入数据都能产生满足规格说明要求的结果。
显然,达到第 4 层意义下的正确是极为困难的,所有不同输入数据的数量大得惊人,逐一验证的方法是不现实的。对于大型软件需要进行专业测试,而一般情况下,通常以第 3 层意义的正确性作为衡量一个程序是否合格的标准。
可读性
算法主要是为了人的阅读与交流,其次才是机器执行。可读性好有助于人对算法牟理解;晦涩难懂的程序易于隐藏较多错误,难以调试和修改。
健壮性
当输入数据非法时,算法也能适当地做出反应或进行处理,而不会产生黄晓明其妙的输出结果。例如,一个求凸多边形面积的算法,是采用求各三角形面积之和的策略来解决问题的。当输入的坐标集合表示的是一个凹多边形时,不应继续计算,而应报告输入出错。并且处理出错的方法应是返回一个表示错误或错误性质的值,而不是打印错误信息或异常,并中止程序的执行,以便在更高的抽象层次上进行处理。
效率与低存储量需求
通俗地说,效率指的是算法执行的时间。对于同一个问题如果有多个算法可以解决,执行时间短的算法效率高。存储量需求算法执行过程中所需要的最大存储空间。效率与低存储量需求这两者都与问题的规模有关。求 100 个人的平均分与求 1000 个人的平均分所花的执行时间或运行空间显然有一空差别。
算法效率的度量
算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量。而度量一个程序的执行时间通常有两种方法。
1) 事后统计的方法 因为很多计算机内部都有计时功能,有的甚至可精确到毫秒级,不同算法的程序可通过一组或若干组相同的统计数据以分辨优劣。但这种方法有两个缺陷:一是必须先运行依据算法编制的程序;二是所得时间的统计量依赖于计算机的硬件、软件等环境因素,有时容易掩盖算法本身的优劣。因此人们采用另一种事前分析估算的方法。
2)事前分析估算的方法 一个用高级程序语言编写的程序在计算机上运行时所消耗的时间取决于下列因素:
- 依据的算法选用何种策略。
- 问题的规模,例如求 100 以内还是还是 1000 以内的素数。
- 书写程序的语言,对于同一个算法,实现语言的级别越高,执行效率就越低。
- 编译程序所产生的机器代码的质量。
- 机器执行指令的速度。
显然,同一个算法用不同的语言实现,或者用不同的编译器进行编译,或者在不同的计算机运行时,效率均不相同。这表明使用绝对的时间单位衡量算法的效率是不合适的。撇开这些与计算机硬件、软件有关的因素,可以认为一个特定算法“运行工作量”的大小,只依赖于问题的规模(通常用整数量 n 表示),或者说,它是问题规模的函数。
一个算法是由控制结构(顺序、分支和循环3种)和原操作(指固有数据类型的操作)构成的,则算法时间取决于两者的综合效果。为了便于比较同一问题的不同算法,通常的做法是,从算法中选取一种对于所研究的问题(或算法类型)来说是基本操作的原操作,以该基本操作重复执行的次数作为算法的时间量度。