#include #include #include struct Matrix { int rows; int cols; }; struct Matrices { struct Matrix * items; int number; }; struct Solution { int cost; int middle1; int middle2; }; struct Solution ** malloc2d(int rows, int columns) { int row; struct Solution ** result = malloc(rows * sizeof(struct Solution *)); for (row = 0; row < rows; row++) result[row] = malloc(columns * sizeof(struct Solution)); return result; } void free2d(struct Solution ** array, int rows, int columns) { int row; for (row = 0; row < rows; row++) free(array[row]); free(array); } struct Result { char * ordering; int cost; }; struct Matrices read_matrices(char * filename) { struct Matrices result; result.number = 0; result.items = 0; FILE * handle = fopen(filename, "rb"); if (handle == 0) { printf("cannot open %s\n", filename); return result; } fscanf(handle, "%d", &(result.number)); result.items = malloc(sizeof(struct Matrix) * result.number); printf("number = %d\n", result.number); int counter; for (counter = 0; counter < result.number; counter++) { int rows, cols; fscanf(handle, "%d %d", & rows, & cols); result.items[counter].rows = rows; result.items[counter].cols = cols; printf("%3d: rows = %4d, cols = %4d\n", counter, rows, cols); if ((counter >= 1) && (rows != result.items[counter-1].cols)) { printf("error, rows/cols mismatch\n"); exit(1); } } return result; } char * get_ordering(struct Matrices input, struct Solution ** solutions, int start, int finish) { struct Matrix * matrices = input.items; int number = input.number; char * result; if (start == finish) { result = malloc(sizeof(char) * 20); sprintf(result, "%d", start); return result; } struct Solution solution = solutions[start][finish]; char * first = get_ordering(input, solutions, start, solution.middle1); char * second = get_ordering(input, solutions, solution.middle2, finish); result = malloc(sizeof(char) * (finish - start +1) * 20); sprintf(result, "(%s * %s)", first, second); free(first); free(second); return result; } struct Result optimal_ordering(struct Matrices input) { struct Matrix * matrices = input.items; int number = input.number; struct Solution ** solutions = malloc2d(number, number); int first, second, third; for (first = 0; first < number; first++) { for (second = first; second >= 0; second--) { struct Solution solution; if (second == first) { solution.cost = 0; solution.middle1 = second; solution.middle2 = first; solutions[second][first] = solution; continue; } if (second == first-1) { solution.cost = matrices[second].rows * matrices[first].rows * matrices[first].cols; solution.middle1 = second; solution.middle2 = first; solutions[second][first] = solution; continue; } solution.cost = -1; for (third = second; third <= first -1; third++) { int cost1 = solutions[second][third].cost; int cost2 = solutions[third+1][first].cost; int rows1 = matrices[second].rows; int rows2 = matrices[third+1].rows; int cols = matrices[first].cols; int cost3 = rows1 * rows2 * cols; int cost = cost1+ cost2+ cost3; if ((cost < solution.cost) || (solution.cost == -1)) { solution.cost = cost; solution.middle1 = third; solution.middle2 = third +1; } } solutions[second][first] = solution; } } struct Result result; result.ordering = get_ordering(input, solutions, 0, number-1); result.cost = solutions[0][number-1].cost; free2d(solutions, number, number); return result; } int main() { struct Matrices matrices = read_matrices("omm1.txt"); struct Result result = optimal_ordering(matrices); printf(" optimal ordering = %s\n", result.ordering); printf(" optimal cost = %d\n", result.cost); free(result.ordering); free(matrices.items); return 0; }