JONY

STRASSEN矩阵乘法

Strassen矩阵乘法             为更好的讨论算法本身,本文矩阵特指行列数相等(方阵)且都为2的幂的矩阵。矩阵乘法的定义是\((AB)_{ij} = \sum_{k=0}^n A_{ik}B_{kj}\)。使用定义直接求\(AB\)需要嵌套3层循环,如果\(AB\)是\(m\times m\)的,时间复杂度是\(O(m^3)\)。如何高效的做矩阵乘法是个重要的问题,计算机各领域都需要用到。目前计算机学者们虽未找到该算法足够“紧”的“理论下界”,但一直都在发明更优的具体算法,目前最快“斯坦福方法”代价为\(O(m^{2.373})\),第一个快于\(O(m^3)\)的算法由德国数学家Strassen于1969年提出。 结合上述(1)和(2)找一种分治算法,(2)把方阵均分为四象限,把每个象限作为“子矩阵”。根据矩阵乘法定义,矩阵乘法可以正确转化成(2)等号右边的递归形式。分析这种算法的时间复杂度,其包含8个“子矩阵乘法”和4次加法,所有加法和其他操作的总代价等于遍历矩阵的\(O(m^2)\)。所以时间复杂度满足\(T(m)=8T(\frac{m}{2})… 阅读全文

汉诺塔问题

汉诺塔问题(Hanoi Tower Problem)印度有一个古老的传说,在贝拿勒斯的圣庙里,一块黄铜板上插着三根宝石针。印度教主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是汉诺塔(如上图所示)。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭。而梵塔、庙宇和众生也都将同归于尽。 \(k\)层汉诺塔问题可以这样表述:“有\(a,b,c\)三个柱子,其中\(a\)有\(k\)片圆盘,圆盘的大小从上到下严格递增。允许一次移动一个圆盘到其他柱子,每次移动后所有柱子上的圆盘上面不能有更大的圆盘。问如何操作能把所有圆盘移动到\(c\)柱”。这里规定解为序列,序列元素是二元组\((X,Y)\)表示“从\(X\)柱移一片圆盘到\(Y\)柱”,那么解就是有顺序的一系列移动步骤。… 阅读全文

约瑟夫环问题

约瑟夫环问题传说在古罗马时期,罗马人占领乔塔帕特后,犹太士兵与约瑟夫不愿投降,于是约瑟夫提出一起自杀的方式:“所有人围成圈,从某人开始报数,每报到3该人自杀,然后再由下个人重新报数,直到所有人自杀”。但约瑟夫其实不想自杀,那他站在什么位置才能最后轮到他自杀?这就是约瑟夫环问题,也叫丢手绢问题。问题的解可用士兵编号来表示。 简单的算法是用环形链表模拟过程,但这里讨论复杂一点的分治算法。先用\(G(n,k)\)符号表示“共\(n\)个人,间隔为\(k\)(\(k=1\)表示下个人)的约瑟夫环问题”。对于\(G(n,k)\),第一次士兵自杀后,问题转化为更小规模的\(G(n-1,k)\),求解\(G(n-1,k)\)得到最后自杀的编号后,将其换算为问题\(G(n,k)\)对应的编号即可。进一步定义函数\(F(n,k)\)为“问题\(G(n,k)\)的解,其中士兵编号从0开始”,定义域满足\(n>0,k\geq… 阅读全文

最大连续子序列问题

最大连续子序列 最大连续子序列是“由原序列中连续元素构成的所有序列里,元素和最大的”,比如\([11, -4, 13, -5, 5,-1]\)的最大连续子序列有\([11,-4,13]\)和\([11,-4,13,-5,5]\)两个。这里规定空序列不能作为问题的输入,非空序列的最大连续子序列至少包含1个元素。那么对于全负序列,其最大连续子序列仅包含其中的最大值。然后来寻找其分治算法,设\(L=[0,…,n]\)为序列,将其尽量等长分为非空的\(L_1=L[0,…,k]\)与\(L_2=L[k+1,…,n]\)。如下情况至少成立1种: a) \(L\)存在可作为\(L_1\)最大连续子序列的最大连续子序列; b) \(L\)存在可作为\(L_2\)最大连续子序列的最大连续子序列;… 阅读全文

(01)背包问题

(01)背包问题背包问题(Knapsack Problem)是一类著名的运筹学、应用数学的问题,其相关研究可追溯至1897年。其中最简单的背包问题是(01)背包问题。其可描述为“给定一个物品序列\([t_0,t_1…t_n]\),序列中任意下标\(i\)的物品都有体积\(A_i\)和价值\(B_i\)两个指标,现有容积\(V\)的背包,问放入背包哪些物品能取到最大价值”。这个问题的解不一定唯一,这里规定解的格式为和物品序列等长的序列,序列下标\(i\)的元素能取的值是0/1,表示物品序列下标\(i\)的物品不放/放入背包。 然后找问题的分治算法,这里先用一个符号\(G(k,V)\)表示“对物品序列前\(k+1\)项构成的子序列\([t_0,t_1…t_k]\),求一个能放入体积\(V\)背包的最大价值物品组合”。然后考虑如何用规模更小的若干个\(G\)构造出\(G(k,V)\)的一个解。这里先直接给出结论,按如下2种方式得到的物品组合,总价最大的其中一个可作为\(G(k,V)\)的解:… 阅读全文

并查集与并查集森林

并查集(Union-find Disjoint Sets) 首先定义不相交集合数据结构(Disjoint-Sets Data Structure),其首先是一个集合\(S = \{S_1,S_2,…,S_n \}\),\(S\)中的元素也是集合,并且对于\(S\)中的任意两个元素\(S_x,S_y\),都满足\(S_x\cap S_y=\emptyset\)。并查集则是带有特定运算的不相交集合数据结构,主要用于解决查询与合并的问题,由于\(S_x\)是可修改的,所以也称它们为动态集合。并查集运算的定义如下: 1) \(MAKE(x)\):创建1个仅含元素\(x\)的动态集合,并把该动态集合加入到并查集中;   是若干不相交动态集合组成的集合\(S = \{S_1,S_2,…S_n \}\),不相交指任意两动态集合间无重复元素,从动态集合中任取一元素即可形成与该动态集合的单射。对并查集中的动态集合\(S_k\)而言,动态指\(S_k\)中的元素是从无到有通过\(S\)上定义的运算结构动态添加的,所以接下来讨论\(S\)上的运算结构:… 阅读全文

机器级数据的检错与纠错

二进制数据的检错纠错 计算机在用“高低电平”的方式传输和表示数据的时候,会因为电平毛刺等导致某些位出错,这时就需要相应的数据纠错检错的机制。比如多用于服务器的ECC内存,其同时具备纠错和检错功能。而普通PC内存通常只有检错功能。计算机电路结构使数据出错时不会出现“多位或少位”的情况,只会出现“位值”的错误,并且多个位中的每个位是否出错可看作是概率独立的。 目前主要的纠错检错机制是纠错码,其核心是在原字(数据位)额外加若干位(校验位),新数据称为码字(用于和字区分),码字同样是定长的,实际传输数据会传输码字而不是字。下面通过汉明距离给出编码方案与纠错检错能力间的关系,汉明距离的定义之前在<算法>中讨论过: 1) 若两两合法码字的汉明距离是\(d+1\)且错误不大于\(d\)位则必可检错。因为到合法码字汉明距离为\(1-d\)的所有数据中,不可能有合法码字;… 阅读全文

字符的机器级表示

字符 大多数计算机中的数据和指令都是二进制位形式的。注意这里区分一下二进制位和二进制数,二进制数是数学概念,而机器本身是“无法理解”数学概念的,只能按照人类规定的范式处理二进制位。只有人类规定好相关范式,计算机才能把二进制位当作数来处理。之后可能不去区分二进制位和二进制数的概念。 想要让计算机存储和表示字符,需要用公认和权威的标准,建立其与二进制位的映射关系,否则计算机间很难交互。这种映射称为字符编码。其由国际机构或国家机构制定。可分为如下2部分: 1) 字符集:规定了语言包含的所有字符和标点符号等。但语言是比较复杂的,比方说让大陆、香港、台湾、日本出具一份汉字的字符集,那它们可能出的不一样。所以汉语这“一种语言”就有国际、大陆、台湾等的多个版本的字符集; 2) 编码:编码是指给定字符集中的字符的区分和表示的方案,对于非计算机有莫尔斯电码的方案,计算机则通常用定长或变长的二进制数来做编码。考虑到二进制数表示字符常需要较多的位,以及机器中数据的位数常以字节为倍数,在很多时候又会用十六进制来表示二进制的编码;… 阅读全文

余数与二进制数的数学性质

整数的带余除法定理 余数在计算机中非常重要,二进制计算机只能用有限数目的二进制位处理和表示数据。当数据超出这个限制时,会被截断。这个特点可以用余数描述,而余数本身是由整数除法定义的。在小中学阶段就会学习余数,但主要是学习如何求余数,没有提到除法和余数的严格定义,以及对整数的严格定义。这部分内容属于数学中的整数理论。整数集中的除法和余数是由如下事实定义的,其本身也是一个定理,是整数理论的重要基础: a) 整数的带余除法定理:设\(a,b(b>0)\)为任意整数,存在唯一整数对\(q,r\),使\(a=bq+r\),其中\(0\leq r < b\); 其中\(q,r\)是商和余数,计做\(a\div b = q……r\),读作a除以b等于q余r。需注意的是上述定义包含了被除数为负的情况,而小中学阶段没有讨论过这种情况。另外这种除法和平时做数学计算的除法有一些区别:… 阅读全文

有向图与无向图

有向图与无向图数据结构中的图(Graph)是对数学分支图论(Graph Theory)中的图的表示,通常用二元组\(G=(V,E)\)定义图\(G\),其中\(V\)是顶点的集合(顶点集),\(E\)是边的集合(边集)。边集的元素也是二元组\((x,y)\)且\(x,y\)是\(V\)的元素,由于二元组包含\(x,y\)的序,若不关心\(x,y\)的序或用集合\(\{x,y\}\)表示边,则\(G\)是无向图,否则是有向图。一般按上图的方式“画”有向图和无向图。 直观上图是对前面讨论过的树的推广,树不允许树边任意的加在两节点间,图边则没有这些限制,并且图中一般不会指定“树根”这样的顶点。所以图相比树会有更多更复杂的“边界情况”,给出与之相关的概念: 1) 重边:即重复的边。设\(u,v\)是图顶点,对于有向图,若存在2个以上的从\(u\)到\(v\)的边,则称从\(u\)到\(v\)有重边。对于无向图,若存在2个以上连接\(u\)和\(v\)的边,则称\(u\)与\(v\)间有重边。也就是边集中有“相同”的二元组;… 阅读全文
滚动至顶部