' P* d7 E( |. N6 t9 {为了得到更快的算法,需要简化矩阵分割和再组合这两个步骤。一种方案是使用S t r a s s e n方法得到7个小矩阵。这7个小矩阵为矩阵D, E, ., J,矩阵D到J可以通过7次矩阵乘法, 6次矩阵加法,和4次矩阵减法计算得出。前述的4个小矩阵可以由矩阵D到J通过6次矩阵加法和两次矩阵减法得出. ' W8 R8 x) S( s' P* a
9 O) V& o2 d7 s
用上述方案来解决n= 2的矩阵乘法。将某矩阵A和B相乘得结果C,如下所示: % ~# C! s% }# R7 {8 a* `1 n" d6 C4 P: p
因为n> 1,所以将A、B两矩阵分别划分为4个小矩阵,每个矩阵为1×1阶,仅包含一个元素。1×1阶矩阵的乘法为小问题,因此可以直接进行运算。利用计算D~J的公式,得: / p5 p$ s4 s9 \$ t3 W+ m- i% n$ Z( Z" b9 ~& L
D= 1(6-8)=-2: i3 m; B2 O# ]* J: F s
7 d) U# u6 b, V3) 对较轻的金块进行比较以确定哪一个金块最轻,对较重的金块进行比较以确定哪一个金块最重。对于节点A到C执行这种比较。 : j! k# l- B5 j" ?- N' c* z% S7 F% K+ m% m6 m) h" ?
根据上述步骤,可以得出程序1 4 - 1的非递归代码。该程序用于寻找到数组w [ 0 : n - 1 ]中的最小数和最大数,若n < 1,则程序返回f a l s e,否则返回t r u e。 / V1 n! N; I( k, a( P, C1 {8 L* b5 k4 x3 f! B% [
当n≥1时,程序1 4 - 1给M i n和M a x置初值以使w [ M i n ]是最小的重量,w [ M a x ]为最大的重量。7 e# L4 d9 f# T& S+ V
' B* A( O2 \8 B$ ?1 n4 Y首先处理n≤1的情况。若n>1且为奇数,第一个重量w [ 0 ]将成为最小值和最大值的候选值,因此将有偶数个重量值w [ 1 : n - 1 ]参与f o r循环。当n 是偶数时,首先将两个重量值放在for 循环外进行比较,较小和较大的重量值分别置为Min和Max,因此也有偶数个重量值w[2:n-1]参与for循环。5 l. X; S3 Q5 P4 U3 B) g* c; A- g
0 C% R+ R/ t$ P/ n7 t0 g在for 循环中,外层if 通过比较确定( w [ i ] , w [ i + 1 ] )中的较大和较小者。此工作与前面提到的分而治之算法步骤中的2) 相对应,而内层的i f负责找出较小重量值和较大重量值中的最小值和 ; n6 [" U% |2 y6 i4 F5 U" u9 e5 X1 G9 Y
最大值,这个工作对应于3 )。for 循环将每一对重量值中较小值和较大值分别与当前的最小值w [ M i n ]和最大值w [ M a x ]进行比较,根据比较结果来修改M i n和M a x(如果必要)。- ~: {* A; s/ U$ f5 _+ H3 {
, I* a- K, }$ @6 F下面进行复杂性分析。注意到当n为偶数时,在for 循环外部将执行一次比较而在f o r循环内部执行3 ( n / 2 - 1 )次比较,比较的总次数为3 n / 2 - 2。当n 为奇数时,f o r循环外部没有执行比较,而内部执行了3(n-1)/2次比较。因此无论n 为奇数或偶数,当n>0时,比较的总次数为「3n/2ù-2次。 ' b7 u! O) R4 S# m- }4 d " I+ i) g ~# } p- h程序14-1 找出最小值和最大值的非递归程序 1 X/ E/ p; a; p) X, t% x- H3 j+ S( S$ c' L! A( N- X
template<CLASS T>! }4 O1 O# b8 Z- N$ R
3 |7 G, E9 m5 w+ K6 N
bool MinMax(T w[], int n, T& Min, T& Max) ( ^% \( j$ i7 @' P2 c% V0 b! s 2 f- V" ?/ p8 z4 G, l; t& N{// 寻找w [ 0 : n - 1 ]中的最小和最大值) j5 r6 Q) J8 S( D8 V4 Q
# V) l8 Z: \& H3 C7 D% J, v: c, U
// 如果少于一个元素,则返回f a l s e; F8 o" O! K' d J* {
0 ^) R8 q( K* Y" N4 c
// 特殊情形: n <= 1( _2 [4 d+ F/ F3 h
: Y7 d' C& B1 P1 m' D
if (n < 1) return false; % d) Y. c5 u* k2 {+ G: l/ g4 Y7 ]- O
if (n == 1) {Min = Max = 0;6 g( V8 Y1 s" i7 P9 T6 }, Q/ R
5 z( i# _$ W7 V% e$ C) yreturn true;} : Y4 |0 ?6 Q8 y! R% | ) E' ^: I( v$ r# v. D2 h/ /对Min 和M a x进行初始化* r2 y/ s' X( q% ]2 a9 W/ ^; ~. i' j' j
/ i8 P, C+ \+ ]" P
int s; // 循环起点 4 S" K3 y% B& E1 I5 K% c L# u7 i* J( _ D0 X. Z
if (n % 2) {// n 为奇数 8 l6 o5 B# n' x) g/ u/ j$ X# R: i( ~# a. y: Y
Min = Max = 0;' _- [# c* V" `
" U- Y X1 i% [: \9 Q# ?
s = 1;}8 H8 A7 _9 Z1 g' r1 N4 T
) O/ Y" \; y5 _: I+ d: I
else {// n为偶数,比较第一对. y: }* G4 N: @3 z+ T1 r
: C5 A: L, Q; o
if (w[0] > w[1]) {$ y; J* q$ V8 i% m' ]2 y. ^8 i. r
- I+ m& d9 P4 \! c' Z' Y/ R+ r4 {Min = 1;4 {" P# ~; M, k& c" M0 @' ~5 U
i$ O- e- P9 d
Max = 0;} 7 ?9 o" Z, w5 @ |' f& d* _2 }$ K8 a4 A6 [6 T2 ~! h
else {Min = 0; 1 D& v6 S0 {* O0 e7 F+ H# x0 N, D; C: z- t9 w, v' _
Max = 1;} ! l3 r3 B/ ?( i5 f/ L+ n g$ W9 w# D3 F4 i/ Z) O* Z8 [
s = 2;}* V* v* v/ D' a) C" g. @+ N
, Y) a% c. g7 A) a
// 比较余下的数对; H3 B1 t2 x. T+ u% v" p
! K7 X/ l9 `- i9 ?# O- {4 {1 r2 Ifor (int i = s; i < n; i += 2) {6 r. l7 ~( j$ y k4 G) C
5 p2 P; r7 \, K: T( A! h/ n& x
// 寻找w 和w [ i + 1 ]中的较大者4 D& f$ X& W O, k) f
) X" m" k' Y. U' v8 m1 o* P' Y// 然后将较大者与w [ M a x ]进行比较0 D" D7 U" P5 l
. s4 e* g1 I; q// 将较小者与w [ M i n ]进行比较 - G, U- }$ m( o- Q# a5 K ! _ g* B3 l- Z) A1 ?- {. Hif (w > w[i+1]) {1 r3 G1 o, E9 l8 E D- ^
/ D8 K3 d/ Y# j2 t- hif (w > w[Max]) Max = i;$ M3 @. g, v% E8 }
, i K5 [) R6 T! Dif (w[i+1] < w[Min]) Min = i + 1;}) N0 r1 H& |; S& b& s) k9 }! Y
' w6 u" x" j. ~. X4 I9 celse {! p4 N: D& y( Z4 A" M
. n% n) `" w8 D1 N" l/ c$ T/ ?0 f
if (w[i+1] > w[Max]) Max = i + 1;* Z d0 ^0 p- X V, g0 ?# v7 r# m: c
6 R' B0 |( N* z- g/ bif (w < w[Min]) Min = i;}2 R8 p( T! F; m: O% c' O
. @5 Y; U. W8 U: o*6. 编写S t r a s s e n矩阵乘法程序。利用不同的k 值(见公式(1 4 - 6))进行实验,以确定k 为何值时程序性能最佳。比较程序及程序2 - 2 4的运行时间。可取n 为2的幂来进行比较。* r! u0 M% p% f& S5 v' R A
P2 g+ n; `+ `6 t9 V6 l7 p
7. 当n 不是2的幂时,可以通过增加矩阵的行和列来得到一个大小为2的幂的矩阵。假设使用最少的行数和列数将矩阵扩充为m 阶矩阵,其中m 为2的幂。 2 R* H1 Y1 q8 H2 l% f; B ) R) N, C6 k- Y7 [: F1) 求m / n。; H8 V* q) F" g7 M& I L
- r! {5 C' ~0 B2) 可使用哪些矩阵项组成新的行和列,以使新矩阵A' 和B' 相乘时,原来的矩阵A和B相乘的结果会出现在C' 的左上角? ; Q: _& p) i2 _, J; E: }. [, S% g2 N8 N0 v
3) 使用S t r a s s e n方法计算A' * B' 所需要的时间为(m2.81 )。给出以n 为变量的运行时间表达式。 </P>