CS3343/3341 Analysis of Algorithms |
Matrix-chain Multiplications |

| Matrix Chain Multiplications | |
|---|---|
// Matrix chain multiplications.
// Input: sequence of matrix dimens, end in 0.
#include <stdio.h>
#define L 15 // big enough for most examples
int r(int i, int j, int s[L][L]); // print =s
void putpre(int x); // used by r
void putdig(int x); // used by r
int newtemp(void); // used by r
void r2(int i, int j, int s[L][L]);// print par
void r3(int i, int j, int s[L][L]);// expression
void main(void) {
int p[L]; // input array of dimensions
int m[L][L]; // array of numbers of mults
int s[L][L]; // array giving index opt sol
int n = 0, i, ll, j, k, q;
int res; // final result from seq of assigns
for (i = 0; i < L; i++) {
scanf("%i", &p[i]); // read up to a zero
if (p[i] <= 0) break;
}
n = i - 1;
// calculate matices m and s
for (i = 1 ; i <= n; i++)
m[i][i] = 0;
for (ll = 2; ll <= n; ll++)
for (i = 1; i <= n - ll + 1; i++) {
j = i + ll - 1;
m[i][j] = 444444444; // "infinity"
for (k = i; k <= j - 1; k++) {
q = m[i][k] + m[k+1][j] +
p[i-1]*p[k]*p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
// print p
printf("The array p:\n\n");
for (i = 0; i <= n; i++)
printf("p[%i] =%3i, ", i, p[i]);
// print m
printf("\n\nThe array m:\n\n ");
for (i = 1; i <= n; i++)
printf(" i=%2i ", i);
printf("\n");
for (j = n; j >= 1; j--) {
printf("j=%2i:", j);
for (i = 1; i <= j; i++)
printf("%7i", m[i][j]);
printf("\n");
}
// print s
printf("\nThe array s:\n\n ");
for (i = 1; i < n; i++)
printf(" i=%2i ", i);
printf("\n");
for (j = n; j >= 2; j--) {
printf("j=%2i:", j);
for (i = 1; i < j; i++)
printf("%7i", s[i][j]);
printf("\n");
}
printf("\n");
res = r(1, n, s);
printf("Final result is in T");
putdig(res); printf("\n\n");
r2(1, n, s); printf("\n\n");
r3(1, n, s); printf("\n");
} | // r: function that calcs series of assigns
int r(int i, int j, int s[L][L]) {
int k, arg1, arg2, res;
if (i == j) return i;
k = s[i][j]; // top-level split
arg1 = r(i, k, s); // temp left half
arg2 = r(k+1, j, s); // temp right half
res = -newtemp(); // next temp
// a negative number indicates a temp
// next three lines output one equation
putpre(res); putdig(res); putchar('=');
putpre(arg1);putdig(arg1);putchar('*');
putpre(arg2);putdig(arg2);putchar('\n');
return res;
}
// putpre: neg is a temp; pos if an arg
void putpre(int x) {
if (x < 0) putchar('T');
else putchar('A');
}
// putdigit: spit one digit, without sign
void putdig(int x) {
if (x < 0) x = -x;
printf("%i", x);
}
// newtemp: return next integer in order
int newtemp(void) {
static i = 1;
return i++;
}
// r2: output paren form with extra parens
void r2(int i, int j, int s[L][L]) {
int k;
if (i == j) {
printf("A%i", i);
return;
}
k = s[i][j];
printf("(");
r2(i, k, s);
printf(")*(");
r2(k+1, j, s);
printf(")");
}
// r3: output paren form with fewer parens
void r3(int i, int j, int s[L][L]) {
int k;
if (i == j) {
printf("A%i", i);
return;
}
printf("(");
k = s[i][j];
r3(i, k, s);
printf("*");
r3(k+1, j, s);
printf(")");
}
|
The array p:
p[0] = 30, p[1] = 35, p[2] = 15, p[3] = 5,
p[4] = 10, p[5] = 20, p[6] = 25,
The array m:
i= 1 i= 2 i= 3 i= 4 i= 5 i= 6
j= 6: 15125 10500 5375 3500 5000 0
j= 5: 11875 7125 2500 1000 0
j= 4: 9375 4375 750 0
j= 3: 7875 2625 0
j= 2: 15750 0
j= 1: 0
The array s:
i= 1 i= 2 i= 3 i= 4 i= 5
j= 6: 3 3 3 5 5
j= 5: 3 3 3 4
j= 4: 3 3 3
j= 3: 1 2
j= 2: 1
T1=A2*A3
T2=A1*T1
T3=A4*A5
T4=T3*A6
T5=T2*T4
Final result is in T5
((A1)*((A2)*(A3)))*(((A4)*(A5))*(A6))
((A1*(A2*A3))*((A4*A5)*A6))
| The array p:
p[0] = 5, p[1] = 10, p[2] = 3, p[3] = 12,
p[4] = 5, p[5] = 50, p[6] = 6,
The array m:
i= 1 i= 2 i= 3 i= 4 i= 5 i= 6
j= 6: 2010 1950 1770 1860 1500 0
j= 5: 1655 2430 930 3000 0
j= 4: 405 330 180 0
j= 3: 330 360 0
j= 2: 150 0
j= 1: 0
The array s:
i= 1 i= 2 i= 3 i= 4 i= 5
j= 6: 2 2 4 4 5
j= 5: 4 2 4 4
j= 4: 2 2 3
j= 3: 2 2
j= 2: 1
T1=A1*A2
T2=A3*A4
T3=A5*A6
T4=T2*T3
T5=T1*T4
Final result is in T5
((A1)*(A2))*(((A3)*(A4))*((A5)*(A6)))
((A1*A2)*((A3*A4)*(A5*A6)))
|
The array p:
p[0] = 20, p[1] = 25, p[2] = 5, p[3] = 10, p[4] = 30, p[5] = 15,
p[6] = 20, p[7] = 10, p[8] = 5, p[9] = 40,
The array m:
i= 1 i= 2 i= 3 i= 4 i= 5 i= 6 i= 7 i= 8 i= 9
j= 9: 13500 12125 7500 8250 10750 5500 5000 2000 0
j= 8: 9500 7125 6500 6250 4750 2500 1000 0
j= 7: 9750 7500 6250 9000 7500 3000 0
j= 6: 9750 7750 5250 7500 9000 0
j= 5: 7750 5625 3750 4500 0
j= 4: 7000 5250 1500 0
j= 3: 3500 1250 0
j= 2: 2500 0
j= 1: 0
The array s:
i= 1 i= 2 i= 3 i= 4 i= 5 i= 6 i= 7 i= 8
j= 9: 8 8 8 8 8 8 8 8
j= 8: 2 2 3 4 5 6 7
j= 7: 2 2 6 5 5 6
j= 6: 2 2 5 5 5
j= 5: 2 2 4 4
j= 4: 2 2 3
j= 3: 2 2
j= 2: 1
T1=A1*A2
T2=A7*A8
T3=A6*T2
T4=A5*T3
T5=A4*T4
T6=A3*T5
T7=T1*T6
T8=T7*A9
Final result is in T8
(((A1)*(A2))*((A3)*((A4)*((A5)*((A6)*((A7)*(A8)))))))*(A9)
(((A1*A2)*(A3*(A4*(A5*(A6*(A7*A8))))))*A9)
| |
The array p:
p[0] = 20, p[1] = 10, p[2] = 15, p[3] = 5, p[4] = 25, p[5] = 10, p[6] = 30, p[7] = 5,
p[8] = 10, p[9] = 20, p[10] = 25, p[11] = 15,
The array m:
i= 1 i= 2 i= 3 i= 4 i= 5 i= 6 i= 7 i= 8 i= 9 i=10 i=11
j=11: 11875 10125 9750 8625 10000 7625 7625 5375 8750 7500 0
j=10: 11000 8750 8625 6750 9375 6250 7250 3500 5000 0
j= 9: 8000 6000 5750 4250 6250 3500 4000 1000 0
j= 8: 6000 4500 4000 3250 4000 2000 1500 0
j= 7: 5000 4000 3375 3000 2750 1500 0
j= 6: 7500 5000 5000 2750 7500 0
j= 5: 4000 2500 2000 1250 0
j= 4: 4250 2000 1875 0
j= 3: 1750 750 0
j= 2: 3000 0
j= 1: 0
The array s:
i= 1 i= 2 i= 3 i= 4 i= 5 i= 6 i= 7 i= 8 i= 9 i=10
j=11: 3 3 3 10 7 7 7 10 10 10
j=10: 3 3 3 9 7 7 7 9 9
j= 9: 3 3 3 8 7 7 7 8
j= 8: 3 3 3 7 7 7 7
j= 7: 1 3 3 5 5 6
j= 6: 3 3 3 5 5
j= 5: 3 3 3 4
j= 4: 3 3 3
j= 3: 1 2
j= 2: 1
T1=A2*A3
T2=A1*T1
T3=A4*A5
T4=A6*A7
T5=T3*T4
T6=T5*A8
T7=T6*A9
T8=T7*A10
T9=T8*A11
T10=T2*T9
Final result is in T10
((A1)*((A2)*(A3)))*(((((((A4)*(A5))*((A6)*(A7)))*(A8))*(A9))*(A10))*(A11))
((A1*(A2*A3))*((((((A4*A5)*(A6*A7))*A8)*A9)*A10)*A11))
| |