《算法导论》第四章-第2节_练习(参考答案)

来源:互联网 发布:湖北省软件协会 编辑:程序博客网 时间:2024/05/17 07:40

算法导论(第三版)参考答案:练习4.2-1,练习4.2-2,练习4.2-3,练习4.2-4,练习4.2-5,练习4.2-6,练习4.2-7

Exercise 4.2-1

Use Strassen’s algorithm to compute the matrix product

>(>1>735>)>(>6>482>)>

Show your work.

步骤1:

A11=(1),A12=(2),B21=(7),B22=(5)B11=(6),B12=(8),B21=(4),B22=(2)

步骤2;
S1=B12B22=6S2=A11+A12=4S3=A21+A22=12S4=B21B11=2S5=A11+A22=6S6=B11+B22=8S7=A12A22=2S8=B21+B22=6S9=A11+A21=6S10=B11+B12=14

步骤3:
P1P2P3P4P5P6P7=A11S1=16=6=S2B22=42=8=S3B11=612=72=A22S4=612=72=S5S6=68=48=S7S8=(2)6=12=S9S10=(6)14=84

步骤4:
C11C12C21C22=P5+P4P2+P6=48+(10)8+(12)=18=P1+P2=6+8=14=P3+P4=72+(10)=62=P5+P1P3P7=48+672(84)=66

结果为:
C=(C11C21C12C22)=(18621466)

Exercise 4.2-2

Write pseudocode for Strassen’s algorithm

Pseudocode

STRASSEN-MATRIX-MULTIPLY-RECURSIVE(A, B)  n = A.rows  let C be a new n×n matrix  if n == 1    c11 = a11 * b11  else partition A, B, and C as in equations (4.9)    calculate 10 addition: S1-S10    P1 = STRASSEN-MATRIX-MULTIPLY-RECURSIVE(A11, S1)    p2 = STRASSEN-MATRIX-MULTIPLY-RECURSIVE(S2, B22)    P3 = STRASSEN-MATRIX-MULTIPLY-RECURSIVE(S3, B11)    P4 = STRASSEN-MATRIX-MULTIPLY-RECURSIVE(A22, S4)    P5 = STRASSEN-MATRIX-MULTIPLY-RECURSIVE(S5, S6)    P6 = STRASSEN-MATRIX-MULTIPLY-RECURSIVE(S7, S8)    P7 = STRASSEN-MATRIX-MULTIPLY-RECURSIVE(S9, S10)    C11 = P5 + P4 - P2 + P6    C12 = P1 + P2    C21 = P3 + P4    C22 = P5 + P1 - P3 - P7  return C

C code

#include <alloca.h>#include <stdio.h>// The matrix representation. One structure to fit both a matrix and a// submatrix.typedef struct {    int x;    int y;    int size;    int original_size;    int *data;} matrix;// Functions to index matricesint get(matrix m, int x, int y) {    return m.data[m.original_size * (m.x + x) + m.y + y];};void put(matrix m, int x, int y, int value) {    m.data[m.original_size * (m.x + x) + m.y + y] = value;};// Matrix buildingmatrix create_matrix(int size, int *data) {    matrix result;    result.x = 0;    result.y = 0;    result.size = size;    result.original_size = size;    result.data = data;    return result;}matrix submatrix(matrix A, int x, int y, int size) {    matrix result;    result.x = A.x + x;    result.y = A.y + y;    result.size = size;    result.original_size = A.original_size;    result.data = A.data;    return result;}#define INIT_ON_STACK(m_, size_) \    m_.x = 0; \    m_.y = 0; \    m_.size = size_; \    m_.original_size = size_; \    m_.data = alloca(size_ * size_ * sizeof(int));// Adding and subtracting matricesvoid plus(matrix C, matrix A, matrix B) {    for (int i = 0; i < C.size; i++) {        for (int j = 0; j < C.size; j++) {            put(C, i, j, get(A, i, j) + get(B, i, j));        }    }}void minus(matrix C, matrix A, matrix B) {    for (int i = 0; i < C.size; i++) {        for (int j = 0; j < C.size; j++) {            put(C, i, j, get(A, i, j) - get(B, i, j));        }    }}void add(matrix T, matrix S) {    for (int i = 0; i < T.size; i++) {        for (int j = 0; j < T.size; j++) {            put(T, i, j, get(T, i, j) + get(S, i, j));        }    }}void sub(matrix T, matrix S) {    for (int i = 0; i < T.size; i++) {        for (int j = 0; j < T.size; j++) {            put(T, i, j, get(T, i, j) - get(S, i, j));        }    }}void zero(matrix m) {    for (int i = 0; i < m.size; i++) {        for (int j = 0; j < m.size; j++) {            put(m, i, j, 0);        }    }}// A function to print matricesvoid print_matrix(matrix m) {    printf("%dx%d (+%d+%d) (%d)\n", m.size, m.size, m.x, m.y, m.original_size);    printf("==============\n");    for (int i = 0; i < m.size; i++) {        for (int j = 0; j < m.size; j++) {            printf("%4d", get(m, i, j));        }        printf("\n");    }    printf("\n");}// Strassen's algorithmvoid strassen(matrix C, matrix A, matrix B) {    int size = A.size,        half = size / 2;    if (A.size == 1) {        put(C, 0, 0, get(A, 0, 0) * get(B, 0, 0));    } else {        matrix s1, s2, s3, s4, s5, s6, s7, s8, s9, s10;        matrix p1, p2, p3, p4, p5, p6, p7;        INIT_ON_STACK(s1, half);        INIT_ON_STACK(s2, half);        INIT_ON_STACK(s3, half);        INIT_ON_STACK(s4, half);        INIT_ON_STACK(s5, half);        INIT_ON_STACK(s6, half);        INIT_ON_STACK(s7, half);        INIT_ON_STACK(s8, half);        INIT_ON_STACK(s9, half);        INIT_ON_STACK(s10, half);        INIT_ON_STACK(p1, half);        INIT_ON_STACK(p2, half);        INIT_ON_STACK(p3, half);        INIT_ON_STACK(p4, half);        INIT_ON_STACK(p5, half);        INIT_ON_STACK(p6, half);        INIT_ON_STACK(p7, half);        matrix a11 = submatrix(A,    0,    0, half);        matrix a12 = submatrix(A,    0, half, half);        matrix a21 = submatrix(A, half,    0, half);        matrix a22 = submatrix(A, half, half, half);        matrix b11 = submatrix(B,    0,    0, half);        matrix b12 = submatrix(B,    0, half, half);        matrix b21 = submatrix(B, half,    0, half);        matrix b22 = submatrix(B, half, half, half);        matrix c11 = submatrix(C,    0,    0, half);        matrix c12 = submatrix(C,    0, half, half);        matrix c21 = submatrix(C, half,    0, half);        matrix c22 = submatrix(C, half, half, half);        minus(s1, b12, b22);        plus(s2,  a11, a12);        plus(s3,  a21, a22);        minus(s4, b21, b11);        plus(s5,  a11, a22);        plus(s6,  b11, b22);        minus(s7, a12, a22);        plus(s8,  b21, b22);        minus(s9, a11, a21);        plus(s10, b11, b12);        strassen(p1, a11, s1);        strassen(p2, s2, b22);        strassen(p3, s3, b11);        strassen(p4, a22, s4);        strassen(p5, s5, s6);        strassen(p6, s7, s8);        strassen(p7, s9, s10);        zero(c11);        zero(c12);        zero(c21);        zero(c22);        add(c11, p5);        add(c11, p4);        sub(c11, p2);        add(c11, p6);        add(c12, p1);        add(c12, p2);        add(c21, p3);        add(c21, p4);        add(c22, p5);        add(c22, p1);        sub(c22, p3);        sub(c22, p7);    }}

Exercise 4.2-3

How would you modify Strassen’s algorithm to multiply n×n matrices in which n is not an exact power of 2? Show that the resulting algorithm runs in time Θ(nlg7).

可以将矩阵填充为 n×n 的矩阵,在 Θ(nlg7) 内求解完成后,再将填充元素剥离掉。

Exercise 4.2-4

What is the largest k such that if you can multiply 3×3 matrices using k multiplications (not assuming commutativity of multiplication), then you can multiply n×n matrices is time o(nlg7)? What would the running time of this algorithm be?

根据题意,可得如下递归式:

T(n)=kT(n/3)+Θ(n)

根据主方法可知运行时间:Θ(nlog3k)。比较 Θ(nlog3k)Θ(nlg7)
nlog3k<nlg7log3k<lg7k<3lg721.84986

Exercise 4.2-5

V. Pan has discovered a way of multiplying 68×68 matrices using 132,464 multiplications, a way of multiplying 70×70 matrices using 143,640 multiplications, and a way of multiplying 72×72 matrices using 155,424 multiplications. Which method yields the best asymptotic running time when used in a divide-and-conquer matrix-multiplication algorithm? How does it compare to Strassen’s algorithm?

log681324642.795128log701436402.795122log721554242.795147

70×70 的矩阵乘法最快,lg72.81 ,比Strassen算法好。

Exercise 4.2-6

How quickly can you multiply a kn×n matrix by an n×kn matrix, using Strassen’s algorithm as a subroutine? Answer the same question with the order of the input matrices reversed.

(kn×n)(n×kn) 需要 k2(n×n) 矩阵相乘,即 T=k2Θ(nlg7)

(n×kn)(kn×n) 只需要 k(n×n) 矩阵相乘,加上 k1(n×n) 矩阵相加,即 T=kΘ(nlg7)+(k1)Θ(n2)=kΘ(nlg7)

Exercise 4.2-7

Show how to multiply the complex numbers a+bi and c+di using only three multiplications of real numbers. The algorithm should take a, b, c and d as input and produce the real component acbd and the imaginary component ad+bc separately.

(a+bi)(c+di)=(acbd)+(ad+bc)i=acbd+[(a+b)(c+d)acbd]i

阅读全文
0 0
原创粉丝点击