离散数学中的基础结构有,集合,函数,序列,求和,矩阵。之所以叫做基础结构,是因为其后的很多结构都是基于这些结构的。之后会慢慢介绍。可以说,离散数学中的基础结构衍生了数据结构,数据结构衍生了不少算法。
1、集合
德国数学家,乔治.康托尔提出了朴素集合论。他定义集合就是对象的聚集,同样这也是我们平时所理解的集合。不过集合论作为基础数学的研究,它想要提出集合就是最为基本的定义 。但是既然集合是由对象组成的,那么最基本的定义就是对象而不是集合。那么我们在定义集合之前就必须定义对象,对象怎么定义?宇宙间的万事万物都可以是对象,最终数学家选择了另一种解决方案,就是公理集合论。那就是设立一个公理,然后所有的理论都建立在这个公理上,这里就不多提了。在应用中朴素集合论也是大有用处的。
朴素集合论还有一个问题那就是悖论,在说明悖论之前首先需要理解一个概念。
1.1幂集
幂集就是集合所有子集(A的每个元素都是B的元素,那么A就是B的子集)的集合。
例如,假设有一个集合A={a,b,c}(集合全部用大括号作为集合符号)。那么A的幂集就是:
P(A)={{a},{b},{c},{a,b},{a,c},{b,c},{abc},∅} ∅就是指的空集,空集中没有元素。A的幂集用P(A)表示。注意,幂集中的元素数量一定比原集合的元素数量多。
那么有一个问题,是否存在一个最大的集合包含宇宙万物和所有可能性呢?平时我们有一个集合叫全集一般用U或者E来表示,这全集是否可以是最大的集合呢?
要解答这个问题,我们就做出一个假设。假设有最大的集合E,它包含了世界所有的可能性。既然E也是集合,那么我们也可以对它取幂集,假设A=P(E),那么A中的元素数量一定比E的中的元素数量多,那么E就不是最大的集合。与假设相矛盾,所以不存在最大的集合。
这个时候就可以搬出你八成听说过的一些通俗的悖论了。
上帝悖论:假设上帝是万能的。那么上帝可不可以创造出一颗自己举不起来的石头呢?如果能,那么上帝的力量不是无敌的,如果不能,那么上帝的创造力不是万能的。这个悖论与“是否存在最大的集合”这个问题有几分相似呢。
理发师悖论:理发师说,我只为那些不为自己理发的人理发。那么谁为理发师理发呢?
这些都是经典的悖论,也是朴素集合论的问题,在这里我也不继续深入研究了,不过这些问题绝对不是没有意义的。准确的说这些问题可能比很多应用问题更加有意义。基础研究终究是推动科学发展的第一动力。
1.2集合运算与恒等式
在高中时,我们就学习过集合的并集,交集,补集。不过,这三种简单的运算可以延伸出很多推论,例如容斥原理(在以后的文章中再详细介绍)。下面给出运算的定义:
交集:集合A与集合B的交集就是某个集合中,元素x即属于A又属于B。
并集:集合A与集合B的交集就是某个集合中,元素x属于A或者属于B。
补集:集合A的补集就是指某个集合中,元素x属于全集合U但不熟与集合A。(全集必须要定义,前面证明过,没有绝对的全集)
恒等式就是指某些集合恒定相等的式子,这些公式可以利用逻辑证明的知识来推导。想要证明某个恒等式成立,那就要证明等号两边的两个集合相等,证明集合相等的通用办法就是证明两个集合互为子集。另外一种简单粗暴地方式就是成员表。
德摩根定律: (这里“——”意思是补集,倒U是交集,U是并集)
逻辑推论如下:
1.也就是一个集合,集合中的元素x不属于A和B的交集。
2.也就是说x不属于A或者x不属于B(交集的定义)。
3.进一步推理,x属于A的补集或者x属于B的补集(补集的定义)。
4.那么x属于A的补集和B的补集的并集(并集的定义)。
成员表的方法如下:
图片取自百度百科,这就是利用真值来判断。当两个集合的真值表中每一个可能性真值都一样,那么就说明两个集合相等。
注意:这里的真值指的是任意元素x是否属于这一列的集合,举个例子:第一行的意思是,元素x不属于A(A列的真值为0)也不属于B,这种情况下x是否属于其他列的集合。
1.3计算机中的集合
计算机中的集合往往可以用于存储信息,也可以用于集合运算。在集合运算时会利用布尔代数,也就是计算机中的或、且、非、异或运算。
另外,在存储时同样按照朴素集合论的要求,集合中某个对象只能存在一个。所以C++中的set就可以利用红黑树来作为数据结构。这样的集合在搜索时只需要耗费常数时间。当然也可以设定集合中的同一个元素不止出现一次。也就是多重集,那么每个元素都会有一个出现次数,我们叫做重数,这种集合就可以使用到C++中的map。map中有一个值key,key也是唯一的,但是每个key值对应一个value,value是数字可以当成重数。同样map的结构和set没有什么区别,只是map以key来排序后续接上一个value。
模糊集:模糊集合中的元素也有类似于重数的概念,但是每个元素可以有多个重数,而且这些数可以不是整数。在社会网络,聚类算法中都应用甚广。
2、函数
从初中开始我们对函数就耳濡目染,学习了编程之后我对函数的理解就是输入一个值进入函数,函数就返回一个值。
不过现在对函数的理解变为了映射,函数是从某一个集合映射到另一个集合的关系。先来看看书上的一些定义。
函数:令A和B为非空集合,f是从A到B元素的一种指派,即a是A中的元素,b是B中的元素,有唯一的b,f(a)=b。
定义域:集合A就是函数f的定义域。
陪域:集合B是函数f的陪域。
在应用时,函数需要理解的概念不多。但是我们对函数必须有一些思考,不能廉价的认为函数就是某个公式然后代入数字计算。我们将函数想象成映射或者是转换。
例如函数中有定义一对一函数和映上函数:
一对一函数:符合a!=b 则 f(a)!=f(b) ,那么f是一对一函数。
映上函数:对于陪域B中每一个元素b,都有f(a)=b。那么f是映上函数。
这些定义看上去没有太多意义,其实这可以表达很多实用的现象和问题。例如函数有一个是否可逆的问题。
如何去判断一个函数是否可逆呢?如果你能想象一个函数就是一种转换,那么就很轻松的想到函数是否可逆取决于转换过程中信息是否丢失。这一点十分的好理解,假设存在a!=b 但是y=f(a)=f(b)。那么这时已知y和f也不能知道原来的参数究竟是a还是b。这样的情况下函数就不可逆。所以当陪域中对象的数量大于定义域对象的数量时,函数一定不可逆。自然一对一函数就是可逆的,因为每个a都对应了单独的b。
陪域也是老是被人误解成值域。值域指的是集合A被函数f映射之后的所有元素的集合。例如A={1,2,3} ,f(x)=x+2。那么计算每一个a,得到3,4,5三个数。那么{3,4,5}就是f的值域。而f的陪域可以是任何集合,当陪域等于值域时,就叫f是映上函数。
3、序列与求和
序列是元素的有序列表,在计算机中我们常常要解决序列和问题。例如等比数列(几何级数): a,a*r,a*r^2.........a*r^n。
等差数列(算数级数):a,a+d,a+2d,a+3d........a+nd。这些都是大部分人有所接触的数列了,当然序列不会只是这两种就能概括的。例如斐波那契数列 f(n)=f(n-1)+f(n-2) f(1)=1 f(2)=1。
1、递推关系
一个递推关系和初始条件就可以确定一个序列。就像斐波那契数列,初始条件就是f(1)=1,f(2)=1。递推关系就是f(n)=f(n-1)+f(n-2)。所以说,寻找一个序列的递推关系是非常重要的。我们需要给序列的每一项都找到一个显示公式,也叫闭公式。这样才能找到递推关系的解。下面将引用书上的例子:
例如:an=a(n-1)+3 a0=3。
已知an的递推关系以及初始条件a0=3。利用迭代法来在反复利用递推关系。
正向替换:a0=3 a2=2+3 a3=2+3*2 a4=2+3*3 .............. an=2+3(n-1)
反向替换:an=a(n-1)+3=a(n-2)+3*2..............=a0+3(n-1)
正向替换就是从第0项开始一直迭代到第n项时的通项,反向替换则是从第n项与第n-1项的关系一直迭代到第一项。
再举一个稍微复杂一些的例子:
汉诺塔:相信汉诺塔是大家都很熟悉的问题,这里不多赘述问题本身,n个盘子的汉诺塔有递推关系:a(n)=2a(n-1)+1 T(n)表示n个盘子移动需要多少步,那么我们用迭代法来寻找其显示公式。
正向替换:a0=1 a2=2*1+1 a3=2*(2*1+1)+1=2^4+2+1 a4=2*(2*(2*1+1)+1)+1=2^3+2^2+2+1 an=2^(n-1)+2^(n-2)+....1
an=2^n -1
反向替换:an=2a(n-1)+1
=4a(n-2)+2+1
=8a(n-3)+4+2+1
=...........=2^(n-1)a0+2^(n-2)+.....1 = 2^n -1
这便是迭代法的大致思路,不过迭代法具有很大的限制,而且迭代法使用时往往考验我们的经验。
2、求和
关于求和符号的性质我认为不需要多做赘述和证明,因为求和符号就是指多项序列相加。拆开求和符号思考就和加法的性质差不多。值得写的是多种数列的求和公式。
几何级数:
至于如何证明,我目前只是看懂了证明的过程,没有搞清楚其中的思维不过依旧写下来以备后用。
(这个过程中从求和式中提取一个k=n+1项,增加了一个k=0项)
这是几何级数求和公式的全部证明过程。
3、其他重要的求和公式
还有几个涉及无穷的级数:
(此处是kx^(k-1))
这些无穷级数只需要一些简单的微积分知识就能解决。
例如第一个无穷级数:我们令初始项a=1 r=x 那么。因为|x|<1 当k趋于无穷大时,x^(k+1)趋于0。那么用0替换x^(k+1)就得到了闭合式。
序列和求和是计算机中很重要的一部分,我所写到的只是很少的很浅显的一部分,后续有机会还会继续研究。
4、矩阵
线性代数中所讨论的矩阵不在这里讨论,当然无论是矩阵乘法的原理还是思考方式,都很重要。最近我也在看MIT线代的公开课,也许之后会有相关博客。
这里讨论的是0-1矩阵:矩阵中的元素非0即1。0-1矩阵是可以进行布尔运算的,在图论中有应用(虽然现在我也不清楚)。
1、0-1矩阵的交和并:
矩阵A= B=
A V B= =
A B= =
2、0-1矩阵的布尔积和布尔幂:
0-1矩阵的布尔积和普通矩阵的乘积相似,不过用代替了加法,用代替了乘法。
也就是说矩阵乘法和布尔积遵循同样的规则,布尔积用符号表示。AB时,矩阵A为n*k,则矩阵B必须是k*m。矩阵A的列必须等于矩阵B的行。
例如:A= B= AB= =
布尔幂:布尔幂类似于矩阵求幂,矩阵A的r次幂:= (此处r个A求布尔积)
布尔幂在计算机网络和图论中都有所应用,但是我还没有用到过,这些都是书上写的。
结语
离散数学中的结构应用在计算机时直接决定了算法的“形状”。也就是说结构决定使用什么样的算法,算法是建立在数据结构之上的,数据结构就是建立在这些基础结构上的。其实这些基础结构都有许多的基础结论和研究,在应用时我们往往不需要过于纠结其中的部分基础理论,而是让这些结论给与我们思考,让我们真正理解其中的含义。