第二章 基础: 算法、整数和矩阵

  许多问题都可以当作一般问题的特例来解决。例如,寻找序列101, 12, 144,212,98 中最大整数的问题。这是寻找整数序列中最大整数问题的一个特例。为解决这个一般问题,必须给出一个算法。这个算法规定解决一般问题的一系列步骤。本书将介绍解决许多不同问题的算法,例如,求两个整 数最大公约数的算法、产生有限集所有排序的算法、搜索列表的算法、搜索序列元素的算法、求网络上两顶点间最短路径的算法等。

  与算法有关的一项重要考虑是算法的复杂度, 即用这一算法解决一定规模问题需要什么计算机资源。为了度量算法的复杂度,使用大O和大Θ记号。本章将介绍这些记号,对算法的复杂度进行分析,另外将讨论就实践和理论而言算法的复杂度意味着什么。

  整数集合是离散数学的基础。特别是整数除法的概念是计算机算术的基础。我们将简要回顾一下数论(整数及其性质的研究)的几个重要概念。学习与整数有关的几个重要算法,包括求最大公约数的欧里几德算法,这是几千年前就给出的算法。整数可以用任何大于1的正整数为基数来表示。贯穿计算机科学的二进制展开即是以2为基数的表示。本章将学习以b 为基数的整数表示,并给出算法求这些表示。还要讨论用于整数算术的算法,这是第一批被称为算法的过程。本章还要介绍几个重要的数论应用。例如,本章将长利用数论来进行信息保密、生成伪随机数并为计算机文件分配内存地址。一度认为是最纯粹数学科学的数论已成为计算机和网络安全的实质性工具。

  矩阵在离散数学中用于表示各种离散结构。我们将学习矩阵的基本内容及表示关系和图形所需的矩阵算术。矩阵算术将用于与这些结构的关的大量算法。

 

2.1 算法

2.1.1 引言

  离散数学中有多种一般性的问题。例如,已知一串整数,求最大的一个;已知一个集合,列出其所有子集;给定一个整数集合,把这些整数从小到大排序;已知一个网络,找两个顶点之间的最短路径等。遇到这样的问题时,首先要做的就是构造一个模型,把问题翻译为数学问题。在这种模型中用到的离散结构包括:集合、序列和函数。这些是第一章讨论过的结构, 以及置换、关系、图、树、网络和有穷状态机等其他结构。这些概念将在以后各章讨论。

  建立合适的数学模型只是解题的第一步。完整的解题还需要利用这一模型解决一般性问题的方法。理想的情况是求一个过程。这个过程能够遵循一串步骤找出所求的答案。这一串步骤称为算法。

  定义1   算法是进行一项计算或解决一个问题的一组有限多条准确的指令。

  算法(algorithm) 这一术语是对 al-khowarizmi (花拉子密)这一名字的讹用。 花拉子密是9世纪的一位数学家。 他关于印度数字的书是现代十进制记号的基础。起初algorism 这个词用于表示使用十进制记号做算术的规则。 18 世纪时algorism进化为algorithm。 随着人们对计算机的兴趣的增长,算法的概念有了更广的含义,已经不仅包含做算术的过程,而且包含所有确定的解题过程(在2.5节将讨论做整数算术的算法。)

  @  Abu Ja' far Mohammed ibn Musa al-khowarizmi (约公元780-850)    天文学家和数学家花拉子密巴格达一个科学组织“智慧之家”的成员。 花拉子密这一名字含义是“来自花拉子模镇”。 该镇现称卡瓦(Khiva),是乌兹别克斯坦的一部分。 花拉子密写过关于数学、天文学和几何学的书。西欧人首先从他的著作中学习代数。 代数(algebra)一词源自 al-jabr, 这是他的书的标题《Kitab albr w'al muquabala》的一部分。这本书曾译为拉丁文并广泛用作课本。 他关于印度数字的书描述了使用这些数字作算术过程。欧洲作者使用了他的名字的一个拉丁讹音来表示用印度数字来做算术内容,后来演变为algorithm (算法)一词。@

  本书将讨论解决各种问题的算法。 这一节用求有限整数序列中最大整数这一问题解释算法的概念和算法的具有的性质。还要给出在有限集合中找出一个特定元素的算法。以后各节将讨论求两个整数的最大公约数的过程,求网络上两点之间的最短路径的过程,矩阵相乘的过程等。

  例1  求有限整数序列中最大值的算法。

    尽管求有限序列最大元素的问题相对简单,但这个问题能很好地说明算法概念。另外,需要求有限整数序列中最大整数的情况各不相同。例如,大学可能要找出几千名学生参加竞赛的最高分。体育组织可能确定每月成绩最好的运动员。人们希望开发出一个算法。求有限整数序列最大元素的问题就可以使用算法。

    可以用几种不同的方式给出解决这一问题的过程。一种方法是直接用中文描述使用的一串步骤。 现在就给出这样一个解。

    例1 的解:采取下面的步骤.

    1. 设临时最大值等于序列第一个整数(在本过程的每一个阶段,临时最大值都等于已检查过的最大整数。)

    2. 将序列中的下一个整数与临时最大值比较,如果这个数大于临时最大值,置临时最大值为这一整数。

    3. 如果序列中还有其他整数,重复前一步骤。

    4. 在序列中没有留下可比的整数时停止,此刻的临时最大值就是序列中的最大整数。

    也可以用计算机语言来描述算法。但是当这样做时,只能使用这种语言所允许的指令。这样做常常导致复杂而难以理解的算法描述。另外,由于许多程序设计语言都是常用的,并不希望从中选用特定的某种语言。因此本书不用任何一种特定的计算机语言描述算法,而是使用伪代码的形式。(本书中所有算法也都是用英文描述。)伪码提供的是在算法的英文描述及其程序设计语言实现之间的中间一步。算法步骤用模仿程序设计语言指令的伪指令描述,不过伪指令可以包括有确切定义的一切运算和语句。以算法的伪码描述为起点,可以用任何一种计算机语言产生计算机程序。

    本书使用的伪码大致上以程序设计语言Pascal 为基础。不过并不遵循Pascal 或其他程序设计语言的语法。此外,任何有确切定义的指令均可用于伪码中,附录B给出本书使用的伪码的细节。必要时读者应参看这一附录。

    下面是求有限序列最大元素的伪码算法。 

算法1  求有限序列中的最大元素

  Procedure max (a1, a2,...,an:整数)

  max  :=a1

  for  i:=2 to n 

    if max<ai  then max  :=ai

(max 是最大元素)

 

 

   这一算法首先把序列的首项a1赋给变量max。"for" 循环用于逐个检查序列项。如果某一项大于max的当前值,就将其赋给max,成为max的新值。

   算法有几个通用的性质。在描述算法时记住这些性质是有用的。这些性质是:

    • 输入  算法从一个指定的集合得到输入值。
    • 输出  对每个输入值集合,算法都要从一个指定的集合中给出输出值。输出值就是问题的解。
    • 确定性   算法的步骤发须是准确定义的。
    • 正确性  对每一组输入值,算法都应产生正确的输出值。
    • 有限性  对任何输入算法都应在有限(可能很多)步之后产生所求的输出。
    • 有效性  算法的每一步都应能够准确地在有限时间内完成。
    • 通用性  算法过程应该可以应用于期望形式的所有问题,而不只是特定的输入值。

  例2. 证明求有限整数序列中最大元素的算法1具有上面列出的所有性质。

  解  算法1的输入是个整数序列。输出的是该序列的最大整数。算法的每一步都是准确定义的,因为只出现赋值、有限循环和物权法件语句。为了说明算法是正确的,必须说明当算法终止时,变量max的值等于序列的最大项。为了看明白这一点,注意max 的初值是序列的第一项;当检查序列的后继项时,如果有一项超过已检查项的最大值, 就把max 更新为这一项的值。这个(非形式化)论证说明当检查了所有的项时,max就等于最大项的值。(这个事实的严格证明需要3.3节介绍的技术。)算法使用有限的步骤数,因为在检查过该序列中所有整数以后算法就终止。算法在有限时间内完成,因为每一步要么是比较,要么是赋值。最后,算法1是通用的,因为该算法可用于求任何有限整数序列的最大元素。 

 

2.1.2  搜索算法

  在有序表中为元素定位的问题常会出现。例如检查单词拼写的程序要在字典中搜索,字典其实就是单词的有序表。这一类问题称为搜索问题。本节将讨论几个搜索算法。在2.2 节将介绍这些算法中各自使用的步骤数。

  一般搜索问题可以描述如下: 在不同的元素a1,a2,...,an的表中为元素x定位,或判定x不在该表中。这一搜索问题的解是表中等于x的那一项的位置(即, x=ai,那么i就是解),或当x不在表中时解为0. 

  线性搜索  将介绍的第一个算法称为线性搜索(或顺序搜索)算法。线性搜索算法从比较x 和a1开始。 若x=a1,那么解就是a1的位置,也就是1.当x=a1时,比较x和 a2。 若x=a2,解就是a2的位置,也就是2.当x≠a1时,比较 x 和 a2。 若x=a2

  

posted @ 2017-09-14 22:19  ZQXTXK  阅读(156)  评论(0)    收藏  举报